roarment@faui09.informatik.uni-erlangen.de (Roberto Armenti) (11/12/90)
Hi net-people, perhaps someone out there can help me. Is there a _portable_ way to recognize whether input comes from stdin or from another stream ? To make the problem clearer : i'm working on a programm that takes its input from stdin. If however someone chooses to redirect the input to a file, so that data is read from that file, how can I figure that out ( Prompting and so on should not occur in this case ) ??? The solution should at least work on UNIX _AND_ MS-DOS, so i'm looking for a _portable_ implementation. Help out there ? Thanks in advance Roberto -- please contact ( no commercials please ) * Roberto Armenti * Voice * For E-Mail * On IRC * Wielandstrasse 6 * 0841/ * roarment@faui09.informatik. * madguitar * 8070 Ingolstadt * 52126 * uni-erlangen.de * or just mad
gwyn@smoke.brl.mil (Doug Gwyn) (11/13/90)
In article <roarment.658423394@faui09> roarment@faui09.informatik.uni-erlangen.de (Roberto Armenti) writes: >Is there a _portable_ way to recognize whether input comes from >stdin or from another stream ? Wrong question. It comes from stdin if you're reading it from the stdin stream. >To make the problem clearer : i'm working on a programm that takes >its input from stdin. If however someone chooses to redirect the input >to a file, so that data is read from that file, how can I figure that >out ( Prompting and so on should not occur in this case ) ??? What you really want to determine is whether or not input is coming from an interactive device. This is in general impossible to ascertain. The usual UNIX kludge is to invoke isatty(fileno(stdin)); I don't know whether or not MS/DOS has something equivalent. Anyway, it is not a reliable test, since just because something is coming via a terminal port does not necessarily mean that there is a human typing the input. You should probably use a command option to determine how prompting should be done, if at all. (One approach is to not prompt initially, but support an input command that enables/disables prompting; the UNIX System V "ed" uses this method.)
epames@eos.ericsson.se (Michael Salmon) (11/13/90)
In article <roarment.658423394@faui09> roarment@faui09.informatik.uni-erlangen.de (Roberto Armenti) writes: >Is there a _portable_ way to recognize whether input comes from >stdin or from another stream ? > >The solution should at least work on UNIX _AND_ MS-DOS, so i'm looking for >a _portable_ implementation. isatty(fileno(stdin)) should do what you want. I have seen it implemented on Unix, MS_DOS and CP/M systems but I can't say how portable it is. I also find it very handy to determine when to give a usage message when file names are omitted from the command line, I hate programmes that do nothing when I make a mistake. Michael Salmon L.M.Ericsson Stockholm
brianh@hpcvia.CV.HP.COM (brian_helterline) (11/14/90)
>Hi net-people, >perhaps someone out there can help me. >Is there a _portable_ way to recognize whether input comes from >stdin or from another stream ? >To make the problem clearer : i'm working on a programm that takes >its input from stdin. If however someone chooses to redirect the input >to a file, so that data is read from that file, how can I figure that >out ( Prompting and so on should not occur in this case ) ??? Check out isatty() >The solution should at least work on UNIX _AND_ MS-DOS, so i'm looking for >a _portable_ implementation. >Help out there ? > Thanks in advance > Roberto -- please contact ( no commercials please ) * Roberto Armenti * Voice * For E-Mail * On IRC * Wielandstrasse 6 * 0841/ * roarment@faui09.informatik. * madguitar * 8070 Ingolstadt * 52126 * uni-erlangen.de * or just mad ----------
darcy@druid.uucp (D'Arcy J.M. Cain) (11/14/90)
In article <14447@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >What you really want to determine is whether or not input is coming >from an interactive device. This is in general impossible to >ascertain. The usual UNIX kludge is to invoke isatty(fileno(stdin)); >I don't know whether or not MS/DOS has something equivalent. Anyway, >it is not a reliable test, since just because something is coming via >a terminal port does not necessarily mean that there is a human typing >the input. You should probably use a command option to determine how >prompting should be done, if at all. (One approach is to not prompt >initially, but support an input command that enables/disables >prompting; the UNIX System V "ed" uses this method.) How about this for a kludge? Have an input routine that takes a prompt and a buffer argument and checks to see if there are characters waiting. If not then issue the prompt. as long as there are characters then you just read. If there is a human waiting for a prompt then you issue one. If necessary you can add timing stuff so that slow terminals with stuff in the pipe don't trigger the prompt. Maybe I'll write this and post it if I get a little time. -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | I support gun control. West Hill, Ontario, Canada | Let's start with the government! + 416 281 6094 |
aquesada@mtecv2.mty.itesm.mx (11/15/90)
From: roarment@faui09.informatik.uni-erlangen.de (Roberto Armenti) Message-ID: <roarment.658423394@faui09> >Hi net-people, > > perhaps someone out there can help me. > > Is there a _portable_ way to recognize whether input comes from > stdin or from another stream ? > To make the problem clearer : i'm working on a programm that takes > its input from stdin. If however someone chooses to redirect the input > to a file, so that data is read from that file, how can I figure that > out ( Prompting and so on should not occur in this case ) ??? > > The solution should at least work on UNIX _AND_ MS-DOS, so i'm looking for > a _portable_ implementation. > Help out there ? > Thanks in advance > Roberto > > > > > Try this, it ran under both MSDOS and Ultrix. Sorry i don't give a longer explanation but i'm in a rush. ************************************ #include <stdio.h> FILE *entrada={stdin}; char linea[255]; main(argc,argv) char *argv[]; { if(argc>1) { if((entrada=fopen(argv[1],"r"))==NULL) puts("file not found"),exit(1); printf("Reading from file: %s\n",argv[1]); /* In here goes any other code you need to execute when reading from a file */ } while(!feof(entrada)) { fgets(linea,255,entrada); puts(linea); } } ************************************* From Monterrey, Mexico: Antonio Quesada Duarte aquesada@mtecv2.mty.itesm.mx
weimer@ssd.kodak.com (Gary Weimer) (11/15/90)
In article <1990Nov14.150228.4038@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: > >How about this for a kludge? Have an input routine that takes a prompt >and a buffer argument and checks to see if there are characters waiting. >If not then issue the prompt. as long as there are characters then you >just read. If there is a human waiting for a prompt then you issue one. >If necessary you can add timing stuff so that slow terminals with stuff >in the pipe don't trigger the prompt. Maybe I'll write this and post it >if I get a little time. This won't work if the program you are piping from runs slower than the program you are piping to (i.e. a spell checker piped through cat). The second program will always be waiting for the first.
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (11/16/90)
>>Is there a _portable_ way to recognize whether input comes from >>stdin or from another stream ? Absolutely none! But isatty(fd) works reasonably well on many systems. Beware of just doing a single test, however (which you may have been thinking of doing after seeing some other postings). You might want to do it like this: if (isatty(fileno(stdin)) && isatty(fileno(stdout))) { ... interactive code ... } else { ... noninteractive code ... } This way you don't print a prompt to the output stream unless it's connected to a tty, and you don't print a prompt unless the input is coming from a tty. You can also explicitly open /dev/tty to print the prompt, but that's much less portable than isatty() alone. -- Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com> UUCP: oliveb!cirrusl!dhesi
scs@adam.mit.edu (Steve Summit) (11/16/90)
[I've included comp.unix.programmer since this is a bit of a tutorial which gets fairly Unix-specific...] In article <roarment.658423394@faui09> roarment@faui09.informatik.uni-erlangen.de (Roberto Armenti) writes: >i'm working on a programm that takes >its input from stdin. If however someone chooses to redirect the input >to a file, so that data is read from that file, how can I figure that >out ( Prompting and so on should not occur in this case ) ??? In article <1990Nov13.073315.2831@ericsson.se> epames@eos.ericsson.se writes: >isatty(fileno(stdin)) should do what you want. I have seen it implemented >on Unix, MS_DOS and CP/M systems but I can't say how portable it is. Correct (but see below for one addition). (Notwithstanding my crosspost to comp.unix, isatty does indeed exist on non-Unix systems.) >I also find it very handy to determine when to give a usage message >when file names are omitted from the command line, I hate programmes >that do nothing when I make a mistake. Excellent! I hit upon this maneuver myself just last week. The implication may not be obvious, so it deserves some explication. Many, many utilities which follow the "everything's a text stream" model usefully read from their standard input if they are invoked without explicit input filenames on their invocation command line. That is, the code looks something like this: #include <stdio.h> main(argc, argv) int argc; char *argv[]; { if(argc <= 1) process(stdin, "standard input"); else { int argi; for(argi = 1; argi < argc; argi++) { FILE *ifd = fopen(argv[argi], "r"); if(ifd == NULL) perror(argv[argi]); else { process(ifd, argv[argi]); (void)fclose(ifd); } } } exit(0); } The problem is that when you've forgotten what the thing is or how it works or what option flags it takes, you can't just invoke it with no arguments and get a usage message. Therefore, a useful wrinkle is if(argc <= 1) { if(isatty(fileno(stdin))) { fprintf(stderr, "usage: ...\n"); exit(1); } process(stdin); } The one drawback here is that the "expert" user now can't type in raw input directly. (Does the Unix beginner/novice/expert hierarchy include "creates programs with `/lib/ccom | as'"?) If easily-accessible usage messages are more important to you than coddling gurus, just tell the gurus to use cat | yourprogram which will let them type away. (Note that one program which therefore _can't_ receive this treatment is cat itself, which is fine, since you also want to leave cat > file working as expected, although it could again be argued that this is guru-coddling :-) .) In article <14447@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >What you really want to determine is whether or not input is coming >from an interactive device. >The usual UNIX kludge is to invoke isatty(fileno(stdin)); >it is not a reliable test, since just because something is coming via >a terminal port does not necessarily mean that there is a human typing >the input. Kludge? I doubt this is much of a problem in practice; presumably non-humans (i.e. programs) which have gone to the trouble to talk to another program through a tty or pty are clever enough (and, I should think, rare enough) that they can figure out how to deal with prompts.%% A somewhat bigger problem than noninteractive tty's is the case when stdin is not a tty, but is interactive. Have you (not Doug; I'm just being didactic) ever wondered why /bin/sh has a -i flag? This tells it to be interactive and issue prompts, even when isatty(0) fails. You need this when you're typing at a shell through a pipe or something, which is admittedly rare, but it does happen. (One example, from BSD Unix, is rsh machine sh -i which is a quick-and-dirty rlogin, without .profile/.login overhead, but which uses sockets rather than pty's, so you need -i if you want prompts. A contrived but perhaps more appreciable example would be something like dd conv=lcase | sh -i when your caps lock key is stuck and you don't know about stty lcase, although how you'd type it is another question :-) ...) %% I do not mean to imply that ignoring prompts is easy for a program to do; in fact, it's surprisingly hard. But I'd rather that programs attempt to be useful to large numbers of users, by using isatty if necessary even if it's imperfect, than that they worry about the occasional non-human-but-on-a-tty "user." And, before someone gives me a lecture on the importance, in the toolkit model, of programs' being invokable by other programs, remember that the vast majority of them do so through pipes or files. (In fact, I could give quite a lecture on the importance of programs' being invokable by other programs, and the way it's being forgotten in the rush towards highly interactive, graphical, mouse-based applications, but that's another article.) Steve Summit scs@adam.mit.edu