Is a successful call to write(2) atomic?

Ronald F. Guilmette rfg at tristatelogic.com
Wed Jun 16 01:13:21 UTC 2021


In message <76ccd29b-d54b-803f-4b02-a565bb649eca at panix.com>, 
Kurt Hackenberg <kh at panix.com> wrote:

>> On objects capable of seeking, the write() starts at a position given
>> by the pointer associated with fd, see lseek(2).  Upon return from write(),
>> the pointer is incremented by the number of bytes which were written.
>
>That's talking about the pointer associated with the file descriptor. 
>The system call fork() gives the child process *copies* of file 
>descriptors. Not clear whether that pointer is also copied.

If i am remembering correctly, this is the exact issue that I got verbally
beaten up about on a Posix standards group mailing list some months back,
simply because there were two -very- similar bits of terminology which
had important *but critically different* semantics associated with them.

(I don't even remember what the two terms in question were... something
like "file descriptor" and "file description"... or at any rate, some
two terms that were approximately that close to one another, lexigraphically
speaking, and which were thus VERY easy to confuse with one another.)

Anyway, if I am rembering correctly, the outcome of my brief foray onto
the Posix list in question was that indeed, a fork() causes the child to
receive "a copy of" the file descriptor that is open in the parent,
*but* that after that each process is effectively on its own and they
*do not* thereafter *share* a single common file descriptor but instead
each maintains its own separate copy thereof after the fork() (and perhaps
also its own separate file pointer, if i am remembering correctly).

Thanks for forcing me to remember all this.  Now that I have, I see that
this may in fact be the explanation for the garbled output files I've
seen.

I will have to go back and review that email conversation, but again, my
recollection is that I got abused because I had failed to grasp that after
a fork, both parent & child have their own independent (and initially
identical) *copies* of any open file descriptors, but that after the fork,
each (copied) "fd" is a separate and distinct thing... *HOWEVER* there is
also some thing which exists at an even lower level and which represents
the kernel's direct interface to the (opened) output device or file.

I need to do some programming now, but now I think I may now understand
the actual problem.  If I do, then just sending all the output data to some
"master" process and having it be the only one making calls to write() may
indeed solve the problem.   (If it does, then I'll declare that... in my
opinion... write() *does not* have any kind of "atomicity" problem, but
rather, allowing a child process to write to any given fd which it inherited
(a copy of) via fork(), even as other processes within the same process
group do likewise will almost always lead to heartache, misery, and garbled
output.)


Regards,
rfg


More information about the freebsd-questions mailing list