[comp.unix.questions] _cleanup

martin@mwtech.UUCP (Martin Weitzel) (06/02/90)

In article <845:May2718:47:2590@stealth.acf.nyu.edu> brnstnd@stealth.acf.nyu.edu (Dan Bernstein) writes:
[dd ...]
>Using fflush() before a fork() is never wrong in practice; it's the only
>way to guarantee that the child can safely use stdio; and the possible
>efficiency hit is miniscule compared to the fork() time. While there may
>be a few exceptions, novices should learn fflush()-fork() rather than a
>fork()-_exit() that will ``mysteriously'' lose output.

One remark to that: Requiring (or teaching novices) to fflush() all
output streams before a fork() tends to clutter up the source
with unnecessary global variables or introduce many additional
parameters: If the program is halfway structured chances are big
that the respective FILE-pointers are not normally visible at the
point were the program fork()s.

It would be quite helpful if stdio had officially defined some
"fflush_all()" operation - which is necessary anyway, because its
implicitly called by exit(). For as much as I know the usual name
of this routine is "_cleanup()", but using it - of course - is not
recommendable for portable programs.

BTW: I would not be surprised if someone finds it a useful idea
to make fork() call _cleanup() implicitly some day, because he was
burned by accidentially duplicated output. Though I would not like to
see this, there have allready been worse things in this area, eg.
fiddling with PATH and UID's within execv(), which has broken some clean
and useful code in the attempt to provide a general fix for sloppily
designed programs.
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83

gwyn@smoke.BRL.MIL (Doug Gwyn) (06/04/90)

In article <775@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
>It would be quite helpful if stdio had officially defined some
>"fflush_all()" operation ...

I don't know what an "official stdio" might be, if not ANS X3.159-1989,
which does specify that fflush(NULL) will have the effect you ask for.
Don't try this in nonconforming implementations, though.

chris@mimsy.umd.edu (Chris Torek) (06/10/90)

In article <775@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
>It would be quite helpful if stdio had officially defined some
>"fflush_all()" operation ...

As of ANSI C, it does: fflush((FILE *)NULL) does the trick.

>- which is necessary anyway, because its implicitly called by exit().
>For as much as I know the usual name of this routine is "_cleanup()",
>but using it - of course - is not recommendable for portable programs.

Indeed.  In particular, in many implementations _cleanup() *closes*
every stdio stream.  The result is that stdin, stdout, and stderr are
gone.

fflush((FILE *)NULL) is the only semi-portable solution.  If you need
something like this, you are probably best off including a separate C
file with a function `flushall' that reads:

	#include <stdio.h>

	flushall()
	{
	#ifdef FFLUSH_NULL	/* use ANSI standard method */
		(void) fflush((FILE *)NULL);
	#else
	#ifdef _NFILE	/* probably a SysV or V7 or 4.1BSD system */
		register FILE *fp;
		for (fp = &_iob[0]; fp < &_iob[_NFILE]; fp++)
			if (fp->_flag)
				(void) fflush(fp);
	#else		/* probably a 4.2BSD system or derivative */
		extern int fflush();	/* might not be in <stdio.h> */
		extern int _fwalk();	/* undocumented but present */
		(void) _fwalk(fflush);
	#endif
	#endif
	}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris