Reputation: 401
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?
Upvotes: 28
Views: 11877
Reputation: 58534
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.)
Upvotes: 18
Reputation: 27233
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.
Upvotes: 49