views:

307

answers:

2

Why fork() before setsid() to daemonize a process ?

Basically, if I want to detach a process from its controlling terminal and make it a process group leader : I use setsid().

Doing this without forking before doesn't work.

Why ?

Thanks :)

+4  A: 

It is required to fork() and have the child call setsid() to ensure that the process calling setsid() isn't already a process group leader (setsid() wants to make the calling process the process group leader of a new process group, so it fails in that case).

caf
+4  A: 

First of all: setsid() will make your process a process group leader, but it will also make you the leader of a new session. If you are just interested in getting your own process group, then use setpgid(0,0).

Now for understanding the actual reason why setsid() returns EPERM if you already are process group leader or session leader you have to understand that process group and session ids are initialized from the process id of the process creating them (and hence leading them, i.e. for a session leader pid == sid and for a process group leader pid == pgid). Also process groups cannot move between sessions.

That means if you are a process group leader, and creating a new session would be allowed then the sid and the pgid would get set to your pid, leaving the other processes in your old process group in a weird state: their process group leader suddenly is in a different session then they themselves might be. And that cannot be allowed, hence the EPERM by the kernel.

Now if you fork() once you are neither session nor process group leader anymore and hence setting your sid and pgid to your pid is safe, because there are no other processes in such group.

So, yepp, think about it, it all makes sense.