As far I understand it, Fds are integers that are used to look up the open files in the kernel's file description table. So therefore if you have a code segment like this:
int fd[2], temp1, temp2;
pipe(fd);
temp1 = fd[0];
temp2 = fd[1];
close(temp1);
close(temp2);
All the file descriptors to the pipe are closed and thus the pipe would no longer exist. Since FDs are simply ints, saying close(temp1)
is identical to saying close(fd[0])
.
In light of all this (and please let me know if I am misunderstanding) I am confused by what happens after a fork()
call. Since the child process inherits the same FDs and state of the parent, the child's FDs should be the same ints as the parents. So by that logic, if I close(fd[0])
in the child, I believe it would also prevent the parent from accessing the file. Since close()
"frees" that integer from the file descriptor table, the parent should not have any way to reference the file.
Is this the case? It seems very unlikely that this is the actual case, since it would cause FDs between parents and children to be very difficult to use (especially since you do not know which process will run first). So if this logic is incorrect, are the FDs duplicated on fork()
? How in the file descriptor table are the parent and child Fds related, especially between close()
calls? It helps me a lot to be able to draw out the file descriptor table, so I would like as specific as an answer as possible.
Thanks for any help with this!
File descriptors are generally unique to each process, but they can be shared by child processes created with a fork subroutine or copied by the fcntl, dup, and dup2 subroutines.
close() closes a file descriptor, so that it no longer refers to any file and may be reused. Any record locks (see fcntl(2)) held on the file it was associated with, and owned by the process, are removed (regardless of the file descriptor that was used to obtain the lock).
A file descriptor is eventually closed by the close(2) system call or by the process' exit. By default, file descriptors 0, 1, and 2 are opened automatically by the C runtime library and represent the standard input, standard output, and standard error streams for a process.
within a parent process when a child closes a file descriptor inherited across a fork. In other words, does the file remain open in the parent, or is it closed there? It stays open in the parent.
No. What the child does in the way of closing files affects just the child's copy of the file descriptors, without affecting the parent's copy of the file descriptors.
However, immediately after forking, both sets of file descriptors (in parent and child) refer to the same set of open file descriptions (note the 'descriptor' vs 'description' terminology). If the child does things such as read or seek that affect the file description, then the child's activities affect the parent too.
You'll want to study the POSIX specifications of open()
,
fork()
and execve()
(especially the execve()
page) with considerable care.
The parent and the child have their own file descriptor tables.
If the child closes (say) file descriptor 5, then the parent still has file descriptor 5 open.
If the child then opened another file, and it happened to get descriptor 5, then the child's file descriptor 5 would refer to a different file than the parent's file descriptor 5 (which would not have changed).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With