xdaemon() (was Re: zcip: pidfile support?)
Rob Landley
rob at landley.net
Wed Sep 13 20:50:20 UTC 2006
On Wednesday 13 September 2006 3:56 am, Steven Scholz wrote:
> Hi all,
>
> how about pidfile support for the zcip applet?
> I need to keep track of running zcip daemons for different interfaces.
>
> And in general how about adding pidfile support for the xdaemon() function?
> Maybe generating a new function
>
> xdaemon_with_pidfile(int nochdir, int noclose, const char *pidfile);
I'm pondering how to support nommu with xdaemon() properly.
Back when Vladimir was block copying other projects' code into the tree he
added libbb/vfork_daemon_rexec.c on the assumption that every caller should
stick an #ifdef around their daemonize testing whether or not they had nommu.
(I like to think that the general taste and sanity level of the busybox
development community has gone up since he left.)
Now, in a sane world xdaemon() worries about whether or not we have an mmu,
and the callers are insulated from this. The problem is, daemonize wants to
fork() so we can detach from our controlling tty (and fork again so that when
the first fork exits, it gets reparented to init). On a nommu system we only
have vfork(), which freezes its parent until the child calls _exit() or
exec().
I _think_ that the double vfork() should still work: the first vfork waits
until the second vfork() finishes. The second one calls exec() and the first
one calls _exit(). However, in order to exec we have to know what program
we're running.
Now there are two places in busybox where we know what argv[] is from every
applet, and that's in applets/busybox.c and applets/applets.c. So if we hook
either busybox_main() or run_applet_by_name() to copy argc and argv to global
variables, we could then use those global variables in xdaemon() to re-exec
ourselves with some kind of "we're daemonized, don't do it again" flag that
could also be parsed and removed by busybox_main(). (Making this work for
scripts/individual is my problem, I'm learning how to declare weak symbols
for the linker to handle this sort of thing.)
Anyway, that should handle giving xdaemon() the info it needs to handle the
nommu case without extra setup on the part of its callers. (There is the
caveat that in the nommu case it'll restart the app, which we should document
but shouldn't cause a major problem.)
The other fallout is that it might be good to yank argc and argv from the
various applet_main() files if we go down this road (to save two arguments,
just use the globals; optind is already global anyway) and on top of that,
bb_getopt_ulflags() could lose its first two arguments and just use the
globals as well, so that's extra savings. But when I started looking into
it, I looked closely at bb_getopt_ulflags() (more of Vladimir's code) and
went "ew, needs a rewrite, and it's now such a thick wrapper around getopt()
that it's probably smaller not to use getopt() at all anymore and just parse
it ourselves without modifying argv[]).
Which raises the possibility of allocating a new argv[] and moving the global
pointer to point to the new one, so we don't modify the part of our
environment that "ps" looks at...
Anyway... Todo item. :)
Rob
--
Never bet against the cheap plastic solution.
More information about the busybox
mailing list