FIFO read interrupted by signal? (Atomicity question)

Jim Rosenberg jr at oglvee.UUCP
Thu Oct 13 03:12:11 AEST 1988


This may be in TFM somewhere, but if so I haven't found it.  It would seem
absurd to me if a read() from a named pipe were not interruptable.  Bach
doesn't seem to comment directly on this question, but he does say that "The
semantics of reading and writing pipes are similar to the semantics of reading
and writing terminal devices" (p. 115).  As I understand it the whole concept
of interruptable vs. non-interruptable has to do with whether the kernel can
in some sense predict how long it will take a system call to complete;
obviously one can't predict how long before data will arrive at a named pipe,
so it would not make much sense for FIFO read() to be non-interruptable.

So the question is:  *HOW MUCH* will get returned by the read() if it's
interrupted?  It seems to me there are 3 possibilities: (1) the read() will
return 0 regardless; the next read() will return all the data in the pipe (up
to the number of bytes requested).  (2) the read will return as many bytes as
there are at the moment queued up in the FIFO's inode's direct blocks (up to
the number of bytes requested).  (3) If the bytes currently in the pipe are
from a write() that wrote more bytes than will fit in the inode's direct
blocks, the read() will return 0, otherwise it will return as many bytes as
there are at the moment queued up in the FIFO's inode's direct blocks (up to
the number of bytes requested).

Obviously the key question is really just how atomicity of pipe writes really
works.  Rochkind (Advanced Unix Programming) says that FIFO writes are atomic
*provided* you never write more bytes in one call than will fit in the inode's
direct blocks.  This would seem to imply that if a process is trying to write
few enough bytes onto a FIFO that they all will fit into the direct blocks of
the inode, but there doesn't happen to be room at the moment for all those
bytes, the process will be put to sleep *before writing ANY* of the bytes to
the FIFO.  The way I read the relevant paragraph in Bach, he's saying that
this is in fact what happens.  However if the write() is for more bytes than
will fit in the direct blocks, the process is put to sleep *AFTER* writing as
many bytes as will fit.

This all says to me that the answer to the question above has *got* to be (2),
and that moreover if every write to the pipe writes a sequence of bytes
beginning with a struct foo, and no write to the pipe writes more than will
fit in an inode's direct blocks, I am GUARANTEED even in the face of receiving
signals (e.g. SIGALARM) that a read from the pipe for sizeof(struct foo) bytes
will either return 0 with errno set to EINTR or an entire struct foo.

Have I got this right??  I'm coding a server process that clients will talk to
by a FIFO.  I want the server to wake up periodically for housekeeping.  The
messages written on the FIFO by clients will all begin with a standard struct
for a message header followed by a fixed maximum number of data bytes.
(Longer messages are divided into chunks, each of which has its own header.)
The question is whether I have to code for getting only a fragment of this
header struct if I get a signal.  Methinks Bach is telling me not to worry
about this.

And (ahem!) if this stuff is not in TFM, shouldn't it be??  What does POSIX
have to say about this?  It seems to me a good standard should address
questions about atomicity.
-- 
Jim Rosenberg                        pitt
Oglevee Computer Systems                 >--!amanue!oglvee!jr
151 Oglevee Lane                      cgh
Connellsville, PA 15425                                #include <disclaimer.h>



More information about the Comp.unix.questions mailing list