[comp.unix.wizards] stdio/socket interaction

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (05/31/90)

(4.3BSD and/or SunOS 4.0.3)

When reading from a file descriptor connected to a socket (or to a tape
device) the read() system call may return fewer bytes than requested.
Thus if a process wants to read exactly n bytes, it must loop on read()
until it has enough data (or until read() returns 0 bytes indicating
EOF).

Given this, how safe is it to use fdopen() to attach such a file
descriptor to a buffered "FILE *" file?  Is there a possible problem
with fgets(), for example, returning less than a complete line, or
fread() returning fewer items than requested, even if EOF has not been
reached?  Or does the stdio library loop on a read() and always read
the requested number of bytes?

(My SunOS 4.0.3 manual says that "fread() stops reading if an
end-of-file or error condition is encountered while reading from
'stream', or if 'nitems' items have been read," which clearly does not
allow fread() to stop reading merely because read() needs to be called
again.)

Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

gwyn@smoke.BRL.MIL (Doug Gwyn) (06/01/90)

In article <1787@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
>When reading from a file descriptor connected to a socket (or to a tape
>device) the read() system call may return fewer bytes than requested.
>Thus if a process wants to read exactly n bytes, it must loop on read()
>until it has enough data (or until read() returns 0 bytes indicating
>EOF).

Quite right; in fact there is no guarantee for anything other than
(under certain circumstances that you can look up) pipes/fifos that
a read() will not return a short count even if all the data is
available.  Indeed, UNIX terminal handlers normally return at most
one line per read().

>Given this, how safe is it to use fdopen() to attach such a file
>descriptor to a buffered "FILE *" file?  Is there a possible problem
>with fgets(), for example, returning less than a complete line, or
>fread() returning fewer items than requested, even if EOF has not been
>reached?  Or does the stdio library loop on a read() and always read
>the requested number of bytes?

In reasonable UNIX implementations, fread() and fgets() only return a
short count when a read() returns 0 (treated as EOF condition) or
negative (error).  It should be trivial to test this on your particular
implementation, exploiting the terminal handler behavior (type your so-
called EOF character to insert delimiters at the points you want read()s
to return).