Like an orange
Everything here is my opinion. I do not speak for your employer.
September 2007
October 2007

2007-09-17 »

Because otherwise you won't know when it's done starting

I was just searching for something else and ran into a discussion in wlach's blog from awhile ago. I replied to it at the time but it's worth reposting here, since I think it's useful information.

The question was, basically: why do daemons fork themselves into the background, anyway? It's so easy in Unix to do it yourself (by adding an & sign after the command) but very hard to force a self-backgrounding program into the foreground.

pmccurdy responded by linking to an article that may or may not have been written by djb (of qmail/djbdns fame) saying that self-backgrounding daemons are wrong, and explaining why. It's a good article.

But it doesn't actually answer the question. The real question is: why would incredibly smart people, like the original designers of Unix, have made daemons fork automatically into the background when it's so annoying and besides, they also invented inittab and inetd which do the right thing?

The answer is that when you background a subprocess yourself, you don't know when it's "done starting." For example, if I'm starting syslogd, I don't actually want to move on to the next program (which might require syslogd's socket to be listening because it sends log messages) until syslogd is actually ready to receive connections, which is later than when it's simply been forked off. If you background the process yourself, there's no way for you to know... except polling for the socket, which is gross.

So the original Unix designers actually did a really clever thing: they had the daemon fork() itself after binding the socket, so when syslogd goes into the background, you know it's ready to receive connections.

Incidentally, this is intimately related to a question that was asked around the same time on wvstreams-devel about wvfork()'s "strange" delays in the parent process. Unlike fork(), the wvfork() in WvStreams can suspend the parent process until the child has finished setting itself up - for example, listening on some sockets or closing other ones. With wvfork(), the parent does the backgrounding (as it should be) but the child can still notify the parent that it's ready (as it should be), so you get the best of both worlds... except you have to use the non-standard wvfork().

Someone also mentioned that KDE programs auto-background themselves on startup, which seems ridiculous since they're not even daemons. That's considerably more crazy, but it was also done for a good reason. The reason, as I understand it, is that to improve shared memory usage and speed (ie. data structure initialization, not .so files themselves) they actually ask the 'kdeinit' program to fork itself and load and run the library corresponding to their program. After that happens, the program you ran isn't actually doing anything, so it quits. But if kdeinit isn't running on your system, the program (a bit confusingly) doesn't fork into the background because it doesn't need to. Try it and see!

I'm CEO at Tailscale, where we make network problems disappear.

Why would you follow me on twitter? Use RSS.

apenwarr on gmail.com