OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / libpthread / linuxthreads / sysdeps / unix / sysv / linux / register-atfork.c
1 /* Copyright (C) 2002 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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <errno.h>
20 #include <stdlib.h>
21 #include "fork.h"
22
23
24 int
25 __register_atfork (prepare, parent, child, dso_handle)
26      void (*prepare) (void);
27      void (*parent) (void);
28      void (*child) (void);
29      void *dso_handle;
30 {
31   struct fork_handler *new_prepare = NULL;
32   struct fork_handler *new_parent = NULL;
33   struct fork_handler *new_child = NULL;
34
35   if (prepare != NULL)
36     {
37       new_prepare = (struct fork_handler *) malloc (sizeof (*new_prepare));
38       if (new_prepare == NULL)
39         goto out1;
40
41       new_prepare->handler = prepare;
42       new_prepare->dso_handle = dso_handle;
43     }
44
45   if (parent != NULL)
46     {
47       new_parent = (struct fork_handler *) malloc (sizeof (*new_parent));
48       if (new_parent == NULL)
49         goto out2;
50
51       new_parent->handler = parent;
52       new_parent->dso_handle = dso_handle;
53     }
54
55   if (child != NULL)
56     {
57       new_child = (struct fork_handler *) malloc (sizeof (*new_child));
58       if (new_child == NULL)
59         {
60           free (new_parent);
61         out2:
62           free (new_prepare);
63         out1:
64           return errno;
65         }
66
67       new_child->handler = child;
68       new_child->dso_handle = dso_handle;
69     }
70
71   /* Get the lock to not conflict with running forks.  */
72   __libc_lock_lock (__fork_block.lock);
73
74   /* Now that we have all the handlers allocate enqueue them.  */
75   if (new_prepare != NULL)
76     list_add_tail (&new_prepare->list, &__fork_block.prepare_list);
77   if (new_parent != NULL)
78     list_add_tail (&new_parent->list, &__fork_block.parent_list);
79   if (new_child != NULL)
80     list_add_tail (&new_child->list, &__fork_block.child_list);
81
82   /* Release the lock.  */
83   __libc_lock_unlock (__fork_block.lock);
84
85   return 0;
86 }