2024-10-05
Daemonization in Unix programs is probably about restarting programs
It's standard for Unix daemon programs to 'daemonize' themselves when they start, completely detaching from how they were run; this behavior is quite old and these days it's somewhat controversial and sometimes considered undesirable. At this point you might ask why programs even daemonize themselves in the first place, and while I don't know for sure, I do have an opinion. My belief is that daemonization is because of restarting daemon programs, not starting them at boot.
During system boot, programs don't need to daemonize in order to
start properly. The general Unix boot time environment has long
been able to detach programs into the background (although the
V7 /etc/rc
didn't bother to do this with /etc/update
and /etc/cron
, the
4.2BSD /etc/rc
did do this for the new BSD network daemons). In general, programs
started at boot time don't need to worry that they will be inheriting
things like stray file descriptors or a controlling terminal. It's
the job of the overall boot time environment to insure that they
start in a clean environment, and if there's a problem there you
should fix it centrally, not make it every program's job to deal
with the failure of your init
and boot sequence.
However, init is not a service manager (not historically), which meant that for a long time, starting or restarting daemons after boot was entirely in your hands with no assistance from the system. Even if you remembered to restart a program as 'daemon &' so that it was backgrounded, the newly started program could inherit all sorts of things from your login session. It might have some random current directory, it might have stray file descriptors that were inherited from your shell or login environment, its standard input, output, and error would be connected to your terminal, and it would have a controlling terminal, leaving it exposed to various bad things happening to it when, for example, you logged out (which often would deliver a SIGHUP to it).
This is the sort of thing that even very old daemonization code deals with, which is to say that it fixes.
The 4.2BSD daemonization code closes (stray) file descriptors and
removes any controlling terminal the process may have, in addition
to detaching itself from your shell (in case you forgot or didn't
use the '&' when starting it). It's also easy to see how people
writing Unix daemons might drift into adding this sort of code to
them as people restarted the daemons (by hand) and ran into the
various problems (cf).
In fact the 4.2BSD code for it is conditional on 'DEBUG
' not being
defined; presumably if you were debugging, say, rlogind, you'd build
a version that didn't detach itself on you so you could easily run
it under a debugger or whatever.
It's a bit of a pity that 4.2 BSD and its successors didn't create a general 'daemonize' program that did all of this for you and then told people to restart daemons with 'daemonize <program>' instead of '<program>'. But we got the Unix that we have, not the Unix that we'd like to have, and Unixes did eventually grow various forms of service management that tried to encapsulate all of the things required to restart daemons in one place.
(Even then, I'm not sure that old System V init systems would properly daemonize something that you restarted through '/etc/init.d/<whatever> restart', or if it was up to the program to do things like close extra file descriptors and get rid of any controlling terminal.)
PS: Much later, people did write tools for this, such as daemonize. It's surprisingly handy to have such a program lying around for when you want or need it.