Re: Open files not shared with the child process ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





Deepak Joshi <deepak_cins@xxxxxxxxxxx> wrote:
Hi all,

By reading all these mails on fork( clone ) its very
difficult for me ( and i think all the students those
r very new to linux kernel and os development ) to
learn what is actually happening after fork, i.e open
files are shared r not. so can any body plz explain it
clearlly.

Thanks in advance

Deepak Joshi.


--- Jan Hudec wrote:

> On Sun, Dec 25, 2005 at 16:12:13 +0200, MHD.Tayseer
> Alquoatli wrote:
> > > There are two things. The file handle used in
> userspace, which is an
> > > integeral index into a file descriptor table,
> and the file descriptor
> > > itself,
> > > which is struct file. The struct file is
> *always* shared after both clone
> > > and
> > > fork. The CLONE_FILES flag specifies whether the
> file descriptor *table*
> > > will be shared, or not.
> >
> > we are talking about the opened file table that is
> in the task descriptor
>
> Sure we are. But the original poster was not at all
> clear what he was talking
> about.
>
> >
> > > > well .. when you call fork, the process
> descriptor of the calling
> > > > process
> > > > will be duplicated, then the new copy will be
> given to the child process
> > > > control.
> > > > you can see that if a process has already
> opened 4 files there will be 7
> > > > files in the process file table (stdin,
> stdout, stderr, 4files then the
> > > > new
> > > > duplicated copy generated by fork will have
> the same entries in it's
> > > > file
> > > > table .. but from this moment and on .. each
> process (the parent and the
> > > > child) will work on it's own copy .. and after
> this point, if the parent
> > > > process opened a file nothing will be affected
> in the child process
> > > > descriptor, and vice verse
> > >
> > > This is not true, actually. They do share the
> struct file and since that
> > > is
> > > where the current position lives, the current
> position WILL be affected.
> > > That's why if parent and child both have a log
> file open (from before
> > > fork)
> > > and write to it, output from BOTH will be there,
> mixed together.
> >
> > this is right .. the struct file (which is part of
> the VFS structs for every
> > file system) will be shared .. but this is only
> -as i've pointed out- when
> > the file has been opened before calling fork .. i
> think i was clear that
> > what i meant is the file descriptor table which
> will be duplicated .. after
> > calling fork you cannot open a file from the
> parent task, then pass the new
> > file descriptor index to the child task some how
> and then let the child task
> > calls "read" from that file descriptor index cause
> it's not associated with
> > the new task's files descriptor table
>
> Sure. But you started with 'the process descriptor
> will be duplicated', which
> is not very clear. The 'process descriptor' is
> struct task_struct. Well, that
> will always be duplicated. The important point is
> that clone duplicates the
> *table* of file descriptors, not the file
> descriptors (struct file)
> themselves as the original poster seemed to think.
>
> > > > here you can find the difference between clone
> and fork .. when a process
> > > > clones a thread using clone then the new
> process descriptor (actually
> > > > it's
> > > > called "task" in Linux) will point it's
> resources like the file table to
> > > > the
> > > > parent process .. it won't copy it, it'll
> point to it instead .. and
> > > > this is
> > > > the reason why the process and the cloned task
> will still be able to
> > > > share
> > > > opened files (and any other cloned resource)
> till the end
> > >
> > > No. fork, though being a different syscall, is a
> strict subset of clone.
> > > sys_clone (_syscall2(int, clone, int, flags,
> void *, child_stack)) with
> > > flags
> > > of 0 and child stack of NULL does exactly fork.
> > >
> > > Note, that it is flags 0, *NOT* CLONE_SIGHAND.
> Again CLONE_SIGHAND does
> > > not
> > > mean the installed handlers remain the same --
> the *always* do -- but that
> > >
> > > the descriptor table is shared -- which after
> fork it is *NOT*.
> >
> >
> > when you ask "clone" not to clone anything it'll
> do as fork does (i.e. will
> > duplicate the task descriptor) but if you ask
> "clone" to clone resources A
> > and B for example it'll duplicate the task
> descriptor and then let resource
> > A and B from the child task point to resource A
> and B from the parent task
> > without allocating anything for them
>
> --
> Jan 'Bulb' Hudec
>



___________________________________________________________
Yahoo! Photos ? NEW, now offering a quality print service from just 8p a photo http://uk.photos.yahoo.com

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/

Hi Deepak,

With thanks to Jan Hudec and others who clarified my questions on this, I try to summarize my understanding for you. Big bies, pls correct me if I am wrong here.

First let me tell you about the terms used.

Open File object/ structure :

When a process opens a file present on disk, a corresponding file structure is created in the memory. This is of type "struct file" (include/linux/fs.h). This contains the details like the current read/write position in the file etc. Overall this represents a open file to the process.

File descriptor handler :

For accessing a open file ( described above ), the process needs a handler. This is a number and this is the return value you get when you open a file using open() call. Whenever you read/write to a file, you use this handler. This is also the index of that particular file object in the file descriptor table ( described below ).

File descriptor table :

Each process has a file descriptor table. It is an array which contains the pointers to the open file objects of that process. And the file descriptor handler ( described above ) is actually an array index in the table. And the element in that index is a pointer to that particular open file object.

So now let me come to your question.
When a process creates a thread, both the file objects and the file descriptor table are shared with the new thread. They are not duplicated.

When a process creates a child process, the open file objects ( created before fork ) are shared with the new process. They are not duplicated. So when the child writes something to a file opened before fork, parent can see the new changes in that file. Note the phrase "opened before fork".

It is the file descriptor table which is duplicated after fork(). It is not shared.  Since after duplication, the child also gets the same indices and pointers ( the same table as the parent ), when it accesses a open file, it actaully accesses the open file accessed by the parent. But after fork(), if the child opens a new file, that entry would be added to the file descriptor table of the child only ( since the child has its own copy of the table ). So the parent will not have access to this new open file object.

I hope you now got the concepts.

Thanks,
Rajaram.






















 


Yahoo! Shopping
Find Great Deals on Holiday Gifts at Yahoo! Shopping

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux