kolling@magic.ARPA (05/11/85)
Does anyone have a fix for the problem described below? Please send mail to me at (kolling@decwrl.arpa or {decvax, purdue, sun, ucbvax}!decwrl!kolling) as I don't normally read this newsgroup. Thanks. /* Test program to prove that select() doesn't work correctly under Unipress Emacs subshells. Kenneth Brooks 5/9/85 DEC Systems Research Center Expected behavior: 1. It types What is your name? and expects input, on the same line. 2. You type something, let's say, "Fred", and press Return. 3. It replies Hello, Fred, nice to meet you. When run under a C-shell on a terminal, this is in fact what it does. But when run under a C-shell running in a window of Unipress Emacs (which uses pty's), it waits 15 seconds before typing the reply and finishing. Analysis and debugger results: Before doing the read to get the input, I do a select() kernel call with descriptor 0 masked on as an interesting source of input. Select is called with a 15 second timeout. In the normal case on the terminal, select returns as soon as I press Return, and it reports input on descriptor 0. In the bad case, on the pty, select does not return until the timeout is up, and when it does, it returns 0. Nevertheless, after select times out, a read works just fine, and returns all the characters I typed. Conclusion: select SIMPLY IS NOT AWARE of input events on a pty, at least not a pty used in the manner that Unipress Emacs uses them. */ #define INCL(set, item) (set |= (1 << item)) typedef char Linebuf[80]; Linebuf outbuf1 = "What is your name? "; Linebuf outbuf2 = "Hello, "; Linebuf outbuf3 = ", nice to meet you.\n"; Linebuf inbuf; int z, namesize; main() { z = write(1, outbuf1, 19); namesize = myread(0, inbuf, 80); z = write(1, outbuf2, 7); z = write(1, inbuf, namesize-1); z = write(1, outbuf3, 20); close(1); } /* I don't directly use the kernel call read, I use myread, which uses the select() feature. It seems silly here, but this program is abstracted from a large system in which it was important. */ #include <sys/time.h> struct timeval time; int readFDs, writeFDs, exceptFDs, nfound; int myread(fd, buffer, nbytes) int fd; char *buffer; int nbytes; { readFDs = 0; writeFDs = 0; exceptFDs = 0; INCL(readFDs, fd); time.tv_usec = 0; time.tv_sec = 15; /* here's the part that malfunctions */ nfound = select(32, &readFDs, &writeFDs, &exceptFDs, &time); /* this is, in fact, a read */ return syscall(3, fd, buffer, nbytes); }