cats@lamont.ldgo.columbia.edu (catherine susch) (02/05/91)
We believe that we've discovered a problem/bug with the alarm(3) function and signal(2). Give us your feedback if you think otherwise, because we think that this is a major problem that needs fixing. HERE IT IS: We've been trying to write a timeout procedure so that if the application is waiting for input and the user decides to take a nap, beep at him to type something, and if he doesn't, then exit. The system we're using is SunOS 4.0.3 and the application is written using AT&T system 5 curses. In SunOS 3.5 we used the following test code fragment which will give the desired results: ------------------------------------------------------------------------ #include <stdio.h> #include <signal.h> #include <errno.h> #include <sys/time.h> void new_alarm(); void last_alarm(); void bad(); main() { int inp; /* start alarm and wait for input */ alarm(10); signal(SIGALRM, new_alarm); printf("waiting for input\n"); inp = getchar(); /* If input was recieved you should get here */ printf("got input\n bye\n"); signal(SIGALRM, SIG_IGN); exit(0); } void new_alarm() { /* start a new alarm and set a new handler for SIGALRM to quit if still no input received */ alarm(20); signal(SIGALRM, last_alarm); printf("alarm has sounded and new alarm is set\n"); } void last_alarm() { printf("no input recieved, exiting program\n"); exit(-1); } ------------------------------------------------------------------ Under all BSD versions it also works the same as SunOS 3.5. Under SunOS 4.0.3 and 4.1.1, however, this routine has very different results: The signal call signal(SIGALRM, last_alarm), inside the handler new_alarm(), never gets set and thus the program never gets to last_alarm(). It acts as if input was received when it wasn't. When the routine is incorporated into an application with cursesV calls, once an alarm sounds, it goes into new_alarm() and returns without resetting either signal or alarm. This causes it to call new_alarm over and over again until input is received. So here's our question: Is this a bug? Has anyone ever encountered this? WHAT IS REALLY SUPPOSED TO HAPPEN UNDER SYSTEM 5??????? Furthermore, is anyone aware of a workaround? Please email responses, since we are so preoccupied with this problem we may have trouble reading this newsgroup. I will post a summary if there is interest. Cat ________________________________________________________________________________ ______ ___ _________ | / / \ / | Catherine Ann Teresa Susch / / \ / | Lamont-Doherty Geo. Observatory / /_______\ / | of Columbia University /_______ / \ / __ | Palisades,N.Y. 10964 USA /__ | __/ | cats@lamont.ldgo.columbia.edu ___________________________________________|____________________________________
rbj@uunet.UU.NET (Root Boy Jim) (02/06/91)
In article <3313@lamont.ldgo.columbia.edu> cats@lamont.ldgo.columbia.edu (catherine susch) writes: > > > We believe that we've discovered a problem/bug with > the alarm(3) function and signal(2). Give us your > feedback if you think otherwise, because we think > that this is a major problem that needs fixing. What you have discovered is an incompatibility between systems. There are two kinds of system calls. Ones that are interruptible, and ones that aren't. Most are not. Wait and read or write on a slow device (such as a tty, where input may never occur) are interruptible. When interrupted by a signal handler, they return -1 and set errno to EINTR, or EAGAIN or some such. Berkeley changed these calls to automaticly restart in 4.2BSD. Purists screamed long and hard and a bit was put into the sigvec to allow a choice to be made for each type of signal. I don't know which versions you have. Another complication is that you are using two timeouts, not one. Probably the most portable solution is to use setjmp with the getchar and longjmp from the alarm routine. You are right. It is a major problem. It has been fixed, in the POSIX specs, but it'll take awhile until everyone is fully compliant. Also, POSIX doesn't specify the behavior of "signal", only that of "sigaction". Such is life. -- Root Boy Jim Cottrell <rbj@uunet.uu.net> I got a head full of ideas They're driving me insane
hue@island.COM (Pond Scum) (02/07/91)
In article <121464@uunet.UU.NET> rbj@uunet.UU.NET (Root Boy Jim) writes: >There are two kinds of system calls. Ones that are interruptible, >and ones that aren't. Most are not. Wait and read or write on a >slow device (such as a tty, where input may never occur) are >interruptible. When interrupted by a signal handler, they >return -1 and set errno to EINTR, or EAGAIN or some such. Writes to a file appear to be interruptable and not restartable under SunOS 4.1.1. Suprised the sh*t out of me when someone started having problems with it. In 4.0.3 and previous versions writes to "fast" devices could not be interrupted. I'll post the test program in a followup. >Berkeley changed these calls to automaticly restart in 4.2BSD. >Purists screamed long and hard and a bit was put into the sigvec >to allow a choice to be made for each type of signal. For the original poster, in order to prevent the auto restart, use sigvec() or sigaction() (only available in SunOS 4.1.1), and specify SV_INTERRUPT in the sv_flags field (SA_INTERRUPT and sa_flags for sigaction()). >I don't know which versions you have. Another complication is >that you are using two timeouts, not one. Probably the most >portable solution is to use setjmp with the getchar and >longjmp from the alarm routine. If all you want is a timeout on tty input, I'd just use VTIME and VMIN, seems simpler to me (though perhaps less portable): #include <sys/termios.h> #include <stdio.h> main() { struct termios oldt, newt; int c; ioctl(fileno(stdin), TCGETS, &oldt); newt = oldt; newt.c_cc[VMIN] = 0; newt.c_cc[VTIME] = 50; newt.c_lflag &= ~ICANON; ioctl(fileno(stdin), TCSETS, &newt); if ((c = getchar()) == EOF) fputs("No input\n", stderr); ioctl(fileno(stdin), TCSETS, &oldt); return(0); } (I know this isn't internals, but this is where to followups were directed) ---- "I'll tell you what "MTV" stands for. It stands for "Music To Vomit by"." -Bobby "The Brain" Heenan Jonathan Hue, Senior Coding Pig Island Grapics Corp. Graphic Arts Division 4000 Civic Center Drive San Rafael, CA {uunet,sun}!island!hue hue@island.com