Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It's important to distinguish between the <strong>file descriptor</strong>, which is a small integer that the process uses in its read and write calls to identify the file, and the <strong>file description</strong>, which is a structure in the kernel. The file offset is part of the file description. It lives in the kernel.</p> <p>As an example, let's use this program:</p> <pre><code>#include &lt;unistd.h&gt; #include &lt;fcntl.h&gt; #include &lt;sys/wait.h&gt; int main(void) { int fd; fd = open("output", O_CREAT|O_TRUNC|O_WRONLY, 0666); if(!fork()) { /* child */ write(fd, "hello ", 6); _exit(0); } else { /* parent */ int status; wait(&amp;status); write(fd, "world\n", 6); } } </code></pre> <p>(All error checking has been omitted)</p> <p>If we compile this program, call it <code>hello</code>, and run it like this:</p> <pre><code>./hello </code></pre> <p>here's what happens:</p> <p>The program opens the <code>output</code> file, creating it if it didn't exist already or truncating it to zero size if it did exist. The kernel creates a file description (in the Linux kernel this is a <code>struct file</code>) and associates it with a file descriptor for the calling process (the lowest non-negative integer not already in use in that process's file descriptor table). The file descriptor is returned and assigned to <code>fd</code> in the program. For the sake of argument suppose that <code>fd</code> is 3.</p> <p>The program does a fork(). The new child process gets a <em>copy</em> of its parent's file descriptor table, but the file description is not copied. Entry number 3 in both processes' file tables points to the same <code>struct file</code>.</p> <p>The parent process waits while the child process writes. The child's write causes the first half of <code>"hello world\n"</code> to be stored in the file, and advances the file offset by 6. The file offset is in the <code>struct file</code>!</p> <p>The child exits, the parent's <code>wait()</code> finishes, and the parent writes, using fd 3 which is still associated with the same file description that had its file offset updated by the child's <code>write()</code>. So the second half of the message is stored <em>after</em> the first part, not overwriting it as it would have done if the parent had a file offset of zero, which would be the case if the file description was not shared.</p> <p>Finally the parent exits, and the kernel sees that the <code>struct file</code> is no longer in use and frees it.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload