bpendlet@esunix.UUCP (Bob Pendleton) (08/18/88)
I'd have thought this was trivial, except that I've spent 2 days RTFMing and can't find the answer. I'm writing a library that needs to do some clean up when the program that is using it is done. Just because I'm such a nice guy I'd like to let the user program just terminate, any old way, a signal or by exit() and just automagically do the clean up. Well I can catch a signal, but I haven't found a portable way to "catch" exit(). I found the SunOS on_exit() routine, nice. But ULTRIX doesn't seem to have one, and I've been told that this is going to have to port to System V. So, is there a portable way for a routine to dectect when the program it is part of is trying to exit()? Bob P. -- Bob Pendleton @ Evans & Sutherland UUCP Address: {decvax,ucbvax,allegra}!decwrl!esunix!bpendlet Alternate: utah-cs!esunix!bpendlet I am solely responsible for what I say.
U23405@UICVM (Michael J. Steiner) (08/25/88)
The easiest way to do some cleaning up when exiting your program would
probably be to call a special function that would do the cleaning up, with
the last statement of that function being exit(), like this:
void my_exit()
{
/* Clean up */
...
exit();
}
If this isn't what you're talking about, please tell me.
Michael Steiner
Email: U23405@UICVM.BITNET
lvc@cbnews.ATT.COM (Lawrence V. Cipriani) (08/27/88)
One solution that I have employed is to define my own exit routine.
When the program terminates my exit routine is called, and does what
I want.
void exit(e)
int e;
{
...whatever...
_exit(e); /* still need this sucker */
}
This probably is non-portable but should solve your problem (if I
understood it correctly).
If you have the source code to popen(3) look at it for another example.
--
Larry Cipriani, AT&T Network Systems, Columbus OH, cbnews!lvc lvc@cbnews.ATT.COM
leo@philmds.UUCP (Leo de Wit) (08/28/88)
In article <967@cbnews.ATT.COM> lvc@cbnews.ATT.COM (Lawrence V. Cipriani) writes: >One solution that I have employed is to define my own exit routine. >When the program terminates my exit routine is called, and does what >I want. > > void exit(e) > int e; > { > ...whatever... > _exit(e); /* still need this sucker */ > } > >This probably is non-portable but should solve your problem (if I >understood it correctly). One of the problems looming up is that exit() should flush stdio buffers. (this should be part of ...whatever...). I don't know how that can be done in a portable manner. Ultrix seems to use _cleanup() at this point. There is a funny thing about _cleanup(): It is called without parameters. If I run the following program through adb: main() { exit(0); } then _cleanup() does just: ret. If I run the following however: main() { printf("12345"); exit(0); } then _cleanup() does a lot of stuff. It seems that if stdio is not used a simple version of _cleanup is used; if it IS used, a complicated one is used that does a _filewalk() or something. Probably has something to do with keeping binary sizes small, but I can't figure out how you can have several _cleanup() 's in one library. Anyone knows? Leo.
bill@proxftl.UUCP (T. William Wells) (08/29/88)
In article <771@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
: Probably has something to
: do with keeping binary sizes small,
Yes. Loading the stdio _cleanup means loading a substantial part
of stdio as well.
: but I can't figure out how you can
: have several _cleanup() 's in one library. Anyone knows?
:
: Leo.
This is easy on a UNIX system. You define __iob or whatever the
FILE pointers point to in the file where you want the fancy
_cleanup routine to go. You then place the exit and then the
dummy _cleanup right after it. You have to give the two object
files different names, but that is easy. The names I have seen
are cleanup.o and fakcu.o. So, if the program references stdio
anywhere, it will reference __iob. When the linker finds the
first _cleanup, it will load it because of the __iob. Then exit
comes along and uses the already loaded _cleanup so the second
one is ignored. On the other hand, if stdio is not referenced,
the first _cleanup is ignored because there is no reference to
it; the exit is loaded because every program references exit, and
that forces the loading of the second _cleanup.
There are several variations on this theme, but as far as I know
they all depend on library ordering tricks.
---
Bill
novavax!proxftl!bill
henry@utzoo.uucp (Henry Spencer) (08/29/88)
In article <771@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes: >... It seems that if stdio is not used >a simple version of _cleanup is used; if it IS used, a complicated one >is used that does a _filewalk() or something. Probably has something to >do with keeping binary sizes small, but I can't figure out how you can >have several _cleanup() 's in one library. Anyone knows? I don't know how Ultrix is doing it, but the way V7 did it was to use a non-ranlibbed libc and have two versions of _cleanup, one preceding exit and the other following it. The first one was tied to stdio by some carefully-crafted external references, so it would be picked up if stdio was in use, while the second one would be picked up if the first wasn't. You can't do this with a single ranlibbed library, at least not that I know of, but you can pull the same trick by using more than one library and getting the search order right. It is in any case somewhat academic, since stdio is practically universal these days. -- Intel CPUs are not defective, | Henry Spencer at U of Toronto Zoology they just act that way. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
greggy@infmx.UUCP (greg yachuk) (08/30/88)
Microsoft C defines a function `onexit()' which takes the address of a function that is to be executed when the program terminates normally. Up to 32 functions may be specified, which are executed in a LIFO manner. The functions may not take any parameters. The MSC 5.0 manual also states that there is a similar ANSI-standard functions named `atexit()'. I don't know anything about it. Greg Yachuk Informix Software Inc., Menlo Park, CA (415) 322-4100 {uunet,pyramid}!infmx!greggy why yes, I DID choose that login myself
gwyn@smoke.ARPA (Doug Gwyn ) (08/31/88)
In article <388@infmx.UUCP> greggy@infmx.UUCP (greg yachuk) writes: >Microsoft C defines a function `onexit()' ... >The MSC 5.0 manual also states that there is a similar ANSI-standard >functions named `atexit()'. I don't know anything about it. onexit() originated with Whitesmiths, Ltd. Somewhere in the course of developing the proposed ANSI C standard, a similar but incompatible function of the same name was present for several drafts. However, it was possible to take the revised onexit() and substantially simplify the interface, and so we did. I suggested calling the result atexit() so that Whitesmiths customers would not find their use of onexit() broken. Unfortunately, IBM and Microsoft jumped the gun and added the interim version of onexit() to their C implementations. Not only is it incompatible with the original Whitesmiths version, it isn't the function finally adopted by X3J11 for this purpose. (At least it is possible to implement both simultaneously!) Incidentally, there are still some unintended ambiguities in the specification of atexit(), but (as I recall; my notes are not at hand) the Committee was unwilling to tighten up the spec at this point. The main ambiguity is that an exit handler SHOULD be unregistered before it is invoked, so that a reentry to exit() from an exit handler will not cause an infinite recursion, but we hadn't thought of that until a member of the public pointed it out. I hope that implementors will be careful to do this. Perhaps I should update my public-domain implementation and repost it.