Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/stdlib')
-rw-r--r--newlib/libc/stdlib/Makefile.am2
-rw-r--r--newlib/libc/stdlib/Makefile.in23
-rw-r--r--newlib/libc/stdlib/atexit.c1
-rw-r--r--newlib/libc/stdlib/exit.c13
-rw-r--r--newlib/libc/stdlib/on_exit.c96
5 files changed, 121 insertions, 14 deletions
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index aad103266..26e4b5332 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -55,6 +55,7 @@ LIB_SOURCES = \
mstats.c \
mtrim.c \
nrand48.c \
+ on_exit.c \
putenv.c \
putenv_r.c \
qsort.c \
@@ -167,6 +168,7 @@ CHEWOUT_FILES= \
mbtowc.def \
mlock.def \
mstats.def \
+ on_exit.def \
qsort.def \
rand.def \
rand48.def \
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 95c56e667..fdb37338d 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -153,6 +153,7 @@ LIB_SOURCES = \
mstats.c \
mtrim.c \
nrand48.c \
+ on_exit.c \
putenv.c \
putenv_r.c \
qsort.c \
@@ -226,6 +227,7 @@ CHEWOUT_FILES = \
mbtowc.def \
mlock.def \
mstats.def \
+ on_exit.def \
qsort.def \
rand.def \
rand48.def \
@@ -268,12 +270,13 @@ LIBS = @LIBS@
@USE_LIBTOOL_FALSE@lcong48.o ldiv.o ldtoa.o lrand48.o malign.o malloc.o \
@USE_LIBTOOL_FALSE@mblen.o mblen_r.o mbstowcs.o mbstowcs_r.o mbtowc.o \
@USE_LIBTOOL_FALSE@mbtowc_r.o mlock.o mprec.o mrand48.o msize.o \
-@USE_LIBTOOL_FALSE@mstats.o mtrim.o nrand48.o putenv.o putenv_r.o \
-@USE_LIBTOOL_FALSE@qsort.o rand.o rand48.o rand_r.o realloc.o seed48.o \
-@USE_LIBTOOL_FALSE@setenv.o setenv_r.o srand48.o strdup.o strdup_r.o \
-@USE_LIBTOOL_FALSE@strtod.o strtol.o strtoll.o strtoll_r.o strtoul.o \
-@USE_LIBTOOL_FALSE@strtoull.o strtoull_r.o system.o valloc.o wcstombs.o \
-@USE_LIBTOOL_FALSE@wcstombs_r.o wctomb.o wctomb_r.o
+@USE_LIBTOOL_FALSE@mstats.o mtrim.o nrand48.o on_exit.o putenv.o \
+@USE_LIBTOOL_FALSE@putenv_r.o qsort.o rand.o rand48.o rand_r.o \
+@USE_LIBTOOL_FALSE@realloc.o seed48.o setenv.o setenv_r.o srand48.o \
+@USE_LIBTOOL_FALSE@strdup.o strdup_r.o strtod.o strtol.o strtoll.o \
+@USE_LIBTOOL_FALSE@strtoll_r.o strtoul.o strtoull.o strtoull_r.o \
+@USE_LIBTOOL_FALSE@system.o valloc.o wcstombs.o wcstombs_r.o wctomb.o \
+@USE_LIBTOOL_FALSE@wctomb_r.o
LTLIBRARIES = $(noinst_LTLIBRARIES)
@USE_LIBTOOL_TRUE@libstdlib_la_DEPENDENCIES = freer.$(oext) \
@@ -291,10 +294,10 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
@USE_LIBTOOL_TRUE@ldtoa.lo lrand48.lo malign.lo malloc.lo mblen.lo \
@USE_LIBTOOL_TRUE@mblen_r.lo mbstowcs.lo mbstowcs_r.lo mbtowc.lo \
@USE_LIBTOOL_TRUE@mbtowc_r.lo mlock.lo mprec.lo mrand48.lo msize.lo \
-@USE_LIBTOOL_TRUE@mstats.lo mtrim.lo nrand48.lo putenv.lo putenv_r.lo \
-@USE_LIBTOOL_TRUE@qsort.lo rand.lo rand48.lo rand_r.lo realloc.lo \
-@USE_LIBTOOL_TRUE@seed48.lo setenv.lo setenv_r.lo srand48.lo strdup.lo \
-@USE_LIBTOOL_TRUE@strdup_r.lo strtod.lo strtol.lo strtoll.lo \
+@USE_LIBTOOL_TRUE@mstats.lo mtrim.lo nrand48.lo on_exit.lo putenv.lo \
+@USE_LIBTOOL_TRUE@putenv_r.lo qsort.lo rand.lo rand48.lo rand_r.lo \
+@USE_LIBTOOL_TRUE@realloc.lo seed48.lo setenv.lo setenv_r.lo srand48.lo \
+@USE_LIBTOOL_TRUE@strdup.lo strdup_r.lo strtod.lo strtol.lo strtoll.lo \
@USE_LIBTOOL_TRUE@strtoll_r.lo strtoul.lo strtoull.lo strtoull_r.lo \
@USE_LIBTOOL_TRUE@system.lo valloc.lo wcstombs.lo wcstombs_r.lo \
@USE_LIBTOOL_TRUE@wctomb.lo wctomb_r.lo
diff --git a/newlib/libc/stdlib/atexit.c b/newlib/libc/stdlib/atexit.c
index 77aab0c98..165b3cf07 100644
--- a/newlib/libc/stdlib/atexit.c
+++ b/newlib/libc/stdlib/atexit.c
@@ -74,6 +74,7 @@ _DEFUN (atexit,
if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
return -1;
p->_ind = 0;
+ p->_fntypes = 0;
p->_next = _REENT->_atexit;
_REENT->_atexit = p;
}
diff --git a/newlib/libc/stdlib/exit.c b/newlib/libc/stdlib/exit.c
index fb7f73e77..54664fec5 100644
--- a/newlib/libc/stdlib/exit.c
+++ b/newlib/libc/stdlib/exit.c
@@ -61,15 +61,20 @@ _DEFUN (exit, (code),
{
register struct _atexit *p;
register int n;
+ int i = 1;
#ifdef _REENT_SMALL
- for (p = &_REENT->_atexit, n = p->_ind; --n >= 0;)
- (*p->_fns[n]) ();
+ for (p = &_REENT->_atexit, n = p->_ind-1, i = (n>=0) ? (1<<n) : 0;
+ n >= 0; --n, i >>= 1)
#else
for (p = _REENT->_atexit; p; p = p->_next)
- for (n = p->_ind; --n >= 0;)
- (*p->_fns[n]) ();
+ for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
#endif
+ if (p->_fntypes & i)
+ (*((void (*)(int, void *))p->_fns[n]))(code, p->_fnargs[n]);
+ else
+ (*p->_fns[n]) ();
+
if (_REENT->__cleanup)
(*_REENT->__cleanup) (_REENT);
_exit (code);
diff --git a/newlib/libc/stdlib/on_exit.c b/newlib/libc/stdlib/on_exit.c
new file mode 100644
index 000000000..1b6cd2abe
--- /dev/null
+++ b/newlib/libc/stdlib/on_exit.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ *
+ * This function is a modified version of atexit.c
+ */
+
+/*
+FUNCTION
+<<on_exit>>---request execution of function with argument at program exit
+
+INDEX
+ on_exit
+
+ANSI_SYNOPSIS
+ #include <stdlib.h>
+ int on_exit (void (*<[function]>)(int, void *), void *<[arg]>);
+
+TRAD_SYNOPSIS
+ #include <stdlib.h>
+ int on_exit ((<[function]>, <[arg]>)
+ void (*<[function]>)(int, void *);
+ void *<[arg]>;
+
+DESCRIPTION
+You can use <<on_exit>> to enroll functions in a list of functions that
+will be called when your program terminates normally. The argument is
+a pointer to a user-defined function which takes two arguments. The
+first is the status code passed to exit and the second argument is of type
+pointer to void. The function must not return a result. The value
+of <[arg]> is registered and passed as the argument to <[function]>.
+
+The functions are kept in a LIFO stack; that is, the last function
+enrolled by <<atexit>> or <<on_exit>> will be the first to execute when
+your program exits. You can intermix functions using <<atexit>> and
+<<on_exit>>.
+
+There is no built-in limit to the number of functions you can enroll
+in this list; however, after every group of 32 functions is enrolled,
+<<atexit>>/<<on_exit>> will call <<malloc>> to get space for the next part
+of the list. The initial list of 32 functions is statically allocated, so
+you can always count on at least that many slots available.
+
+RETURNS
+<<on_exit>> returns <<0>> if it succeeds in enrolling your function,
+<<-1>> if it fails (possible only if no space was available for
+<<malloc>> to extend the list of functions).
+
+PORTABILITY
+<<on_exit>> is a non-standard glibc extension
+
+Supporting OS subroutines required: None
+*/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <reent.h>
+
+/*
+ * Register a function to be performed at exit.
+ */
+
+int
+_DEFUN (on_exit,
+ (fn, arg),
+ _VOID _EXFUN ((*fn), (int, _PTR)) _AND
+ _PTR arg)
+{
+ register struct _atexit *p;
+ void (*x)(void) = (void (*)(void))fn;
+
+/* _REENT_SMALL on_exit() doesn't allow more than the required 32 entries. */
+#ifndef _REENT_SMALL
+ if ((p = _REENT->_atexit) == NULL)
+ _REENT->_atexit = p = &_REENT->_atexit0;
+ if (p->_ind >= _ATEXIT_SIZE)
+ {
+ if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
+ return -1;
+ p->_ind = 0;
+ p->_fntypes = 0;
+ p->_next = _REENT->_atexit;
+ _REENT->_atexit = p;
+ }
+#else
+ p = &_REENT->_atexit;
+ if (p->_ind >= _ATEXIT_SIZE)
+ return -1;
+#endif
+ p->_fntypes |= (1 << p->_ind);
+ p->_fnargs[p->_ind] = arg;
+ p->_fns[p->_ind++] = x;
+ return 0;
+}