(__unregister_atfork): Don't free memory not allocated dynamically.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / unregister-atfork.c
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <errno.h>
21 #include <stdlib.h>
22 #include "fork.h"
23
24
25 /* Defined in libc_pthread_init.c.  */
26 extern struct fork_handler __pthread_child_handler attribute_hidden;
27 /* Three static memory blocks used when registering malloc.  */
28 static struct fork_handler malloc_prepare;
29 static struct fork_handler malloc_parent;
30 static struct fork_handler malloc_child;
31
32
33 void
34 __unregister_atfork (dso_handle)
35      void *dso_handle;
36 {
37   /* Get the lock to not conflict with running forks.  */
38   lll_lock (__fork_lock);
39
40   list_t *runp;
41   list_t *prevp;
42
43   list_for_each_prev_safe (runp, prevp, &__fork_prepare_list)
44     if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
45       {
46         list_del (runp);
47
48         struct fork_handler *p = list_entry (runp, struct fork_handler, list);
49         if (p != &malloc_prepare)
50           free (p);
51       }
52
53   list_for_each_prev_safe (runp, prevp, &__fork_parent_list)
54     if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
55       {
56         list_del (runp);
57
58         struct fork_handler *p = list_entry (runp, struct fork_handler, list);
59         if (p != &malloc_parent)
60           free (p);
61       }
62
63   list_for_each_prev_safe (runp, prevp, &__fork_child_list)
64     if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
65       {
66         list_del (runp);
67
68         struct fork_handler *p = list_entry (runp, struct fork_handler, list);
69         if (p != &__pthread_child_handler && p != &malloc_child)
70           free (p);
71       }
72
73   /* Release the lock.  */
74   lll_unlock (__fork_lock);
75 }