Return to BSD News archive
Received: by minnie.vk1xwt.ampr.org with NNTP id AA6500 ; Sun, 10 Jan 93 10:14:41 EST Path: sserve!manuel.anu.edu.au!munnari.oz.au!uunet!europa.asd.contel.com!howland.reston.ans.net!spool.mu.edu!agate!dog.ee.lbl.gov!horse.ee.lbl.gov!torek From: torek@horse.ee.lbl.gov (Chris Torek) Newsgroups: comp.unix.bsd Subject: Re: a unix terminal question Date: 12 Jan 1993 21:05:35 GMT Organization: Lawrence Berkeley Laboratory, Berkeley CA Lines: 75 Message-ID: <28370@dog.ee.lbl.gov> References: <1iql6kINNisk@ub.d.umn.edu> <1993Jan11.215312.2080@fcom.cc.utah.edu> <uonuhjc@zola.esd.sgi.com> NNTP-Posting-Host: 128.3.112.15 (I note that this article would have gone to both comp.lang.c and comp.unix.bsd. It is rare for an article ever to belong in both groups. This particular stuff really should not be in comp.lang.c at all, so I have redirected it.) In article <uonuhjc@zola.esd.sgi.com> dps@delhi.esd.sgi.com (D.P. Suresh) writes: >select() or poll() in itself will not get you the desired result >[because the O/S is doing line gathering and you must disable this too]. > /* Create proper environment for select() */ > FD_ZERO( &readfds ); > FD_ZERO( &writefds ); > FD_ZERO( &exceptfds ); > FD_SET( fileno(stdin), &readfds ); Since no write or exception file descriptors will be used, none need be provided. Select() allows (fd_set *)NULL arguments, meaning `nothing of interest here'. > /* We shall specify 0.5 sec as the waiting time */ > timeout.tv_sec = 0; /* 0 seconds */ > timeout.tv_usec = 500; /* 500 microseconds */ tv_usec is indeed microseconds, so 500 us is 0.0005 seconds, not 0.5. (Most current UNIX systems will round this up to their actual internal timeout rate of 100 Hz, or .01 seconds.) > /* Put tty in raw mode */ > ioctl(fileno(stdout), TCGETA, &otty); ... > ioctl(fileno(stderr), TCSETAW, &ntty); Here I have to wonder why the tty modes are obtained from stdout and set on stderr when we are going to read stdin. If the reading is to be from fileno(stdin), the tty operations should be done there as well, since their purpose is to affect this reading. In more complex tty control programs (such as editors), the goal may be both to affect input and output. In this case it is a bit more reasonable to try both stdin and stdout. In any case it seems wrong to touch stderr. The wise and cautious programmer might consider: iocfd = STDIN_FILENO; /* or simply 0 */ if (ioctl(iocfd, TCGETA, &otty) < 0) { iocfd = STDOUT_FILENO; /* 1---these should be in <unistd.h> */ if (ioctl(iocfd, TCGETA, &otty) < 0) { /* disable tty operations, i/o is pipes or similar */ ttycontrol = 0; return; } } ... (void)ioctl(iocfd, TCSETAW, &ntty); In this particular case (reading stdin only), the attempts using STDOUT_FILENO are not advised. On BSD systems, one should also use care lest code like this be stopped (via, e.g., ^Z) between the `get' and `set' phases and the tty settings be changed. Careful use of signal handlers and, if necessary, setjmp and longjmp can make tty alteration appear atomic. >This feature should be used wisely. One could incur quite a lot of >performance penalties as expressed by terry. Indeed, particularly if the keyboard mode is changed twice on every call to this checking function. Incidentally, note that select() for reading returns true at EOF (because reading EOF does not block). Callers should be prepared for this. -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov