27

When i tried to write a daemon under linux using C, i was told i should add following code after fork code block:

/* Preparations */
...

/* Fork a new process */
pid_t cpid = fork();
if (cpid == -1){perror("fork");exit(1);}
if (cpid > 0){exit(0);}

/* WHY detach from tty ? */
int fd = open("/dev/tty", O_RDWR);
ioctl(fd, TIOCNOTTY, NULL);

/* Why set PGID as current PID ? */
setpgid(getpid(), 0);

My question is: Is there a must to do the above operations?

4
  • I think part of the reason is that a daemon is not expected to write output or read input. If you were to start, e.g. an HTTP server on an SSH session, you wouldn't expect random warning output later on in the session. Commented Jan 8, 2012 at 12:48
  • 1
    @JohnChadwick What you're saying is indeed one of the things you want to do while transforming into a daemon, but you achieve this by closing stdin, stdout and stderr. You detach from the terminal to avoid certain signals (see answers below). Commented Jan 8, 2012 at 13:01
  • 1
    Can you "unaccept" my answer and accept @AdamZalcman's instead? He does a much better job than me. And he is fully right about setsid(), you should use that.
    – fge
    Commented Jan 8, 2012 at 13:05
  • @AdamZalcman Oh, right, I actually forgot about closing std*. I was thinking changing the process group ID prevented all of the relevant signals, but that would make a lot less sense, at least in the case of SIGHUP. Commented Jan 8, 2012 at 13:06

2 Answers 2

48

You must disassociate your daemon process from the terminal to avoid being sent signals related to terminal's operation (like SIGHUP when the terminal session ends as well as potentially SIGTTIN and SIGTTOU).

Note however that the way of disassociating from the terminal using TIOCNOTTY ioctl is largely obsolete. You should use setsid() instead.

The reason for a daemon to leave its original process group is not to receive signals sent to that group. Note that setsid() also places your process in its own process group.

2
  • +1. Caveat: even after setsid(2) it may be possible to acquire a controlling terminal if one is not careful (fork() again or O_NOCTTY).
    – pilcrow
    Commented Jan 8, 2012 at 16:34
  • Can yourlaborate on this? Why the background process can’t just ignore those signals? Commented Jan 31, 2019 at 0:46
18

The other answer is clear and technically correct (and so I upvoted accordingly).

Another answer is: "No, don't write code that daemonizes itself."

Instead use a process supervision framework (like daemontools or runit or launchd) that takes care of this for you.

The traditional UNIX server is self-daemonizing, and as such fusses over many things: current working directory, process group and session independence, signal masks and disposition, filesystem root, privileges, umask, open file descriptors, etc.

However, most or all of these process attributes are inherited across an exec(), meaning that a server process can typically be "born" with the desired process group, working directory, root, etc. There is little need to do everything yourself, though you'll often still have to manage privileged operations and privilege revocation yourself.

(Indeed, I'd argue there's long-term risk in writing self-daemonizing programs. Boilerplate "backgrounding" routines get copied and pasted and hastily ported and extended, and the programmer spends time on ancillary code rather than on the program's main purpose.)

1
  • Great answer! Daemonizing should be the choice of the caller, not forced by the application itself. And for the caller, there are plenty of existing tools, no need to re-invent it in the application.
    – Erki Aring
    Commented Feb 16, 2017 at 10:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.