I have a command line utility that spawns a daemon process which then becomes orphaned. How can I make the daemon exit along with the terminal emulator?
-
What exactly does "spawns a daemon process" mean? Is the process doing a complete disassociation from the parent, or ... ? – thrig Aug 15 '22 at 20:01
-
The cli utility forks itself and then execs the daemon. The cli utility then exits and the daemon ignores the SIGHUP signal. – Rillian Grant Aug 15 '22 at 20:34
3 Answers
Once a process becomes a daemon and ignores SIGHUP (or more likely, it has become its own session leader and is in its own process group and it is never even sent SIGHUP), the only way to terminate it when the terminal emulator closes is by recording its PID and sending a fatal signal:
# pid=$(</var/run/some-daemon.pid)
# trap "kill $pid" EXIT
This is assuming you're using bash or a compatible shell. The way you get the PID of the daemon may vary, but most daemons write their PIDs to a file. The real magic is the trap
command.
As thrig pointed out, this technique assumes the daemon writes a PID file and that you are exiting your shell normally (with exit
, ^D, etc.). This technique can be fragile, but it is simple.

- 2,655
A daemon may perform a double fork, or may not support a PID file, or may change its name randomly in the process listing. If the daemon does not do any of the prior, it could be tracked by the shell $!
variable, or maybe it has a file you can cat
and pray that the contents are correct (the PID will not be correct if the daemon crashes and something else takes that PID meanwhile), or maybe pkill(1)
can find and kill the process in a shell EXIT
trap. (The shell EXIT
trap may not fire if you exec some-other-program
and replace the shell with some other program, so be sure to remember not to do that.) Does this sound not very reliable? That is because it is not very reliable.
A daemon may have an option to run in the foreground, in which case you can launch it along the lines of your-daemon --with-the-foreground-flag &
, possibly redirecting any output from it as necessary, in which case the SIGHUP
should apply to it when the parent shell process goes away. (But maybe not if you exec
the shell to some other program.)
If you are on Linux, then one might put the terminal and daemon and whatever all else into a custom cgroup and murder that entire group when the session ends. systemd got in trouble for doing this to tmux
by default. This should be somewhat more reliable than a double-fork escaping from $!
or there being no PID file, or maybe an incorrect PID file, or to guess at the process name in the process listing. Also a cgroup will not care when the shell is exec
'd to be some different process.

- 34,938
The point of a process daemonizing itself is to not depend on its parent.
To depend on an arbitrary pid you can open a pidfd for it, see pidfd_open
, it's got example code though you may prefer epoll
to poll
.
So before daemonizing itself your utility can try to hunt down some process it wants to care about, maybe check if it was apparently started by a shell and depend on the shell's parent, otherwise maybe take a pid cmdline option. For me the grandparent would be my tmux server, not the terminal emulator; it's not clear what's going to be right, at a guess it's context-dependent and maybe pure preference.

- 2,710