os/ossrv/genericopenlibs/cstdlib/LPOSIX/ATEXIT.C
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* ATEXIT.C
sl@0
     2
 * 
sl@0
     3
 * Portions Copyright (c) 1990-2006 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     4
 * All rights reserved.
sl@0
     5
 */
sl@0
     6
sl@0
     7
/*
sl@0
     8
 * Copyright (c) 1990 Regents of the University of California.
sl@0
     9
 * All rights reserved.
sl@0
    10
 *
sl@0
    11
 * %sccs.include.redist.c%
sl@0
    12
 */
sl@0
    13
sl@0
    14
/*
sl@0
    15
FUNCTION
sl@0
    16
<<atexit>>---request execution of functions at program exit
sl@0
    17
sl@0
    18
INDEX
sl@0
    19
	atexit
sl@0
    20
sl@0
    21
ANSI_SYNOPSIS
sl@0
    22
	#include <stdlib.h>
sl@0
    23
	int atexit(void (*<[function]>)(void);
sl@0
    24
sl@0
    25
TRAD_SYNOPSIS
sl@0
    26
	#include <stdlib.h>
sl@0
    27
	int atexit((<[function]>)
sl@0
    28
	void (*<[function]>)();
sl@0
    29
sl@0
    30
DESCRIPTION
sl@0
    31
You can use <<atexit>> to enroll functions in a list of functions that
sl@0
    32
will be called when your program terminates normally.  The argument is
sl@0
    33
a pointer to a user-defined function (which must not require arguments and
sl@0
    34
must not return a result).
sl@0
    35
sl@0
    36
The functions are kept in a LIFO stack; that is, the last function
sl@0
    37
enrolled by <<atexit>> will be the first to execute when your program
sl@0
    38
exits.
sl@0
    39
sl@0
    40
There is no built-in limit to the number of functions you can enroll
sl@0
    41
in this list; however, after every group of 32 functions is enrolled,
sl@0
    42
<<atexit>> will call <<malloc>> to get space for the next part of the
sl@0
    43
list.   The initial list of 32 functions is statically allocated, so
sl@0
    44
you can always count on at least that many slots available.
sl@0
    45
sl@0
    46
RETURNS
sl@0
    47
<<atexit>> returns <<0>> if it succeeds in enrolling your function,
sl@0
    48
<<-1>> if it fails (possible only if no space was available for
sl@0
    49
<<malloc>> to extend the list of functions or the library globals could not
sl@0
    50
be allocated).
sl@0
    51
sl@0
    52
PORTABILITY
sl@0
    53
<<atexit>> is required by the ANSI standard, which also specifies that
sl@0
    54
implementations must support enrolling at least 32 functions.
sl@0
    55
sl@0
    56
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
sl@0
    57
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
sl@0
    58
*/
sl@0
    59
sl@0
    60
#include <stddef.h>
sl@0
    61
#include <stdlib.h>
sl@0
    62
#include <reent.h>
sl@0
    63
sl@0
    64
/*
sl@0
    65
 * Register a function to be performed at exit.
sl@0
    66
 * NB. MSVC 5.0 has a built-in prototype for atexit, so we have to use a #define
sl@0
    67
 * to map the name atexit to _epoc32_atexit
sl@0
    68
 */
sl@0
    69
sl@0
    70
/*
sl@0
    71
@return On Success, returns 0.
sl@0
    72
		On Failure, returns -1.
sl@0
    73
*/
sl@0
    74
sl@0
    75
EXPORT_C int
sl@0
    76
_epoc32_atexit (void (*fn)(void))
sl@0
    77
{
sl@0
    78
  register struct _atexit *p;
sl@0
    79
  struct _reent *rp = _REENT2;
sl@0
    80
  if (!rp)
sl@0
    81
	return -1; // Memory for library globals is not allocated (errno not set). 
sl@0
    82
 
sl@0
    83
  if ((p = rp->_atexit) == NULL)
sl@0
    84
    rp->_atexit = p = &rp->_atexit0;
sl@0
    85
  if (p->_ind >= _ATEXIT_SIZE)
sl@0
    86
    {
sl@0
    87
      if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
sl@0
    88
		return -1;
sl@0
    89
      p->_ind = 0;
sl@0
    90
      p->_next = rp->_atexit;
sl@0
    91
      rp->_atexit = p;
sl@0
    92
    }
sl@0
    93
  p->_fns[p->_ind++] = fn;
sl@0
    94
  return 0;
sl@0
    95
}
sl@0
    96
sl@0
    97
EXPORT_C void 
sl@0
    98
_atexit_processing_r (struct _reent *rp)
sl@0
    99
{
sl@0
   100
  register struct _atexit *p;
sl@0
   101
  register int n;
sl@0
   102
sl@0
   103
  for (p = rp->_atexit; p; p = p->_next)
sl@0
   104
    for (n = p->_ind; --n >= 0;)
sl@0
   105
      (*p->_fns[n]) ();
sl@0
   106
  if (rp->__cleanup)
sl@0
   107
    (*rp->__cleanup) (rp);
sl@0
   108
}