19

Using the posix read() write() linux calls, is it guaranteed that if I write through one file descriptor and read through another file descriptor, in a serial fashion such that the two actions are mutually exclusive of each other... that my read file descriptor will always see what was written last by the write file descriptor?

i believe this is the case, but I want to make sure and the man page isn't very helpful on this

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Michael Xu
  • 557
  • 1
  • 5
  • 14

3 Answers3

30

It depends on where you got the two file descriptors. If they come from a dup(2) call, then they share file offset and status, so doing a write(2) on one will affect the position on the other. If, on the other hand, they come from two separate open(2) calls, each will have their own file offset and status.

A file descriptor is mostly just a reference to a kernel file structure, and it is that kernel structure that contains most of the state. When you open(2) a file, you get a new kernel file structure and a new file descriptor that refers to it. When you dup(2) a file descriptor (or pass a file descriptor through sendmsg), you get a new reference to the same kernel file struct.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • what if i use separate open() calls on each individually.. will the data from the written fd be available to the read fd? – Michael Xu Mar 12 '11 at 18:47
  • 2
    With two separate open calls, each fd will have its own position. So if both are at the beginning of the file, and you write with one, the other will still be at the beginning of the file, so a write there will overwrite what the first write wrote, unless you opened the file with O_APPEND (in which case every write implicitly seeks to the end before writing). – Chris Dodd Mar 15 '11 at 05:08
  • 4
    thanks chris. my question was a bit different, but yes... if that second one was reading, it would read exactly what the first one wrote. the asnwer to my question is that yes, its guaranteed that anyone reading from the file after the write has returned will read whatever the write wrote. this is because linux locks access to io cache pages in memory – Michael Xu Mar 16 '11 at 00:34
  • so can we have two file descriptors pointing on the same file but have different value? – Vaggelis Spi Nov 17 '16 at 23:21
  • @MichaelXu do you have any reference says "read on a fd will always get what has written by a different fd if both fd pointing to the same file(the two fds are created by separated open(2))"? I don't think Chris Dodd says that. – ideawu Apr 07 '21 at 08:28
1

This is guaranteed if they both refer to the same file description, aka you got them from "dup" or "dup2" (or inherited via fork()).

After a successful return from one of these system calls, the old and new file descriptors may be used interchangeably. They refer to the same open file description (see open(2)) and thus share file offset and file status flags; for example, if the file offset is modified by using lseek(2) on one of the descriptors, the offset is also changed for the other.

Erik
  • 88,732
  • 13
  • 198
  • 189
0

when you use dup() or dup2() or fork() , the file table is shared by both of the file descriptors. so if you write something from one file descriptor , and again write something through other file descriptor , then it is appended not overwritten.

but if two independent process open one file , then the data written by both processes may get mixed.

user2742399
  • 61
  • 2
  • 6