Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!mcvax!nikhefh!gert
From: gert@nikhefh.UUCP (Gert Poletiek)
Newsgroups: comp.os.minix
Subject: standard I/O and exit/_exit
Message-ID: <374@nikhefh.UUCP>
Date: Mon, 6-Jul-87 08:17:45 EDT
Article-I.D.: nikhefh.374
Posted: Mon Jul  6 08:17:45 1987
Date-Received: Tue, 7-Jul-87 01:47:10 EDT
References: <3118@felix.UUCP> <2352@hoptoad.uucp> <3169@felix.UUCP>
Reply-To: gert@nikhefh.UUCP (Gert Poletiek)
Organization: Nikhef-H, Amsterdam (the Netherlands).
Lines: 80

In article <3169@felix.UUCP> zemon@felix.UUCP (Art Zemon) writes:
>In article <2352@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>>
>>Wouldn't it be easier to replace the supplied exit() with one
>>that worked, e.g. that implemented onexit(), so stdio could get
>>its buffers flushed without rewriting every program?
>
>The original idea behind this was to keep the tools in
>/usr/bin and /bin small by not including the stdio library.
>Exit(), if it called _cleanup(), would bring in large chunks
>of otherwise unused code.
>
>I think a better solution would be to rename the existing
>exit() to _exit() and create an exit() subroutine which
>calls _cleanup() and change the tools which don't use stdio
>to call _exit().  Whew!  I said all that in one breath. :-)
>--
>	-- Art Zemon
>	   FileNet Corporation
>	   Costa Mesa, California
>	   ...!hplabs!felix!zemon

A solution that does not cause any overhead when not using the standard I/O
library, and still flushes the buffers of the standard I/O library when it
*is* used would be this:

In the runtime startup module for every program (crt0 ??)  one should declare
a pointer to a cleanupo function:

extern int		(_cleanup (*)());

Not having initialized this pointer it will be zero.

Then in the standard I/O library module that allocates the stream buffers
one would have to include the following:
(**note that the identifiers are probably not the same as those in the Minix
library: I don't have the tape yet **)

static __stdio_cleanup ()
{
	register int	i;

	for ( i=0; i<_NFILE; i++ )		/* for all streams */
		fclose ( _iobuf[i] );		/* close it */
}

int	(_cleanup (*)()) = __stdio_cleanup;


And in the module for exit:

extern int	(_cleanup (*)());

exit ( code )
int code;
{
	if ( _cleanup )			/* is standard I/O used ? */
		(*_cleanup)();		/* flush stdio buffers */
	/*
		rest of the exit routine as it is now 
	*/
}


In addition one needs a module that initializes the _cleanup pointer in case
standard I/O is not used:

int	(_cleanup (*)()) = 0;

This module should be in the end of the library so the linker will encounter
it always *after* the module containing the other initialisation of
_cleanup.

Hope that helps a bit.


Gert Poletiek
Dutch National Institute for High Energy Physics, NIKHEF-H
Amsterdam
The Netherlands.