[net.unix-wizards] Questions about read

hokey@gang.UUCP (Hokey) (12/22/84)

While rewriting an application to provide for robust error handling of
read() and write() calls, I noticed the manual page for SysV says a few
strange things about read().

For starters, the function returns an int.  One passes an unsigned number
of bytes which specifies the maximum number of characters which should be
returned.  The return value is a non-negative integer indicating the actual
number of bytes read, or -1.  If this is true, why is the number of bytes
an unsigned quantity?

Write() is similarly documented to a lesser degree.

Nextly, what happens to the current file position if a read() or write() is
interrupted?  This is another non-documented issue, near as I can tell.
Should another lseek() be issued when restarting one of these calls (when
dealing with disk files)?

If so, one must be careful when reading or writing to disk files when doing
realtive lseek()s.

What happens if, under 4.2, an alarm call causes the read() or write() to
be restarted for me (is there a good reason why this was changed in 4.2)?

I am interested in information pertaining to this gluck for V7, Sys{III,V},
and {2,4}BSD.

-- 
Hokey           ..ihnp4!plus5!hokey
		  314-725-9492

chris@umcp-cs.UUCP (Chris Torek) (12/24/84)

> ... what happens to the current file position if a read() or write()
> is interrupted?  This is another non-documented issue, near as I can
> tell.  Should another lseek() be issued when restarting one of these
> calls (when dealing with disk files)?

read() and write() on disk files cannot be interrupted: the entire
transfer will happen before a signal is taken.  This ought to be true
even in System N.

You might lose the return value if a signal arrives "inside" a disk
read() or write().  Other than that, everything should be OK; the
current position will be after the read/written bytes.

> What happens if, under 4.2, an alarm call causes the read() or write() to
> be restarted for me (is there a good reason why this was changed in 4.2)?

The alarm will interrupt a read() or write() of a ``slow device'' (e.g.,
terminal; technically, anything that sleep()s at > PZERO).  After the
alarm handler returns, the system call will continue wherever it left
off, and will pretend it was never interrupted at all.  Thus you won't
lose the return value, or anything else nasty.  This is only true in 4.2
(and 4.1 when using -ljobs).
-- 
(This line accidently left nonblank.)

In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/26/84)

> strange things about read().
> 
> For starters, the function returns an int.  One passes an unsigned number
> of bytes which specifies the maximum number of characters which should be
> returned.  The return value is a non-negative integer indicating the actual
> number of bytes read, or -1.

That's right; this bogosity is required for backward compatibility.
I advise not telling read() or write() to handle more bytes than can
be expressed in an int.

> Nextly, what happens to the current file position if a read() or write() is
> interrupted?

Filesystem I/O is not interrupted by signals.

> What happens if, under 4.2, an alarm call causes the read() or write() to
> be restarted for me (is there a good reason why this was changed in 4.2)?

I/O to/from a slow device (e.g. terminal) is automatically restarted by
4.2BSD.  This was somebody's "better idea" that breaks existing code.
You can avoid the automatic system call restart by some kludgery first
described by Donn Seeley and posted by me several months ago.