| Summary: | daemon(3) fails if called by a session leader | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | mkamm | ||||
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.2-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
State Changed From-To: open->closed Committed a fix, thanks. Please MFC this PR! |
The C library routine daemon(3) has a subtle bug: If the calling process is a session leader (i.e. pid == pgid) then a hangup signal will be delivered immediately to the created child process (daemon). The reason can be read in the _exit(2) manpage. I guess this bug is rarely triggered during normal operation but I can think of several scenarios were it will show up: - starting a daemon from /etc/passwd (as a login shell) - exec'ing a daemon from any login shell - exec'ing a daemon from a daemon - controlling a daemon with expect(1) from ports/lang/expect - giving a daemon as argument to script(1) Fix: There are several options here. I guess the most simple approach is ignoring SIGHUP until setsid(2) has been called. Of course, this doesn't fix daemons using fork && _exit instead of daemon(3). How-To-Repeat: ~/tmp$ cat daemontest.c #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> int main (void) { unlink("SUCCESS"); printf("I want to become a daemon\n"); if (daemon(1, 1)) perror("daemon"); open("SUCCESS", O_CREAT | O_TRUNC | O_WRONLY, 0666); printf("I'm a daemon now\n"); return (0); } ~/tmp$ make daemontest cc -Wall daemontest.c -o daemontest ~/tmp$ ./daemontest I want to become a daemon ~/tmp$ I'm a daemon now ~/tmp$ script -q logfile ./daemontest I want to become a daemon ~/tmp$ ls SUCCESS ls: SUCCESS: No such file or directory ~/tmp$ cat logfile I want to become a daemon ~/tmp$