ok@quintus.uucp (Richard A. O'Keefe) (10/05/88)
In article <4975@saturn.ucsc.edu> haynes@saturn.ucsc.edu (Jim Haynes - Computer Center) writes: >So - I'm thinking of sticking in something along the lines of > if (!isatty(1)) > fprintf(stderr, "Redirecting output may not be what > you have in mind. Type a ctrl-D if you want to start > over.\n"); Please, anyone who is thinking of doing something like that, DON'T hardwire "ctrl-D" into your program. Mention the end-of-file character the user has assigned, whatever that is. Just to make life easier for people who would like to extend this elementary courtesy to the users of their programs, here's some source code: : execute this with sh cat >eofchar.c <<'ENDOFFILE' /* File : eofchar.c Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc Purpose: Return name of user's end-of-file character Compile: cc -DBSD -c eofchar.c # on 4.x BSD cc -DUSG -c eofchar.c # on System V cc -DTEST -DBSD eofchar.c # to test it Usage: eofchar() returns a string which identifies the user's end-of-file character. A static buffer is used, but this value is not likely to change, so that's no problem. It is possible that no end-of-file character may be assigned, in which case the value shown is "exit", which is what you type to a shell to stop it. Error: if the end-of-file character cannot be determined, NULL is returned. (This is distinct from it being determined that there is no end-of-file character.) */ #include <stdio.h> #ifdef BSD #include <sgtty.h> #define TIO_GET_CHARS TIOCGETC #define TIO_CHR_STRUCT tchars #define TIO_CHR_FIELD t_eofc #endif #ifdef USG #include <termio.h> #define TIO_GET_CHARS TCGETA #define TIO_CHR_STRUCT termio #define TIO_CHR_FIELD c_cc[VEOF] #endif #ifndef TIO_GET_CHARS ERROR: either BSD or USG must be defined; #endif char *eofchar() { int fd; struct TIO_CHR_STRUCT info; int ch; static char buffer[12]; if (!(isatty(fd=2) || isatty(fd=1) || isatty(fd=0))) { fd = open("/dev/tty", 0); if (fd < 0) { perror("Cannot open /dev/tty"); return NULL; } } if (ioctl(fd, TIO_GET_CHARS, &info) < 0) { perror("Cannot obtain terminal characters"); if (fd > 2) (void) close(fd); return NULL; } if (fd > 2) (void) close(fd); ch = info.TIO_CHR_FIELD; if (ch == 127) return "DELETE"; if (ch == -1) return "exit"; if (ch >= 32) (void) sprintf(buffer, "%c", ch); else (void) sprintf(buffer, "Control-%c", ch+64); return buffer; } #ifdef TEST main() { printf("Your end-of-file character is %s\n", eofchar()); exit(0); } #endif ENDOFFILE
maart@cs.vu.nl (Maarten Litmaath) (10/11/88)
In article <503@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
\... here's some source code:
[C source deleted]
People, what happened to good old shell script programming?
BSD:
sh -c 'stty all 2> /tmp/stty.$$; set `tail -1 /tmp/stty.$$`;
shift; shift; echo $9; /bin/rm /tmp/stty.$$'
----------------------------------------------------------------------------
SysV:
sh -c 'stty -a | sed -e "s/.*eof = \([^;]*\).*/\1/" -e q'
----------------------------------------------------------------------------
BTW, this shows the SysV stty(1) command is favorable in one way: if stdout
isn't a tty, try stderr or stdin! (So we won't need the stupid temp file.)
--
Hippic sport: |Maarten Litmaath @ Free U Amsterdam:
a contradiction in terms.|maart@cs.vu.nl, mcvax!botter!maart
maart@cs.vu.nl (Maarten Litmaath) (10/11/88)
In article <1503@fireball.cs.vu.nl> I goofed. Sorry.
--
Hippic sport: |Maarten Litmaath @ Free U Amsterdam:
a contradiction in terms.|maart@cs.vu.nl, mcvax!botter!maart
bsy@PLAY.MACH.CS.CMU.EDU (Bennet Yee) (10/12/88)
In article <1503@fireball.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: >In article <503@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >\... here's some source code: >[C source deleted] > >People, what happened to good old shell script programming? > >BSD: >sh -c 'stty all 2> /tmp/stty.$$; set `tail -1 /tmp/stty.$$`; > shift; shift; echo $9; /bin/rm /tmp/stty.$$' >SysV: >sh -c 'stty -a | sed -e "s/.*eof = \([^;]*\).*/\1/" -e q' > >BTW, this shows the SysV stty(1) command is favorable in one way: if stdout >isn't a tty, try stderr or stdin! (So we won't need the stupid temp file.) No no no no. With even BSD stty, you can do it all in one line w/o stupid tmp files: sh -c 'set `stty all 2>&1 >/dev/tty | tail -1`; shift; shift; echo $9' or, if you don't like the tail, you could also use sh -c 'stty all 2>&1 > /dev/tty | awk "{ last = \$NF } END { print last }"' What _did_ happen to good olde shell programming? -bsy -- Internet: bsy@cs.cmu.edu Bitnet: bsy%cs.cmu.edu%smtp@interbit CSnet: bsy%cs.cmu.edu@relay.cs.net Uucp: ...!seismo!cs.cmu.edu!bsy USPS: Bennet Yee, CS Dept, CMU, Pittsburgh, PA 15213-3890 Voice: (412) 268-7571
ok@quintus.uucp (Richard A. O'Keefe) (10/12/88)
In article <1503@fireball.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: >In article <503@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >\... here's some source code: >[C source deleted] > >People, what happened to good old shell script programming? Well, it's very simple. I wanted my __C__ programs to be able to remind their users what to type to get an end-of-file. So I wrote a C function. The main() in that file was enclosed in #ifdef TEST, remember! (I have received some mail pointing out problems, esp. with System V.) >BSD: >sh -c 'stty all 2> /tmp/stty.$$; set `tail -1 /tmp/stty.$$`; > shift; shift; echo $9; /bin/rm /tmp/stty.$$' It is very easy to break this (took me 2 minutes), and in any case on the system I am using I get the answer "^Z/^[", which is wrong (it should be "^Z"). >SysV: >sh -c 'stty -a | sed -e "s/.*eof = \([^;]*\).*/\1/" -e q' It is also easy to break this (took me 5 minutes; I don't know SysV well). Forking off three programs (sh, stty, rm or sed) would be a very odd thing to do in a C program when you can get the same information with a few system calls. While we're on the subject, I have read the SVID termio(ba_env) section several times, and cannot tell whether there is any general way of disabling individual elements of c_cc[] or not. Setting c_cc[VEOL] to ASCII NUL appears to disable that feature. In DYNIX V3.0.12 NFS, SunOS 3.2, and UNIX System V/386 Release 3.0, setting c_cc[VKILL] to ASCII NUL merely makes ^@ the kill character. Does anyone know which elements of c_cc[] can be suppressed and which can't?
jc@minya.UUCP (John Chambers) (10/18/88)
> While we're on the subject, I have read the SVID termio(ba_env) section > several times, and cannot tell whether there is any general way of > disabling individual elements of c_cc[] or not. Setting c_cc[VEOL] to > ASCII NUL appears to disable that feature. In DYNIX V3.0.12 NFS, > SunOS 3.2, and UNIX System V/386 Release 3.0, setting c_cc[VKILL] to > ASCII NUL merely makes ^@ the kill character. Does anyone know which > elements of c_cc[] can be suppressed and which can't? My Sys/V manual here says "These functions may be disabled individually by changing the value of the control character to an unlikely or impossible value (e.g., 0377)." In other words, the answer to your question is "No, there is no way guaranteed to disable individual elements of c_cc[]." Don't you love it when they phrase things in such a way as to give the impression that something works, when in fact it doesn't, and they know it? (:-{(> (That's a bald hacker with a moustache, a frown, and a goatee. ;-) -- John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393) [Any errors in the above are due to failures in the logic of the keyboard, not in the fingers that did the typing.]