summaryrefslogtreecommitdiff
path: root/libc/stdlib/atexit.c
diff options
context:
space:
mode:
authorErik Andersen <andersen@codepoet.org>2000-05-14 04:16:35 +0000
committerErik Andersen <andersen@codepoet.org>2000-05-14 04:16:35 +0000
commit64bc6412188b141c010ac3b8e813b837dd991e80 (patch)
treeffa12b79ea4b13191754f54b872eb1a4f9e3a04b /libc/stdlib/atexit.c
Initial revision
Diffstat (limited to 'libc/stdlib/atexit.c')
-rw-r--r--libc/stdlib/atexit.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
new file mode 100644
index 000000000..2a82c6edb
--- /dev/null
+++ b/libc/stdlib/atexit.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+ * This file is part of the Linux-8086 C library and is distributed
+ * under the GNU Library General Public License.
+ */
+
+/*
+ * This deals with both the atexit and on_exit function calls
+ *
+ * Note calls installed with atexit are called with the same args as on_exit
+ * fuctions; the void* is given the NULL value.
+ *
+ */
+
+#include <errno.h>
+
+/* ATEXIT.H */
+#define MAXONEXIT 20 /* AIUI Posix requires 10 */
+
+typedef void (*vfuncp) ();
+
+extern vfuncp __cleanup;
+extern void __do_exit();
+
+extern struct exit_table
+{
+ vfuncp called;
+ void *argument;
+}
+__on_exit_table[MAXONEXIT];
+
+extern int __on_exit_count;
+
+/* End ATEXIT.H */
+
+#ifdef L_atexit
+vfuncp __cleanup;
+
+int
+atexit(ptr)
+vfuncp ptr;
+{
+ if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ __cleanup = __do_exit;
+ if( ptr )
+ {
+ __on_exit_table[__on_exit_count].called = ptr;
+ __on_exit_table[__on_exit_count].argument = 0;
+ __on_exit_count++;
+ }
+ return 0;
+}
+
+#endif
+
+#ifdef L_on_exit
+int
+on_exit(ptr, arg)
+vfuncp ptr;
+void *arg;
+{
+ if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ __cleanup = __do_exit;
+ if( ptr )
+ {
+ __on_exit_table[__on_exit_count].called = ptr;
+ __on_exit_table[__on_exit_count].argument = arg;
+ __on_exit_count++;
+ }
+ return 0;
+}
+
+#endif
+
+#ifdef L___do_exit
+
+int __on_exit_count = 0;
+struct exit_table __on_exit_table[MAXONEXIT];
+
+void
+__do_exit(rv)
+int rv;
+{
+ register int count = __on_exit_count-1;
+ register vfuncp ptr;
+ __on_exit_count = -1; /* ensure no more will be added */
+ __cleanup = 0; /* Calling exit won't re-do this */
+
+ /* In reverse order */
+ for (; count >= 0; count--)
+ {
+ ptr = __on_exit_table[count].called;
+ (*ptr) (rv, __on_exit_table[count].argument);
+ }
+}
+
+#endif
+
+#ifdef L_exit
+
+void
+exit(rv)
+int rv;
+{
+ if (__cleanup)
+ __cleanup();
+ _exit(rv);
+}
+
+#endif