2

I know that after fork(), all files (and their offsets) opened by the parent are shared
by the child. That is, parent and child share the file table entry of all the files.

What happens if child opens some file. Is it specific to child? Or is it shared by parent?

I've also written small test program. Is this the right way to test this?

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define FLAG (O_RDWR | O_CREAT | O_TRUNC)

int main(int argc, char *argv[])
{
    pid_t pid;

    if ((pid = fork()) < 0) {
        perror("fork error");
        exit(1);
    } else if (pid == 0) {
        int fc;
        if ((fc = open("abc", FLAG)) == -1) {
            perror("cannot open abc");
            exit(-1);
        }
        exit(fc);
        //returning the file descriptor open through exit()
    } else {
        int fp;
        wait(&fp);
        if (fp == -1)
            exit(1);
        if (fcntl(fp, F_GETFD) == -1)
            perror("doesn't work");     //Ouputs: doesn't work: Bad file descriptor
        //returns file descriptor flags
        //should not return error, if fd is valid
    }
    return 0;
}

Thanks.

mohit
  • 5,696
  • 3
  • 24
  • 37
  • To make it short: **no**. Child gets a snapshot of parent's handles in the moment of the fork, everything will happen after that won't be reflected. – Adriano Repetti Apr 19 '13 at 10:56
  • @MM. I'm opening file in child after `fork` not before as the cited question does. – mohit Apr 19 '13 at 10:56
  • This is not a duplicate of the question [Are file descriptors shared when forking](http://stackoverflow.com/questions/4277289/are-file-descriptors-shared-when-forking) as has been suggested. That asks about file descriptors opened before forking; this asks about file descriptors created after forking. The situations and answers are quite different. – Jonathan Leffler Apr 19 '13 at 16:32

4 Answers4

7

The child gets a copy of the file descriptors of the parent in the moment of fork().

If you open a file in the child, it's not shared with the parent.

Also if you open a file in the parent process after fork() it won't be shared with the child.

Johnny Mnemonic
  • 3,822
  • 5
  • 21
  • 33
0

All remaining open file will be closed when your child process exits. So, it is no more valid when the parent try to use it.

Bechir
  • 987
  • 10
  • 26
0

man fork :

The child inherits copies of the parent's set of open file descriptors. Each file descriptor in the child refers to the same open file description (see open(2)) as the corresponding file descriptor in the parent. This means that the two descriptors share open file status flags, current file offset, and signal-driven I/O attributes (see the description of F_SETOWN and F_SETSIG in fcntl(2)).

If you close a file in the child, it will also been closed in parent.

ibi0tux
  • 2,481
  • 4
  • 28
  • 49
  • 1
    when child exits, all files are closed. since parent `stdout` is also shared, why is that not closed? – mohit Apr 19 '13 at 11:06
  • what function do you use to close all file descriptors ? – ibi0tux Apr 19 '13 at 11:08
  • I mean does normal exit close all files? – mohit Apr 19 '13 at 11:08
  • No it doesn't. Depending on your os and it's configuration, the files will be automatically closed or not. On linux file descriptor are closed after process ending most of time, but if the file descriptor is still used by another process, it won't be closed. – ibi0tux Apr 19 '13 at 11:11
  • but i would like to knwo if in the live time of the child the parent process can see the file descriptor opened by the child – c4f4t0r Oct 21 '13 at 19:58
0

I have this code and i saw the file descriptors are shared with parent pid

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


pid_t p;

int main(){
    if((p = fork()) != -1){
            open("file",O_APPEND);
            sleep(120);
    }
}

gcc -o fork fork.c

root      4576  2675  0 06:39 ttyS0    00:00:00 ./fork
root      4577  4576  0 06:39 ttyS0    00:00:00 ./fork

lsof -p 4576
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
fork    4576 root  cwd    DIR    8,1     4096 69266 /root
fork    4576 root  rtd    DIR    8,1     4096     2 /
fork    4576 root  txt    REG    8,1     9882 70117 /root/fork
fork    4576 root  mem    REG    8,1  1682436 23185 /lib/libc-2.11.3.so
fork    4576 root  mem    REG    8,1   143987 23174 /lib/ld-2.11.3.so
fork    4576 root    0u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4576 root    1u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4576 root    2u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4576 root    3r   REG    8,1        0 75269 /root/file

lsof -p 4577
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
fork    4577 root  cwd    DIR    8,1     4096 69266 /root
fork    4577 root  rtd    DIR    8,1     4096     2 /
fork    4577 root  txt    REG    8,1     9882 70117 /root/fork
fork    4577 root  mem    REG    8,1  1682436 23185 /lib/libc-2.11.3.so
fork    4577 root  mem    REG    8,1   143987 23174 /lib/ld-2.11.3.so
fork    4577 root    0u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4577 root    1u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4577 root    2u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4577 root    3r   REG    8,1        0 75269 /root/file

The same result using this python code:

#!/usr/bin/env python

import os
import time

print os.getpid()

if os.fork() is not None:
  print os.getpid()
  fd = open("/etc/passwd","r")
  time.sleep(120)

Now you can check the parent and child process:

python pyfork.py
25131
25131
25132

lsof -p 25131
......
......
......
python  25131 root    3r   REG    8,8      2080  143680 /etc/passwd

lsof -p 25131
......
......
......
python  25132 root    3r   REG    8,8      2080  143680 /etc/passwd
c4f4t0r
  • 1,563
  • 15
  • 24
  • Your lsof output shows that each process happens to have a file descriptor open to the same file (NODE). It does *not* tell you that they are sharing an open file description. – pilcrow Oct 21 '13 at 15:11
  • Well, yes and no. The lsof output you posted has a column named NODE, which is what I meant to draw your attention to. The meaning of values in that field is the file's inode. – pilcrow Oct 21 '13 at 20:27
  • why process 4576 see file descriptor 3 if i open the /root/file inside the child? – c4f4t0r Jan 18 '15 at 15:05
  • 1
    There's a bug in your code: fork() returns 0 in the child and pid of the child in the parent process. For both parent and child your condition will be true so they will both open the same file. – xyz Oct 17 '15 at 00:11
  • @xyz I don't think is bug in my C code, I wrote in python and the problem is the same, file descriptor open after fork, is shared with the parent process, I think this happen because the parent and child use the same file descriptor table. – c4f4t0r Jan 03 '16 at 15:15
  • It is a bug, in Python os.fork() doesn't return None. Check the documentation: https://docs.python.org/2/library/os.html#os.fork – xyz Jan 04 '16 at 18:28
  • @xyz is not depending about my code, you can try to use the code you want and you well see, the files opened for the child process is shared with parent. – c4f4t0r Jan 04 '16 at 23:18
  • It is your code, this https://gist.github.com/anonymous/664ac598d34bff862019 works fine. – xyz Jan 06 '16 at 11:29