Date: Tue, 16 Mar 2010 03:07:05 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Bruce Evans <brde@optusnet.com.au> Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Poul-Henning Kamp <phk@FreeBSD.org> Subject: Re: svn commit: r205165 - head/lib/libc/gen Message-ID: <20100316024446.A24853@delplex.bde.org> In-Reply-To: <20100316021240.N24765@delplex.bde.org> References: <201003150858.o2F8wZid011308@svn.freebsd.org> <20100316021240.N24765@delplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 16 Mar 2010, Bruce Evans wrote: > ... > The unobvious points are: > - why avoid triggering atexit(), etc. processing in daemon()? > - why isn't this documented? Some callers of daemon() need to know that > it won't flush open streams, etc., so that they can flush and their > open streams, etc., before calling daemon(). Callers should do this > anyway before calling any function that can exit (especially exit() > itself), so that they can actually check that the output went out, > but most are sloppy. Callers should know if they have any open > streams but they would have a hard time telling what else they are > missing from not calling exit(). There may be profiling cleanup > (profiling won't work right for the child?) and other magic destructors. Due to the way that daemon() works, it is really an error to have any open streams when it is called. This is also undocumented, except implicitly. The errors are: - unflushed output on stdout and stderr won't get flushed normally by the child. stdout and stderr are redirected so it will go there if the child erroneously (?) uses these streams or simply calls exit() which will give the default flush. - unflushed input in stdin may cause problems, since although stdin is redirected, the input may be in stdio's buffers. - it is unclear if stdio can do something better than crash when its fd's for stdinout/err are redirected without telling it. - fd's above 2 are not touched, so the child inherits any open streams on these fd's. These streams are likely to get flushed on exit() if not explicitly. I think daeomon() should be doing an fflush(NULL) or fcloseall() and most other cleanups done by atexit processing. Before the fork() of course, so that the child doesn't inherit stuff. fcloseall() would be too destructive if the fork() fails, but fflush(NULL) is almost as clean. At least the fflush(NULL) is safe since it has no effect except for buggy callers that have unflushed streams. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100316024446.A24853>