[OPEN-ILS-DEV] PATCH: utils.c (daemonizing)

Scott McKellar mck9 at swbell.net
Fri Jun 29 22:29:41 EDT 2007


Here's the promised patch for the daemonize function.  This will be
a long post because it is a matter of some delicacy, and I want to 
show a rationale for everything.

1. As long as I was in the neighborhood, I replaced the error messages
going to stderr with messages going to the logging machinery.

2. I altered the comment just above daemonize(), because the original
was inaccurate.  This function does not change the process title.

3. Pedantic point: I captured the return value of fork() with a pid_t
instead of an int.

4. After the fork, the parent process terminates with _exit()
instead of exit().  That way it doesn't flush any buffers or close
any files.  It also doesn't call any functions registered with 
atexit().  In fact it doesn't do much of anything except get out of
the way and let the child process take its place in every way.

5. The child process switches to the root directory, calls setsid()
to create a new session, and freopens the three standard streams
to /dev/null.

I could have changed directories before the fork, or at any of
several other places.  I don't think it makes any difference.

I could also have done the freopens before the fork, but if the
fork failed, I might not have a way to report it (if the logging is
going to stderr for some reason).

Note that I'm not flushing any buffers, apart from the three standard
streams.  There's no need to.  The child process inherits the file
descriptors intact and can do with them whatever it likes.  The
parent may have died, but the estate doesn't have to go through
probate.

I didn't add any error checking for chdir(), setsid(), or freopen().
The first two are unlikely to fail, as is the freopen of stdin.  The
freopens of stderr and stdout could fail, if for example they are
redirected to a full disk.  I don't know how paranoid we need to be.

Testing:

I used a butchered version of ChopChop as a test driver.  Here's the
relevant fragment of test code:

	FILE * extra = fopen( "extra.txt", "w" );
	if( extra )
		fprintf( extra, "This is extra\n" );
	else
		fprintf( stderr, "Can't open extra.txt\n" );
	
	fprintf( stderr, "before daemonizing\n" );
	daemonize();
	fprintf( stderr, "after daemonizing\n" );
	sleep( 30 );
	fclose( extra );
	//osrfChatServerWait( server );

I opened a file and wrote to it before daemonizing, but I didn't
close the file until afterwards.  The 30 second sleep gave me time
to verify that I could see ChopChop via ps, as a child of process 1.
I could also verify that the output file was present but empty,
because the buffer was still unflushed.

After 30 seconds, ChopChop was gone from the ps output, and the
output file contained the expected text.  That showed that the
buffer was flushed exactly once, as intended.

I wrote messages to stderr immediately before and immediately after
daemonizing.  Only the first one showed up, as intended.

I commented out the call to osrfChatServerWait() because it was
irrelevant for present purposes.

I have not tried to verify that syslogging still works after
daemonizing, but I can't imagine why it wouldn't.  It's just another
file descriptor.

Scott McKellar
http://home.swbell.net/mck9/ct/

Developer's Certificate of Origin 1.1 By making a contribution to
this project, I certify that:

(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license indicated
in the file; or

(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source license
and I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
same open source license (unless I am permitted to submit under a
different license), as indicated in the file; or

(c) The contribution was provided directly to me by some other person
who certified (a), (b) or (c) and I have not modified it; and

(d) In the case of each of (a), (b), or (c), I understand and agree
that this project and the contribution are public and that a record
of the contribution (including all personal information I submit
with it, including my sign-off) is maintained indefinitely and may
be redistributed consistent with this project or the open source
license indicated in the file.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: utils_c_4.patch
Type: text/x-patch
Size: 2763 bytes
Desc: 204565846-utils_c_4.patch
Url : http://list.georgialibraries.org/pipermail/open-ils-dev/attachments/20070629/b92c1b26/utils_c_4.bin


More information about the Open-ils-dev mailing list