newlib-cygwin/newlib/libc/reent/reent.c

152 lines
3.0 KiB
C
Raw Normal View History

2000-02-18 03:39:52 +08:00
/*
FUNCTION
<<reent>>---definition of impure data.
INDEX
reent
DESCRIPTION
This module defines the impure data area used by the
non-reentrant functions, such as strtok.
2000-02-18 03:39:52 +08:00
*/
#include <stdlib.h>
2000-02-18 03:39:52 +08:00
#include <reent.h>
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifndef REENTRANT_SYSCALLS_PROVIDED
/* We use the errno variable used by the system dependent layer. */
#undef errno
int errno;
#endif
2000-02-18 03:39:52 +08:00
/* Interim cleanup code */
void
_DEFUN (cleanup_glue, (ptr, glue),
struct _reent *ptr _AND
struct _glue *glue)
2000-02-18 03:39:52 +08:00
{
/* Have to reclaim these in reverse order: */
if (glue->_next)
cleanup_glue (ptr, glue->_next);
_free_r (ptr, glue);
}
void
_DEFUN (_reclaim_reent, (ptr),
struct _reent *ptr)
2000-02-18 03:39:52 +08:00
{
if (ptr != _impure_ptr)
{
/* used by mprec routines. */
#ifdef _REENT_SMALL
if (ptr->_mp) /* don't bother allocating it! */
{
#endif
if (_REENT_MP_FREELIST(ptr))
2000-02-18 03:39:52 +08:00
{
int i;
for (i = 0; i < _Kmax; i++)
2000-02-18 03:39:52 +08:00
{
struct _Bigint *thisone, *nextone;
nextone = _REENT_MP_FREELIST(ptr)[i];
2000-02-18 03:39:52 +08:00
while (nextone)
{
thisone = nextone;
nextone = nextone->_next;
_free_r (ptr, thisone);
}
}
_free_r (ptr, _REENT_MP_FREELIST(ptr));
2000-02-18 03:39:52 +08:00
}
if (_REENT_MP_RESULT(ptr))
_free_r (ptr, _REENT_MP_RESULT(ptr));
#ifdef _REENT_SMALL
}
#endif
2000-02-18 03:39:52 +08:00
#ifdef _REENT_SMALL
if (ptr->_emergency)
_free_r (ptr, ptr->_emergency);
if (ptr->_mp)
_free_r (ptr, ptr->_mp);
if (ptr->_r48)
_free_r (ptr, ptr->_r48);
if (ptr->_localtime_buf)
_free_r (ptr, ptr->_localtime_buf);
if (ptr->_asctime_buf)
_free_r (ptr, ptr->_asctime_buf);
if (ptr->_atexit && ptr->_atexit->_on_exit_args_ptr)
_free_r (ptr, ptr->_atexit->_on_exit_args_ptr);
#else
2000-02-18 03:39:52 +08:00
/* atexit stuff */
if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
{
struct _atexit *p, *q;
for (p = ptr->_atexit; p != &ptr->_atexit0;)
{
q = p;
p = p->_next;
_free_r (ptr, q);
}
}
#endif
2000-02-18 03:39:52 +08:00
if (ptr->_cvtbuf)
_free_r (ptr, ptr->_cvtbuf);
if (ptr->__sdidinit)
{
/* cleanup won't reclaim memory 'coz usually it's run
before the program exits, and who wants to wait for that? */
ptr->__cleanup (ptr);
if (ptr->__sglue._next)
cleanup_glue (ptr, ptr->__sglue._next);
}
/* Malloc memory not reclaimed; no good way to return memory anyway. */
}
}
/*
* Do atexit() processing and cleanup
*
* NOTE: This is to be executed at task exit. It does not tear anything
* down which is used on a global basis.
*/
void
_DEFUN (_wrapup_reent, (ptr), struct _reent *ptr)
2000-02-18 03:39:52 +08:00
{
register struct _atexit *p;
register int n;
if (ptr == NULL)
ptr = _REENT;
2000-02-18 03:39:52 +08:00
#ifdef _REENT_SMALL
for (p = ptr->_atexit, n = p ? p->_ind : 0; --n >= 0;)
(*p->_fns[n]) ();
#else
2000-02-18 03:39:52 +08:00
for (p = ptr->_atexit; p; p = p->_next)
for (n = p->_ind; --n >= 0;)
(*p->_fns[n]) ();
#endif
2000-02-18 03:39:52 +08:00
if (ptr->__cleanup)
(*ptr->__cleanup) (ptr);
}