Back to index

glibc  2.9
exit.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991,95,96,97,99,2001,2002,2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <unistd.h>
00022 #include <sysdep.h>
00023 #include "exit.h"
00024 
00025 #include "set-hooks.h"
00026 DEFINE_HOOK (__libc_atexit, (void))
00027 
00028 
00029 /* Call all functions registered with `atexit' and `on_exit',
00030    in the reverse of the order in which they were registered
00031    perform stdio cleanup, and terminate program execution with STATUS.  */
00032 void
00033 exit (int status)
00034 {
00035   /* We do it this way to handle recursive calls to exit () made by
00036      the functions registered with `atexit' and `on_exit'. We call
00037      everyone on the list and use the status value in the last
00038      exit (). */
00039   while (__exit_funcs != NULL)
00040     {
00041       struct exit_function_list *old;
00042 
00043       while (__exit_funcs->idx > 0)
00044        {
00045          const struct exit_function *const f =
00046            &__exit_funcs->fns[--__exit_funcs->idx];
00047          switch (f->flavor)
00048            {
00049              void (*atfct) (void);
00050              void (*onfct) (int status, void *arg);
00051              void (*cxafct) (void *arg, int status);
00052 
00053            case ef_free:
00054            case ef_us:
00055              break;
00056            case ef_on:
00057              onfct = f->func.on.fn;
00058 #ifdef PTR_DEMANGLE
00059              PTR_DEMANGLE (onfct);
00060 #endif
00061              onfct (status, f->func.on.arg);
00062              break;
00063            case ef_at:
00064              atfct = f->func.at;
00065 #ifdef PTR_DEMANGLE
00066              PTR_DEMANGLE (atfct);
00067 #endif
00068              atfct ();
00069              break;
00070            case ef_cxa:
00071              cxafct = f->func.cxa.fn;
00072 #ifdef PTR_DEMANGLE
00073              PTR_DEMANGLE (cxafct);
00074 #endif
00075              cxafct (f->func.cxa.arg, status);
00076              break;
00077            }
00078        }
00079 
00080       old = __exit_funcs;
00081       __exit_funcs = __exit_funcs->next;
00082       if (__exit_funcs != NULL)
00083        /* Don't free the last element in the chain, this is the statically
00084           allocate element.  */
00085        free (old);
00086     }
00087 
00088   RUN_HOOK (__libc_atexit, ());
00089 
00090   _exit (status);
00091 }
00092 libc_hidden_def (exit)