thssvhj@iitmax.IIT.EDU (vijay hemraj jadhwani) (03/06/89)
In my code I use a signal (SIGALRM), system-call, following which is a 'read' system-call. The read is done on a tty-port. It is mentioned in the unix v manual that 'read' will return -1 when interrupted by a signal. Is it poss- ible to lose the partially read data by the 'read' system call, when the signal was caught , even though I execute a 'read' again ? Note that I am doing a 'read' on the tty-port. Thanks in advance for any help.
guy@auspex.UUCP (Guy Harris) (03/09/89)
>In my code I use a signal (SIGALRM), system-call, following which is a 'read' >system-call. The read is done on a tty-port. It is mentioned in the unix v >manual that 'read' will return -1 when interrupted by a signal. Is it poss- >ible to lose the partially read data by the 'read' system call, when the >signal was caught , even though I execute a 'read' again ? Note that I >am doing a 'read' on the tty-port. Assuming by "is it possible to lose the partially read data" you mean "if the 'read' blocks, and then transfers some data and blocks waiting for more data, and *then* gets interrupted by a signal, is the data it transferred more-or-less lost", the answer is "yes, and this happens under 4.xBSD as well". The problem is that, since you get a -1 back from the "read", rather than a count of the number of bytes read, you have no idea how much data was actually transferred.
jcm@mtunb.ATT.COM (was-John McMillan) (03/10/89)
In article <1134@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: >>In my code I use a signal (SIGALRM), system-call, following which is a 'read' >>... >... >for more data, and *then* gets interrupted by a signal, is the data it >transferred more-or-less lost", the answer is "yes, and this happens >under 4.xBSD as well". The problem is that, since you get a -1 back >from the "read", rather than a count of the number of bytes read, you >have no idea how much data was actually transferred. "More or less lost"? "Unnoticed" may be more like it, IF MY RECOLLECTIONS ARE CORRECT. (When did that last occur?) I can't RECALL any place for the characters to BE lost (in traditional tty reads -- as opposed to STREAMS, which I've paid little attention to), so I presume they're all in the user's buffer. A workaround? 'Hate these -- will you still respect me in the morning? (OK: neither do I.) #define BKGND '\0' SRead(f,b,l) char *b; /* read args */ { register int i; register char *c; extern int errno; errno = 0; /* ZERO out the errno flag -- so it can be tested * after SRead() to detect interrupt IYGAD */ /* ZERO out the read buffer: its cheaper if you * know the dirty-bits -- ie., if you only * zap length of soiled bytes. * OK: ZERO is 'NUL-ist' -- AA requires us to * give more-than-equal consideration to * other background chars. */ for ( i=l, c=b; i-- > 0; *c++ = BKGND); /* Only calculate kength when nec. */ if ( (i=read(f,b,l) < 0 ) ) /* Back-Scanning vs. Forward-Scanning: * Wasted effort vs minimum of lost BKGNDs */ for ( c=b+l, i=l+1; --i > 0 && *--c == BKGND; ); return i; } NB: It is a 30-second HACK. It is neither debugged nor fully general. It is far from optimized -- there are conflicting strategies. The IDEA is that you can often infer the LENGTH of data if you can "see" it against a known -- preferably un-receivable -- background. There are multiple attacks and defenses for details of the above implementation. Someone must care about them: Wire Paladin, San Francisco. jcm -- juzz muttering
ka@june.cs.washington.edu (Kenneth Almquist) (03/11/89)
guy@auspex.UUCP (Guy Harris) writes: > Assuming by "is it possible to lose the partially read data" you mean > "if the 'read' blocks, and then transfers some data and blocks waiting > for more data, and *then* gets interrupted by a signal, is the data it > transferred more-or-less lost", the answer is "yes, and this happens > under 4.xBSD as well". The problem is that, since you get a -1 back > from the "read", rather than a count of the number of bytes read, you > have no idea how much data was actually transferred. I don't know of any cases where this should happen, at least on System V. Reads on regular files, directories, disk devices and magnetic tapes are not interruptable (assuming that the disk and tape device drivers don't do nonstandard things). Reads on a pipe will block until the pipe is nonempty and then transfer what is in the pipe, so if a read on a pipe can only be interrupted before any data is transferred. Reads on cooked tty devices block until an entire line is available and then copy in the entire line at once. I don't remember the raw tty device code as well, but I'm pretty sure that in this case as well all the characters are buffered inside the kernel and transferred to the user space in an uninterruptable operation right before the read returns. Write operations on a tty are different, since it is possible to write more characters than the kernel is willing to buffer internally. If the write system call is interrupted after some but not all of the data has been written, the kernel will return the number of characters written rather than returning an error indication, so you can write out the rest of the characters later. Kenneth Almquist
mouse@mcgill-vision.UUCP (der Mouse) (03/29/89)
In article <7553@june.cs.washington.edu>, ka@june.cs.washington.edu (Kenneth Almquist) writes: > guy@auspex.UUCP (Guy Harris) writes: >> Assuming by "is it possible to lose the partially read data" you >> mean "if the 'read' blocks, and then transfers some data and blocks >> waiting for more data, and *then* gets interrupted by a signal, is >> the data it transferred more-or-less lost", the answer is "yes, and >> [...]" [...]. > Reads on cooked tty devices block until an entire line is available > and then copy in the entire line at once. The original posting seems to have expired here. There is one common case which *looks* like "partially read" data being "lost", even though this is not really true: when the signal coming in is due to a special character (interrupt or quit, for example) being typed on the tty that's being read from. In this case, the input buffer is generally flushed, losing any partial line that's been typed. Until you realize that the partial line is being buffered in the kernel and not transferred to the user's buffer until you push return (and therefore isn't partially read at all), this looks a lot like "losing partially read data". The original question probably belonged in comp.unix.questions, but we all know nobody pays any attention to the distinction any longer :-(. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu