os/ossrv/genericopenlibs/cstdlib/LPOSIX/ATEXIT.C
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LPOSIX/ATEXIT.C	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,108 @@
     1.4 +/* ATEXIT.C
     1.5 + * 
     1.6 + * Portions Copyright (c) 1990-2006 Nokia Corporation and/or its subsidiary(-ies).
     1.7 + * All rights reserved.
     1.8 + */
     1.9 +
    1.10 +/*
    1.11 + * Copyright (c) 1990 Regents of the University of California.
    1.12 + * All rights reserved.
    1.13 + *
    1.14 + * %sccs.include.redist.c%
    1.15 + */
    1.16 +
    1.17 +/*
    1.18 +FUNCTION
    1.19 +<<atexit>>---request execution of functions at program exit
    1.20 +
    1.21 +INDEX
    1.22 +	atexit
    1.23 +
    1.24 +ANSI_SYNOPSIS
    1.25 +	#include <stdlib.h>
    1.26 +	int atexit(void (*<[function]>)(void);
    1.27 +
    1.28 +TRAD_SYNOPSIS
    1.29 +	#include <stdlib.h>
    1.30 +	int atexit((<[function]>)
    1.31 +	void (*<[function]>)();
    1.32 +
    1.33 +DESCRIPTION
    1.34 +You can use <<atexit>> to enroll functions in a list of functions that
    1.35 +will be called when your program terminates normally.  The argument is
    1.36 +a pointer to a user-defined function (which must not require arguments and
    1.37 +must not return a result).
    1.38 +
    1.39 +The functions are kept in a LIFO stack; that is, the last function
    1.40 +enrolled by <<atexit>> will be the first to execute when your program
    1.41 +exits.
    1.42 +
    1.43 +There is no built-in limit to the number of functions you can enroll
    1.44 +in this list; however, after every group of 32 functions is enrolled,
    1.45 +<<atexit>> will call <<malloc>> to get space for the next part of the
    1.46 +list.   The initial list of 32 functions is statically allocated, so
    1.47 +you can always count on at least that many slots available.
    1.48 +
    1.49 +RETURNS
    1.50 +<<atexit>> returns <<0>> if it succeeds in enrolling your function,
    1.51 +<<-1>> if it fails (possible only if no space was available for
    1.52 +<<malloc>> to extend the list of functions or the library globals could not
    1.53 +be allocated).
    1.54 +
    1.55 +PORTABILITY
    1.56 +<<atexit>> is required by the ANSI standard, which also specifies that
    1.57 +implementations must support enrolling at least 32 functions.
    1.58 +
    1.59 +Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
    1.60 +<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
    1.61 +*/
    1.62 +
    1.63 +#include <stddef.h>
    1.64 +#include <stdlib.h>
    1.65 +#include <reent.h>
    1.66 +
    1.67 +/*
    1.68 + * Register a function to be performed at exit.
    1.69 + * NB. MSVC 5.0 has a built-in prototype for atexit, so we have to use a #define
    1.70 + * to map the name atexit to _epoc32_atexit
    1.71 + */
    1.72 +
    1.73 +/*
    1.74 +@return On Success, returns 0.
    1.75 +		On Failure, returns -1.
    1.76 +*/
    1.77 +
    1.78 +EXPORT_C int
    1.79 +_epoc32_atexit (void (*fn)(void))
    1.80 +{
    1.81 +  register struct _atexit *p;
    1.82 +  struct _reent *rp = _REENT2;
    1.83 +  if (!rp)
    1.84 +	return -1; // Memory for library globals is not allocated (errno not set). 
    1.85 + 
    1.86 +  if ((p = rp->_atexit) == NULL)
    1.87 +    rp->_atexit = p = &rp->_atexit0;
    1.88 +  if (p->_ind >= _ATEXIT_SIZE)
    1.89 +    {
    1.90 +      if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
    1.91 +		return -1;
    1.92 +      p->_ind = 0;
    1.93 +      p->_next = rp->_atexit;
    1.94 +      rp->_atexit = p;
    1.95 +    }
    1.96 +  p->_fns[p->_ind++] = fn;
    1.97 +  return 0;
    1.98 +}
    1.99 +
   1.100 +EXPORT_C void 
   1.101 +_atexit_processing_r (struct _reent *rp)
   1.102 +{
   1.103 +  register struct _atexit *p;
   1.104 +  register int n;
   1.105 +
   1.106 +  for (p = rp->_atexit; p; p = p->_next)
   1.107 +    for (n = p->_ind; --n >= 0;)
   1.108 +      (*p->_fns[n]) ();
   1.109 +  if (rp->__cleanup)
   1.110 +    (*rp->__cleanup) (rp);
   1.111 +}