Do we need to close the read end of a pipe explicitly whose write end has already been closed?
Asked Answered
J

2

12

I have this following scenario.

  1. I create a pipe.

  2. Forked a child process.

  3. Child closes read end of the pipe explicitly and writes into the write end of the pipe and exits without closing anything ( exit should close all open file/pipe descriptors on behalf of the child, I presume).

  4. Parent closes the write end of the pipe explicitly and reads from the read end of the pipe using fgets until fgets returns NULL. ie it reads completely.

Now my question is, why does the parent need to close the read end of the pipe explicitly once its done reading? Isn't it wise for the system to delete the pipe altogether once complete data has been read from the read-end?

I dint close the read end explicitly in the parent and I have Too many file descriptors error sooner or later while opening more pipes. My assumption was that the system automatically deletes a pipe once its write end is closed and data has been completely read from read end. Cos you cant from a pipe twice!

So, whats the rationale behind the system not deleting the pipe once data has been completely read and write end closed?

Janice answered 6/8, 2012 at 10:24 Comment(2)
"Cos you cant from a pipe twice!"???Algar
@KerrekSB What I meant was you can read the same pipe twice but will see EOF the second time right?Janice
A
8

You're correct that the system will close the write end of the pipe once the child exits. However there could be another write end of that pipe open, if the child forks or passes a duplicate of the write end to another process.

It is still true that the system would be able to tell when all the descriptors at one end of a pipe have been closed (either explicitly or because the owning process exited). It still doesn't make sense to close those on the other end of the pipe, as that would lead to confusion when the parent process tries to close the descriptor on its end of the pipe; either:

  • the fd has been closed by the system, in which case there is an error as it tries to close an already closed fd; or
  • the fd has been reused, which is even worse as it is now closing a completely unrelated fd.

From the point of view of the system, it might well have discarded the pipe once all the descriptors at one end have been closed, so you don't need to worry about inefficiency there. What matters more is that the user space process should have a consistent experience, which means not closing the descriptor unless it is specifically requested.

Airflow answered 6/8, 2012 at 10:32 Comment(0)
G
6

File descriptors are not closed by the system, until the process exits. This is true for pipes, as well as any other file descriptor.

There's a big difference between a pipe (or any other file) with no data in it and a closed file descriptor.
When a file descriptor is closed, the system can reuse its number for a new file descriptor. Then, when you read, you get something else. So after you've closed a file descriptor, you must no longer use it.

Now imagine that once there's no more data, the system would automatically close the file descriptor. This would make the number available for reuse, and a subsequent unrelated open may get it. Now the reader, who doesn't know yet that there's no more data, will read from what it thinks is the pipe, but will actually read from another file.

Gilgai answered 6/8, 2012 at 10:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.