208

I'm trying to create a daemon in python. I've found the following question, which has some good resources in it which I am currently following, but I'm curious as to why a double fork is necessary. I've scratched around google and found plenty of resources declaring that one is necessary, but not why.

Some mention that it is to prevent the daemon from acquiring a controlling terminal. How would it do this without the second fork? What are the repercussions?

user3840170
  • 26,597
  • 4
  • 30
  • 62
Shabbyrobe
  • 12,298
  • 15
  • 60
  • 87
  • 1
    http://stackoverflow.com/questions/10932592/why-fork-twice/16655124#16655124 – nj-ath Feb 16 '15 at 09:00
  • 4
    One difficulty with doing a double fork is that the parent can't easily get the PID of the grandchild process (the `fork()` call returns the child's PID to the parent, so it's easy to get the PID of the child process, but not so easy to get the PID of the _grandchild_ process). – Craig McQueen Jan 13 '16 at 05:18

9 Answers9

202

I was trying to understand the double fork and stumbled upon this question here. After a lot of research this is what I figured out. Hopefully it will help clarify things better for anyone who has the same question.

In Unix every process belongs to a group which in turn belongs to a session. Here is the hierarchy…

Session (SID) → Process Group (PGID) → Process (PID)

The first process in the process group becomes the process group leader and the first process in the session becomes the session leader. Every session can have one TTY associated with it. Only a session leader can take control of a TTY. For a process to be truly daemonized (ran in the background) we should ensure that the session leader is killed so that there is no possibility of the session ever taking control of the TTY.

I ran Sander Marechal's python example daemon program from this site on my Ubuntu. Here are the results with my comments.

1. `Parent`    = PID: 28084, PGID: 28084, SID: 28046
2. `Fork#1`    = PID: 28085, PGID: 28084, SID: 28046
3. `Decouple#1`= PID: 28085, PGID: 28085, SID: 28085
4. `Fork#2`    = PID: 28086, PGID: 28085, SID: 28085

Note that the process is the session leader after Decouple#1, because it's PID = SID. It could still take control of a TTY.

Note that Fork#2 is no longer the session leader PID != SID. This process can never take control of a TTY. Truly daemonized.

I personally find terminology fork-twice to be confusing. A better idiom might be fork-decouple-fork.

