Path: utzoo!mnetor!uunet!husc6!hao!oddjob!mimsy!chris
From: chris@mimsy.UUCP (Chris Torek)
Newsgroups: comp.os.minix
Subject: Re: Making exit() flush stdio buffers on exit
Message-ID: <9750@mimsy.UUCP>
Date: 13 Dec 87 17:09:02 GMT
References: <960@uokmax.UUCP>
Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742
Lines: 54

In article <960@uokmax.UUCP> rmtodd@uokmax.UUCP (Richard Michael Todd) writes:
>... exit() always flushes all stdio buffers, _exit() exits
>immediately, but exit() won't cause stdio to be linked in if
>your program never references it. ...
...
>	4.  Create a new file 'fakecleanup.c' with this in it:
>	int _cleanup() {}
>	5. Compile the changed and added files and rebuild the library.
[being very careful about the order of files in the library]

This method can work, depending on the implmentation of your archiver
and loader, but is rather painful.  A simpler (to me) system is
the one I implemented recently; it goes about like this:

	exit.c:
	int (*__cleanup)();

	exit(status)
		int status;
	{

		if (__cleanup)
			(*__cleanup)();
		_exit(status);
	}

	:
		...
		extern int (*__cleanup)();
		int _cleanup();

		/* arrange for exit to call _cleanup */
		__cleanup = _cleanup;
		...

This way exit has no reference to any stdio functions; it merely
uses a sizeof(int (*)()) global variable.  If stdio has been used,
this variable points to _cleanup, so that exit can find it.  Note
that if stdio is referenced but never used, _cleanup is never
called.  This particular implementation assumes that exit will
always be referenced if stdio is referenced; since the typical C
startup is `...; exit(main(argc, argv, envp));' this will be true
unless you write assembly coded startups.

This would be better done with a reserved slot in an `atexit'
table, but that requires a bit more ambition than I had when I
implemented it.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris