Bug 25462

Summary: daemon(3) fails if called by a session leader
Product: Base System Reporter: mkamm
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.2-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description mkamm 2001-02-28 21:50:01 UTC
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$
Comment 1 Guy Helmer freebsd_committer freebsd_triage 2003-11-10 22:11:53 UTC
State Changed
From-To: open->closed

Committed a fix, thanks.
Comment 2 Martin Kammerhofer 2004-07-21 08:41:08 UTC
Please MFC this PR!