]> sourceware.org Git - glibc.git/blame - stdlib/cxa_atexit.c
* stdlib/bits/stdlib.h: New file.
[glibc.git] / stdlib / cxa_atexit.c
CommitLineData
a334319f 1/* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
c41041bc
UD
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
c41041bc
UD
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
c41041bc 13
41bdb6e2
AJ
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
c41041bc 18
0ecb606c 19#include <bits/libc-lock.h>
a334319f 20#include <stdlib.h>
c41041bc
UD
21#include "exit.h"
22
6b87a564
UD
23#undef __cxa_atexit
24
c41041bc
UD
25/* Register a function to be called by exit or when a shared library
26 is unloaded. This function is only called from code generated by
27 the C++ compiler. */
28int
29__cxa_atexit (void (*func) (void *), void *arg, void *d)
30{
31 struct exit_function *new = __new_exitfn ();
32
33 if (new == NULL)
34 return -1;
35
a334319f 36 new->flavor = ef_cxa;
5ef50d00 37 new->func.cxa.fn = (void (*) (void *, int)) func;
c41041bc
UD
38 new->func.cxa.arg = arg;
39 new->func.cxa.dso_handle = d;
40 return 0;
41}
6b87a564 42INTDEF(__cxa_atexit)
c08bc50a
UD
43
44
45/* We change global data, so we need locking. */
46__libc_lock_define_initialized (static, lock)
47
48
49static struct exit_function_list initial;
50struct exit_function_list *__exit_funcs = &initial;
51
52struct exit_function *
53__new_exitfn (void)
54{
55 struct exit_function_list *l;
56 size_t i = 0;
57
58 __libc_lock_lock (lock);
59
a334319f 60 for (l = __exit_funcs; l != NULL; l = l->next)
c08bc50a 61 {
a334319f
UD
62 for (i = 0; i < l->idx; ++i)
63 if (l->fns[i].flavor == ef_free)
c08bc50a 64 break;
a334319f 65 if (i < l->idx)
c08bc50a
UD
66 break;
67
a334319f
UD
68 if (l->idx < sizeof (l->fns) / sizeof (l->fns[0]))
69 {
70 i = l->idx++;
71 break;
72 }
c08bc50a
UD
73 }
74
a334319f 75 if (l == NULL)
c08bc50a 76 {
a334319f
UD
77 l = (struct exit_function_list *)
78 malloc (sizeof (struct exit_function_list));
79 if (l != NULL)
c08bc50a 80 {
a334319f
UD
81 l->next = __exit_funcs;
82 __exit_funcs = l;
c08bc50a 83
a334319f
UD
84 l->idx = 1;
85 i = 0;
c08bc50a
UD
86 }
87 }
88
89 /* Mark entry as used, but we don't know the flavor now. */
a334319f
UD
90 if (l != NULL)
91 l->fns[i].flavor = ef_us;
c08bc50a
UD
92
93 __libc_lock_unlock (lock);
94
a334319f 95 return l == NULL ? NULL : &l->fns[i];
c08bc50a 96}
This page took 0.227244 seconds and 5 git commands to generate.