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:
authorNick Clifton <nickc@redhat.com>2003-06-06 19:36:31 +0400
committerNick Clifton <nickc@redhat.com>2003-06-06 19:36:31 +0400
commit75d7d177004358ba5e410a2cd98f2249b6c4e1b3 (patch)
treefc1541e54ea04ed5a4260fbc60e578424945e2ef /newlib/libc
parent54152c7e7ed656c969fe4536f17f66360cd8d971 (diff)
New structure containing fields used by the on_exit() function.
(struct _atexit): Include struct _on_exit_args. For _REENT_SMALL do his via a pointer that is initialised when needed.
Diffstat (limited to 'newlib/libc')
-rw-r--r--newlib/libc/include/sys/reent.h16
-rw-r--r--newlib/libc/reent/reent.c2
-rw-r--r--newlib/libc/stdlib/atexit.c6
-rw-r--r--newlib/libc/stdlib/exit.c41
-rw-r--r--newlib/libc/stdlib/on_exit.c29
5 files changed, 67 insertions, 27 deletions
diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h
index 2d6ce4146..d1a04dc43 100644
--- a/newlib/libc/include/sys/reent.h
+++ b/newlib/libc/include/sys/reent.h
@@ -64,20 +64,24 @@ struct __tm
#define _ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */
-#ifndef _REENT_SMALL
+struct _on_exit_args {
+ void * _fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */
+ __ULong _fntypes; /* type of exit routine -
+ Must have at least _ATEXIT_SIZE bits */
+};
+
+#ifdef _REENT_SMALL
struct _atexit {
- struct _atexit *_next; /* next in list */
int _ind; /* next index in this table */
void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */
- void *_fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */
- __ULong _fntypes; /* type of exit routine */
+ struct _on_exit_args * _on_exit_args_ptr;
};
#else
struct _atexit {
+ struct _atexit *_next; /* next in list */
int _ind; /* next index in this table */
void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */
- void *_fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */
- __ULong _fntypes; /* type of exit routine */
+ struct _on_exit_args _on_exit_args;
};
#endif
diff --git a/newlib/libc/reent/reent.c b/newlib/libc/reent/reent.c
index 9300e8cd0..3ce02dcf2 100644
--- a/newlib/libc/reent/reent.c
+++ b/newlib/libc/reent/reent.c
@@ -81,6 +81,8 @@ _DEFUN (_reclaim_reent, (ptr),
_free_r (ptr, ptr->_localtime_buf);
if (ptr->_asctime_buf)
_free_r (ptr, ptr->_asctime_buf);
+ if (ptr->_atexit._on_exit_args_ptr)
+ _free_r (ptr->_atexit._on_exit_args_ptr);
#else
/* atexit stuff */
if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
diff --git a/newlib/libc/stdlib/atexit.c b/newlib/libc/stdlib/atexit.c
index 165b3cf07..e0e42988a 100644
--- a/newlib/libc/stdlib/atexit.c
+++ b/newlib/libc/stdlib/atexit.c
@@ -65,16 +65,16 @@ _DEFUN (atexit,
{
register struct _atexit *p;
-/* _REENT_SMALL atexit() doesn't allow more than the required 32 entries. */
+ /* _REENT_SMALL atexit() 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;
+ return -1;
p->_ind = 0;
- p->_fntypes = 0;
+ p->_on_exit_args._fntypes = 0;
p->_next = _REENT->_atexit;
_REENT->_atexit = p;
}
diff --git a/newlib/libc/stdlib/exit.c b/newlib/libc/stdlib/exit.c
index 54664fec5..a659361bd 100644
--- a/newlib/libc/stdlib/exit.c
+++ b/newlib/libc/stdlib/exit.c
@@ -60,20 +60,43 @@ _DEFUN (exit, (code),
int code)
{
register struct _atexit *p;
+ register struct _on_exit_args * args;
register int n;
- int i = 1;
+ int i;
+
+ p = &_REENT->_atexit;
#ifdef _REENT_SMALL
- for (p = &_REENT->_atexit, n = p->_ind-1, i = (n>=0) ? (1<<n) : 0;
- n >= 0; --n, i >>= 1)
+ args = p->_on_exit_args_ptr;
+
+ if (args == NULL)
+ {
+ for (n = p->_ind; n--;)
+ p->_fns[n] ();
+ }
+ else
+ {
+ for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
+ if (args->_fntypes & i)
+ (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]);
+ else
+ p->_fns[n] ();
+ }
#else
- for (p = _REENT->_atexit; p; p = p->_next)
- for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
+ do
+ {
+ args = & p->_on_exit_args;
+
+ for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
+ if (args->_fntypes & i)
+ (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]);
+ else
+ p->_fns[n] ();
+
+ p = p->_next;
+ }
+ while (p);
#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);
diff --git a/newlib/libc/stdlib/on_exit.c b/newlib/libc/stdlib/on_exit.c
index 1b6cd2abe..b7bf6f304 100644
--- a/newlib/libc/stdlib/on_exit.c
+++ b/newlib/libc/stdlib/on_exit.c
@@ -68,29 +68,40 @@ _DEFUN (on_exit,
_VOID _EXFUN ((*fn), (int, _PTR)) _AND
_PTR arg)
{
+ struct _on_exit_args * args;
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
+#ifdef _REENT_SMALL
+ p = &_REENT->_atexit;
+ if (p->_ind >= _ATEXIT_SIZE)
+ return -1;
+ args = p->_on_exit_args_ptr;
+ if (args == NULL)
+ {
+ args = malloc (sizeof * p->_on_exit_args_ptr);
+ if (args == NULL)
+ return -1;
+ args->_fntypes = 0;
+ p->_on_exit_args_ptr = args;
+ }
+#else
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;
+ return -1;
p->_ind = 0;
- p->_fntypes = 0;
+ p->_on_exit_args._fntypes = 0;
p->_next = _REENT->_atexit;
_REENT->_atexit = p;
}
-#else
- p = &_REENT->_atexit;
- if (p->_ind >= _ATEXIT_SIZE)
- return -1;
+ args = & p->_on_exit_args;
#endif
- p->_fntypes |= (1 << p->_ind);
- p->_fnargs[p->_ind] = arg;
+ args->_fntypes |= (1 << p->_ind);
+ args->_fnargs[p->_ind] = arg;
p->_fns[p->_ind++] = x;
return 0;
}