man 7 daemon
When a traditional SysV daemon starts, it should execute the following steps as part of the initialization. Note that these steps are unnecessary for new-style daemons (see below), and should only be implemented if compatibility with SysV is essential.
[...]
6. In the child, call setsid() to detach from any terminal and create an independent session.
7. In the child, call fork() again, to ensure that the daemon can never re-acquire a terminal again.
but compare this to processes started with no vestige of SysV compatibility:
$ ps -efj
UID PID PPID PGID SID C STIME TTY TIME CMD
root 1 0 1 1 0 May10 ? 00:06:44 /sbin/init
...
root 185 1 185 185 0 May10 ? 00:09:48 /lib/systemd/systemd-journald
root 16434 1 16434 16434 0 May26 ? 00:00:11 /usr/sbin/rsyslogd -n
The processes for both rsyslog.service
and systemd-journal.service
are session leaders (SID = PID).
It seems that if such programs were configured to log to a TTY, they would gain the TTY as a controlling terminal, and receive an unwanted / fatal signal when the TTY is hung up / receives Ctrl+C, respectively. Unless they remember to set O_NOCTTY when opening the TTY file.
It seems this is a little pitfall when writing or converting a program to run as a systemd service w/o any SysV compatibility, if your program supports writing messages to custom files. It does not seem to be pointed out by this doc which advocates the systemd style. The doc rather implies the opposite, by insisting that double-fork is necessary to avoid this on SysV, and then not mentioning this as an issue when describing the steps a native systemd service would use.
Is that correct? Does systemd provide some protection against this I have overlooked, or is the issue pointed out elsewhere in the systemd doc?