frank@Morgan.COM (Frank Wortner) (11/15/88)
I've written an atexit() function for use with the Minix 1.3 library. It's occasionally useful, and no one (that I can recall) has posted anything like it yet, so here it is. Enjoy! Frank ------------------------------------------------------------------------------ echo x - atexit.doc sed '/^X/s///' > atexit.doc << '/' Xint atexit(func) Xvoid (*func)(); X Xatexit() arranges for the subroutine whose address is func to be Xcalled upon normal program termination. atexit() returns zero Xif the registration cannot be made, non-zero otherwise. / echo x - atexit.c sed '/^X/s///' > atexit.c << '/' X/* Copyright 1988 Frank Wortner X** You may reproduce and use this software as long as you X** do not delete this notice from the source code. X*/ X X#define MAXFN 33 /* Maximum number of functions registerable X (includes 1 for __cleanup) */ X Xtypedef void (*PFN)(); /* Pointer to FuNction */ X Xextern PFN __cleanup; /* imported from exit.c */ X Xstatic PFN fn[MAXFN]; /* addresses of functions stored here */ Xstatic int nfn = -1; /* number of functions registered less one */ X Xvoid checkcleanup(), run_atexit(); X Xint atexit(fun) XPFN fun; X{ X if (nfn == -1) /* Do we need to check for stdio? */ X checkcleanup(); X if (nfn >= MAXFN) /* Run out of room yet? */ X return (-1); X fn[++nfn] = fun; /* Save the address of the subr. */ X return (0); X} X X/* Check to see if stdio is used. If yes register stdio's cleanup routine X** with the atexit() system and then force stdio to call run_atexit(). X*/ Xstatic void checkcleanup() X{ X if (__cleanup) /* stdio used ? */ X fn[++nfn] = __cleanup; X __cleanup = run_atexit; X} X X/* Run the requested subroutines */ Xstatic void run_atexit() X{ X while (nfn >= 0) { X (*fn)[nfn--](); X } X} / -- Frank "Computers are mistake amplifiers."
frank@Morgan.COM (Frank Wortner) (11/28/88)
Here, for hopefully the *final* time is atexit(). Credit goes to Mark Becker and Bruce Evans for spotting inconsistancies in the previous (now cancelled) postings. To use this function, unshar the attached archive, and apply the patch putc.dif to putc.c. (It's in libsrc.a.) Compile the resulting putc.c like so: cc -c -O -LIB putc.c and replace putc.s in libc.a. If you do not, atexit() won't work. atexit() also will not work if you do not have the 1.3 C library. You can make it work with earlier libaries by modifying exit.c. Simply add a line that checks to see if __cleanup contains a non-NULL pointer and calls the function addressed. One final warning: I've only tried this function on PC-Minix. While chances are the ST library works in the same manner, I have no way of confirming this. Good luck. Frank "Computers are mistake amplifiers." -------------------------------cut here---------------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # atexit.c # atexit.fmt # putc.dif # This archive created: Mon Nov 28 08:53:10 1988 export PATH; PATH=/bin:$PATH echo shar: extracting "'atexit.c'" '(1126 characters)' if test -f 'atexit.c' then echo shar: will not over-write existing file "'atexit.c'" else sed 's/^ X//' << \SHAR_EOF > 'atexit.c' X/* Copyright 1988 Frank Wortner X** You may reproduce and use this software as long as you X** do not delete this notice from the source code. X*/ X X#define MAXFN 33 /* Maximum number of functions registerable X (includes 1 for __cleanup) */ X Xtypedef void (*PFN)(); /* Pointer to FuNction */ X Xextern PFN __cleanup; /* imported from exit.c */ X Xstatic PFN fn[MAXFN]; /* addresses of functions stored here */ Xstatic int nfn = -1; /* number of functions registered less one */ X Xstatic void checkcleanup(), run_atexit(); X Xint atexit(fun) XPFN fun; X{ X if (nfn == -1) /* Do we need to check for stdio? */ X checkcleanup(); X if (nfn >= MAXFN) /* Run out of room yet? */ X return (-1); X fn[++nfn] = fun; /* Save the address of the subr. */ X return (0); X} X X/* Check to see if stdio is used. If yes register stdio's cleanup routine X** with the atexit() system and then force stdio to call run_atexit(). X*/ Xstatic void checkcleanup() X{ X if (__cleanup) /* stdio used ? */ X fn[++nfn] = __cleanup; X __cleanup = run_atexit; X} X X/* Run the requested subroutines */ Xstatic void run_atexit() X{ X while (nfn >= 0) { X (*fn[nfn--])(); X } X} SHAR_EOF if test 1126 -ne "`wc -c < 'atexit.c'`" then echo shar: error transmitting "'atexit.c'" '(should have been 1126 characters)' fi fi # end of overwriting check echo shar: extracting "'atexit.fmt'" '(422 characters)' if test -f 'atexit.fmt' then echo shar: will not over-write existing file "'atexit.fmt'" else sed 's/^ X//' << \SHAR_EOF > 'atexit.fmt' X X X Xatexit(3) C LIBRARY FUNCTIONS atexit(3) X X X XNAME X atexit() - call a function just before program termination X XSYNOPSIS X int atexit(func) X void (*func)(); X XDESCRIPTION X atexit() arranges for the subroutine whose address is func X to be called upon normal program termination. atexit() X returns zero if the registration cannot be made, non-zero X otherwise. X SHAR_EOF if test 422 -ne "`wc -c < 'atexit.fmt'`" then echo shar: error transmitting "'atexit.fmt'" '(should have been 422 characters)' fi fi # end of overwriting check echo shar: extracting "'putc.dif'" '(528 characters)' if test -f 'putc.dif' then echo shar: will not over-write existing file "'putc.dif'" else sed 's/^ X//' << \SHAR_EOF > 'putc.dif' X*** putc.c.orig Tue Nov 23 05:14:07 1988 X--- putc.c Tue Nov 23 05:08:07 1988 X*************** X*** 22,28 **** X didwrite++; X } X else{ X! __cleanup = _cleanup; X *iop->_ptr++ = ch; X if ((++iop->_count) >= BUFSIZ && !testflag(iop,STRINGS) ){ X n = write(iop->_fd,iop->_buf,iop->_count); X--- 22,29 ---- X didwrite++; X } X else{ X! if (__cleanup == 0) X! __cleanup = _cleanup; X *iop->_ptr++ = ch; X if ((++iop->_count) >= BUFSIZ && !testflag(iop,STRINGS) ){ X n = write(iop->_fd,iop->_buf,iop->_count); SHAR_EOF if test 528 -ne "`wc -c < 'putc.dif'`" then echo shar: error transmitting "'putc.dif'" '(should have been 528 characters)' fi fi # end of overwriting check # End of shell archive exit 0 -- Frank "Computers are mistake amplifiers."