mike@samira.UUCP (Mike Deutsch) (11/10/86)
I have a program written in C which I need to run under both ULTRIX 1.2 on an 8600 and Microsoft sys V XENIX on an IBM AT. In the application, the user enters commands from the keyboard. I trap interrupts, and go to an interrupt handler when they hit interrupt. In this handler, I ask the user if they wish to continue or abort. Under XENIX, when the program returns from the interrupt handler, the program doesn't still expect to be reading at the read where the interrupt trap was received. Under ULTRIX, it does. 1) Which one is correct? It's the same code, both C, so one must be wrong. 2) I'd prefer the program to function as it does under XENIX. How can I get it to not continue with the read when there was an interrupt during the read? Thank you very much. Please e-mail me the answer, as our net connection remains slightly shaky.
ballou@brahms (Kenneth R. Ballou) (11/11/86)
In article <43@samira.UUCP> mike@samira.UUCP (Mike Deutsch) writes: >I have a program written in C which I need to run under both ULTRIX 1.2 >on an 8600 and Microsoft sys V XENIX on an IBM AT. > >In the application, the user enters commands from the keyboard. >I trap interrupts, and go to an interrupt handler when they hit >interrupt. In this handler, I ask the user if they wish to continue >or abort. > >Under XENIX, when the program returns from the interrupt handler, the >program doesn't still expect to be reading at the read where the interrupt >trap was received. Under ULTRIX, it does. > >1) Which one is correct? It's the same code, both C, so one must be wrong. ABSOLUTELY NOT! Library functions are exactly that: library functions. C does not specify how library functions must behave, or even what functions must be provided in an implementation's library. Now, if you browse through signal.h, you will note an error value called EINTR. At least on BSD 4.2, if a signal arrives while read is awaiting data, read returns -1 and errno is set to EINTR: [EINTR] A read from a slow device was interrupted before any data arrived by the delivery of a signal. Again, please note that this is part of UNIX, not of C proper. >2) I'd prefer the program to function as it does under XENIX. How can >I get it to not continue with the read when there was an interrupt during >the read? Since read has returned -1, it seems you could examine the value of errno and repeat the read call if errno is equal to EINTR, viz.: while (read (....) == -1 && errno == EINTR) ; Probably you will want to save the value returned by read for later use. -------- Kenneth R. Ballou ...!ucbvax!brahms!ballou Dept. of Mathematics ballou@brahms.berkeley.EDU University of California Berkeley, California
guy@sun.uucp (Guy Harris) (11/12/86)
> >1) Which one is correct? It's the same code, both C, so one must be > > wrong. > > ABSOLUTELY NOT! Library functions are exactly that: library functions. Correct. > C does not specify how library functions must behave, or even what functions > must be provided in an implementation's library. Correct, but not if you're talking about ANSI C. It actually *does* specify some functions that must be provided, and how they behave. One of these functions is "signal"; however, since "read" is (fortunately) not one of these functions, it does not specify what happens to a "read" when you return from a signal handler. > Now, if you browse through signal.h, you will note an error value called > EINTR. At least on BSD 4.2, if a signal arrives while read is awaiting > data, read returns -1 and errno is set to EINTR: Well, not really; if you browse through "errno.h" you'll find EINTR, but you sure won't find it in "signal.h". More to the point, under *some* circumstances, on BSD 4.2 (which is what ULTRIX-32, at least, is derived from; XENIX, however, does not derive its signal handling code from BSD 4.2), returning from a signal handler to a "read" will cause the "read" to return -1 and set "errno" to EINTR. However, in the most common circumstances, it won't. With the older signal mechanism that V7, S3, and S5-derived systems, such as XENIX, provide, returning from a signal handler to a "read" will cause the "read" to return -1 and set "errno" to EINTR. (Actually, it's a combination of the signal and "read" mechanisms, and I think in the S5R3 "streams" code, if the signal handler returns to the "read" *after it has already transferred some data* the "read" will return the number of bytes it transferred before being interrupted. This is what the signal and "read" mechanisms should have done all along; otherwise, you have no idea how much data was transferred before the interrupt occurred.) With the newer 4.2BSD and 4.3BSD signal mechanisms, if the "read" has not transferred any data, and the signal in question has not been specified as interrupting system calls, returning from the signal handler will cause the "read" to be reexecuted. If the read has already transferred some data, or if the 4.3BSD feature that permits you to specify that particular signals should interrupt calls like "read" has been used, returning from the signal handler will cause the "read" to return -1/EINTR, just as it does with older signal mechanisms. > >2) I'd prefer the program to function as it does under XENIX. How can > >I get it to not continue with the read when there was an interrupt during > >the read? > > Since read has returned -1, it seems you could examine the value of errno > and repeat the read call if errno is equal to EINTR, viz.: Since "read" hasn't returned -1, but has been repeated for you by the system, you can't. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)
ballou@brahms (Kenneth R. Ballou) (11/13/86)
In article <9180@sun.uucp> guy@sun.UUCP writes: [The next three lines are my stupid remark. --- K. Ballou] >> Now, if you browse through signal.h, you will note an error value called >> EINTR. At least on BSD 4.2, if a signal arrives while read is awaiting >> data, read returns -1 and errno is set to EINTR: > >Well, not really; if you browse through "errno.h" you'll find EINTR, but you >sure won't find it in "signal.h". Quite right. I was too busy fuming over what I had just read to check my response carefully. Sorry ... -------- Kenneth R. Ballou ...!ucbvax!brahms!ballou Dept. of Mathematics ballou@brahms.berkeley.EDU University of California Berkeley, California 94720
caf@omen.UUCP (Chuck Forsberg WA7KGX) (11/13/86)
In article <43@samira.UUCP> mike@samira.UUCP (Mike Deutsch) writes:
:Under XENIX, when the program returns from the interrupt handler, the
:program doesn't still expect to be reading at the read where the interrupt
:trap was received. Under ULTRIX, it does.
....
:2) I'd prefer the program to function as it does under XENIX. How can
:I get it to not continue with the read when there was an interrupt during
:the read?
A longjmp from within the interrupt handler should do the trick. When 4.2 BSD
changed the way signals affected read calls, thus breaking rb/sb, I changed
the interrupt handler from the previous no-op (just let the read fail) to a
longjmp. Just make sure the longjmp always has a valid place to long jump to!
Chuck Forsberg WA7KGX Author of Pro-YAM communications Tools for PCDOS and Unix
...!tektronix!reed!omen!caf Omen Technology Inc "The High Reliability Software"
Voice: 503-621-3406 17505-V Northwest Sauvie Island Road Portland OR 97231
TeleGodzilla BBS: 621-3746 2400/1200 CIS:70007,2304 Genie:CAF Source:TCE022
omen Any ACU 1200 1-503-621-3746 se:--se: link ord: Giznoid in:--in: uucp
omen!/usr/spool/uucppublic/FILES lists all uucp-able files, updated hourly