On Mon, Aug 17, 2009 at 04:37:07PM -0700, Garrett D'Amore wrote: > >It's there in libc in RHEL5. > > If its there in RHEL5, then I'll withdraw my major concerns. I think > the documentation should point users to other, more robust ways of > dealing with daemon startup.
Yes, that's true, but here daemon() does help: the start method of a service whosea daemon that doesn't do any of what daemon() does and does not call it... needs to start the daemon like so: #!/bin/sh . /lib/svc/share/smf_include.sh /path/to/daemon & sleep $some_time # We don't know if it really did start. If it didn't we'll get # restarted until it does start or n-strikes-you're-done exit $SMF_EXIT_OK Whereas a daemon program that calls daemon() _after_ initializing can be started like this: #!/bin/sh . /lib/svc/share/smf_include.sh if ! /path/to/daemon then # handle errors and map to suitable SMF error ... fi exit $SMF_EXIT_OK In other words: daemon() is a Good Thing. The only things to document are: a) the need to do something like daemon(), b) make sure the parent exits _after_ initialization completes, c), if you need to drop privs after initialization, then do that too. Ideally we'd have something like: /* * Depending on flags daemon2() will fork(), setsid(), fork(), * chdir("/"), etcetera. In the child daemon2() will call * templace_callback(); if that returns non-zero, then daemon2() will * exit(2) with that error. In the grandchild daemon2() will call * init_callback(init_cb_data), and it that returns zero, then it will * call context_setup(context_setup_data), and the grandparent will * exit() with the first non-zero return value of those callbacks, else * it will exit(0). (Internally daemon2() uses an IPC mechanism by * which the grandchild communicates its status to the grandparent.) * * Any and all three of templace_callback, init_callback, and * context_setup may be NULL. * * Pre-defined templace and context setup callback functions: * * - daemon2_process_contract_template(...) * (put the grandchild in its own process contract as described by * template_cb_data.) * - daemon2_process_context_setup(...) * (initialize the ruid/suid/euid, rgid/sgid/egid, supplementary * groups, privileges.) * * Flags: DAEMON2_CHDIR, DAEMON2_SETSID, ... */ void daemon2( int flags, int (*templace_callback)(void *arg), void *template_cb_data, int (*init_callback)(void *arg), void *init_cb_data, int (*context_setup)(void *arg), void *context_setup_data ); Or something like that. > Last question: Is "Committed" the way to deal with this? If we want to > steer developers elsewhere, should we instead just list this interface > with "Committed Obsolete" or perhaps "Uncommitted". daemon() won't go away. Committed is fine, IMO. Nico --