Why fork() twice while daemonizing? [duplicate]

2019-03-22 02:20发布

This question already has an answer here:

I'm wodering why people are calling fork() twice and why the 1st call is performed before setsid().

Yes, no new session is created if the caller is already a process group leader. But what if I just don't make the (grand)parent a process group leader? Who would make it for me (without asking me)? (OK, maybe 1llum1n4t1, Sc13nt0l0gy, the NSA, ... ;) )

Yes, the 1st child should exit immediately not to create a zombie process. But couldn't the (grand)parent just exit after forking? Or would one or two fprintf(stderr,... or write(2,... calls (like "successfully started daemon xy") be such a big deal? (And couldn't I prevent zombies another way?)

All in all, is this double-fork()-"magic" really required (not to get trouble)? Or is it just tradition or so-called "best practise" (like the avoiding of goto)? Or does it just guarantee the daemon to work on "historical" (of course I mean "far too old for usage in production environments") platforms like SVr4, BSD 3, RHEL 2 or some crappy, 32-bit embedded ones?

1条回答
混吃等死
2楼-- · 2019-03-22 02:53

The first call to fork(2) ensures that the process is not a group leader, so that it is possible for that process to create a new session and become a session leader. There are other reasons for the first fork(2): if the daemon was started as a shell command, having the process fork and the parent exit makes the shell go back to its prompt and wait for more commands.

The second fork(2) is there to ensure that the new process is not a session leader, so it won't be able to (accidentally) allocate a controlling terminal, since daemons are not supposed to ever have a controlling terminal. About the 2nd fork, here's a quote from Advanced Programming in the UNIX Environment, Chapter 13 (Daemon Processes):

Under System V-based systems, some people recommend calling fork again at this point, terminating the parent, and continuing the daemon in the child. This guarantees that the daemon is not a session leader, which prevents it from acquiring a controlling terminal under the System V rules. Alternatively, to avoid acquiring a controlling terminal, be sure to specify O_NOCTTY whenever opening a terminal device.

Section 13.3 of that book describes a lot more rules and patterns that are used when daemonizing a process, it is well worth the time to read it, if you can.

查看更多
登录 后发表回答