Additional links of interest:

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Praveen Gollakota
  • 37,112
  • 11
  • 62
  • 61
  • 3
    Forking twice also prevents creating zombies when parent process runs for longer time and for some reason removing default handler for signal informing that process died. – Trismegistos Mar 28 '14 at 18:28
  • But second for can also call decouple and become session leader and then acquire terminal. – Trismegistos Apr 06 '14 at 20:52
  • 3
    This is not true. The first `fork()` already prevents creating zombies, provided you close the parent. – parasietje Jan 12 '15 at 10:52
  • 1
    A minimal example to produce the above quoted results: https://gist.github.com/cannium/7aa58f13c834920bb32c – can. Jul 06 '15 at 02:02
  • 2
    Would it be any good to call `setsid()` _before_ a single `fork()`? Actually I guess the answers of [this question](http://stackoverflow.com/q/2613104/60075) answer that. – Craig McQueen Jan 13 '16 at 05:44
  • For anyone like me wondering what TTY is: [this blog post](https://itsfoss.com/what-is-tty-in-linux/) is a good one to study. – therealak12 Jan 02 '22 at 19:33
154

Strictly speaking, the double-fork has nothing to do with re-parenting the daemon as a child of init. All that is necessary to re-parent the child is that the parent must exit. This can be done with only a single fork. Also, doing a double-fork by itself doesn't re-parent the daemon process to init; the daemon's parent must exit. In other words, the parent always exits when forking a proper daemon so that the daemon process is re-parented to init.

So why the double fork? POSIX.1-2008 Section 11.1.3, "The Controlling Terminal", has the answer (emphasis added):

The controlling terminal for a session is allocated by the session leader in an implementation-defined manner. If a session leader has no controlling terminal, and opens a terminal device file that is not already associated with a session without using the O_NOCTTY option (see open()), it is implementation-defined whether the terminal becomes the controlling terminal of the session leader. If a process which is not a session leader opens a terminal file, or the O_NOCTTY option is used on open(), then that terminal shall not become the controlling terminal of the calling process.

This tells us that if a daemon process does something like this ...

int fd = open("/dev/console", O_RDWR);

... then the daemon process might acquire /dev/console as its controlling terminal, depending on whether the daemon process is a session leader, and depending on the system implementation. The program can guarantee that the above call will not acquire a controlling terminal if the program first ensures that it is not a session leader.

Normally, when launching a daemon, setsid is called (from the child process after calling fork) to dissociate the daemon from its controlling terminal. However, calling setsid also means that the calling process will be the session leader of the new session, which leaves open the possibility that the daemon could reacquire a controlling terminal. The double-fork technique ensures that the daemon process is not the session leader, which then guarantees that a call to open, as in the example above, will not result in the daemon process reacquiring a controlling terminal.

The double-fork technique is a bit paranoid. It may not be necessary if you know that the daemon will never open a terminal device file. Also, on some systems it may not be necessary even if the daemon does open a terminal device file, since that behavior is implementation-defined. However, one thing that is not implementation-defined is that only a session leader can allocate the controlling terminal. If a process isn't a session leader, it can't allocate a controlling terminal. Therefore, if you want to be paranoid and be certain that the daemon process cannot inadvertently acquire a controlling terminal, regardless of any implementation-defined specifics, then the double-fork technique is essential.

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Dan Moulding
  • 211,373
  • 23
  • 97
  • 98
  • 4
    +1 Too bad this answer came ~four years after the question was asked. – Tim Seguine Sep 27 '13 at 11:09
  • 21
    But that still doesn't explain why it's so terribly important that a daemon can't reacquire a controlling terminal – UloPe Oct 23 '13 at 13:59
  • 12
    The keyword is "inadvertently" acquire a controlling terminal. If the process happens to open a terminal, and it becomes the processes controlling terminal, than if somebody issues a ^C from that terminal it could terminate the process. So it might be nice to protect a process from having that happen to it inadvertently. Personally I'll stick to a single fork and setsid() for code I write that I know won't be opening terminals. – BobDoolittle Aug 01 '14 at 17:29
  • @BobDoolittle: One thing to note, however, is that opening a terminal device file is but one way that a process could reacquire a controlling terminal. "*The controlling terminal for a session is allocated by the session leader in an implementation-defined manner.*" That means implementations could provide other ways that a session leader can acquire a controlling terminal. I'm not always paranoid, but when I am, I daemonize my processes carefully :) – Dan Moulding Nov 19 '14 at 19:29
  • 1
    @BobDoolittle how could this happen "inadvertently"? A process won't just willy nilly end up opening terminals if it's not written to do so. Maybe double-forking is useful if you the programmer don't know the code and don't know if it might open a tty. – Marius Aug 06 '15 at 22:27
  • 17
    @Marius Imagine what might happen if you add a line like this to your daemon's configuration file: `LogFile=/dev/console`. Programs don't always have compile-time control over which files they might open ;) – Dan Moulding Aug 07 '15 at 20:45
  • @Marius yes you always need to vet your inputs. If you have a config file that controls what you are opening, this can be significant. This is a case of you the programmer not knowing what it might open. But if the files you open are not specified via user/admin input, this is just sloppy programming. It reminds me of the days people used to type "sync" twice before shutting down a system. In fact the only purpose the second sync served was a delay so the first async flush to disk could have time to complete. – BobDoolittle Aug 13 '15 at 23:33
  • 1
    FWIW, you're right double-fork isn't needed to reparent to init when demonizing, but that part *is* needed when a demon wants to fork and reparent a child and keep running: http://stackoverflow.com/q/10932592/53974 (of course, in that scenario you can avoid reparenting and do your own reaping but it can be complicated). – Blaisorblade Oct 18 '16 at 16:41
123

Looking at the code referenced in the question, the justification is:

Fork a second child and exit immediately to prevent zombies. This causes the second child process to be orphaned, making the init process responsible for its cleanup. And, since the first child is a session leader without a controlling terminal, it's possible for it to acquire one by opening a terminal in the future (System V- based systems). This second fork guarantees that the child is no longer a session leader, preventing the daemon from ever acquiring a controlling terminal.

So it is to ensure that the daemon is re-parented onto init (just in case the process kicking off the daemon is long lived), and removes any chance of the daemon reacquiring a controlling tty. So if neither of these cases apply, then one fork should be sufficient. "Unix Network Programming - Stevens" has a good section on this.

Beano
  • 7,551
  • 3
  • 24
  • 27
  • 34
    This is not entirely correct. The standard way to create a daemon is to simply do `p=fork(); if(p) exit(); setsid()`. In this case, the parent also exits and the first child process is reparented. The double-fork magic is *only* required to prevent the daemon from acquiring a tty. – parasietje Jan 12 '15 at 10:49
  • 1
    So, as I understand it, if my program starts and `forks` a `child` process, this very first child process will be a `session leader` and will be able to open a TTY terminal. But if I fork again from this child and terminate this first child, the second forked child won't be a `session leader` and won't be able to open a TTY terminal. Is this statement correct? – tonix Jun 18 '16 at 15:49
  • 5
    @tonix: simply forking does not create a session leader. That is done by `setsid()`. So, the first forked process becomes a session leader after calling `setsid()` and then we fork again so that the final, double-forked process is no longer a session leader. Other than the requirement of `setsid()` to be a session leader, you are spot on. – dbmikus May 23 '17 at 16:12
  • 1
    @parasietje Is there anyway to prevent the daemon from acquiring a tty without forking twice? Why would double forking prevent it from acquiring one if a single fork doesn't? – Melab Mar 29 '21 at 18:07
  • The session leader is a controlling process connecting to the tty. If you want to prevent a process from acquiring a tty, the process shouldn't be the session leader. So, i think the only way to do that is through double-forking. – rosshjb Apr 16 '21 at 12:32
11

Taken from Bad CTK:

"On some flavors of Unix, you are forced to do a double-fork on startup, in order to go into daemon mode. This is because single forking isn’t guaranteed to detach from the controlling terminal."

Stefan Thyberg
  • 3,445
  • 3
  • 23
  • 29
  • 3
    How can single fork not detach from the controlling terminal but double fork do so? What unixes does this occur on? – bdonlan May 19 '09 at 07:34
  • 13
    A daemon must close it's input and output file descriptors (fds), otherwise, it would be still attached to the terminal it was started in. A forked process inherits those from the parent. Apparently, the first child closes the fds but that doesn't clean up everything. On the second fork, the fds don't exist, so the second child can't be connected to anything anymore. – Aaron Digulla May 19 '09 at 07:41
  • 5
    @Aaron: No, a daemon properly "detaches" itself from its controlling terminal by calling `setsid` after an initial fork. It then ensures that it **stays** detached from a controlling terminal by forking again and having the session leader (the process that called `setsid`) exit. – Dan Moulding May 01 '13 at 12:42
  • 2
    @bdonlan: It's not `fork` that detaches from the controlling terminal. It's `setsid` that does it. But `setsid` will fail if it is called from a process group leader. So an initial `fork` must be done before `setsid` to ensure that `setsid` is called from a process that is not a process group leader. The second `fork` ensures that the final process (the one that will be the daemon) is not a session leader. Only session leaders can acquire a controlling terminal, so this second fork guarantees that the daemon won't inadvertently reacquire a controlling terminal. This is true of any POSIX OS. – Dan Moulding May 01 '13 at 12:49
  • @DanMoulding This does not guarante that second child won't acquire controlling terminal because it can call setsid and become session leader and then acquire control terminal. – Trismegistos Apr 06 '14 at 20:57
  • This answer is poor, but ends up being good because of the comment from @bdonlan – peabody Jul 23 '14 at 00:27
7

According to "Advanced Programming in the Unix Environment", by Stephens and Rago, the second fork is more a recommendation, and it is done to guarantee that the daemon does not acquire a controlling terminal on System V-based systems.

Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
3

It might be easier to understand in this way:

  • The first fork and setsid will create a new session (but the process ID == session ID).
  • The second fork makes sure the process ID != session ID.
pandy.song
  • 41
  • 1
3

One reason is that the parent process can immediately wait_pid() for the child, and then forget about it. When then grand-child dies, it's parent is init, and it will wait() for it - and taking it out of the zombie state.

The result is that the parent process doesn't need to be aware of the forked children, and it also makes it possible to fork long running processes from libs etc.

KarlP
  • 5,149
  • 2
  • 28
  • 41
2

The daemon() call has the parent call _exit() if it succeeds. The original motivation may have been to allow the parent to do some extra work while the child is daemonizing.

It may also be based on a mistaken belief that it's necessary in order to ensure the daemon has no parent process and is reparented to init - but this will happen anyway once the parent dies in the single fork case.

So I suppose it all just boils down to tradition in the end - a single fork is sufficient as long as the parent dies in short order anyway.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
2

A decent discussion of it appear to be at http://www.developerweb.net/forum/showthread.php?t=3025

Quoting mlampkin from there:

...think of the setsid( ) call as the "new" way to do thing (disassociate from the terminal) and the [second] fork( ) call after it as redundancy to deal with the SVr4...

Stobor
  • 44,246
  • 6
  • 66
  • 69