Back to index

glibc  2.9
register-atfork.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <stdlib.h>
00022 #include "fork.h"
00023 
00024 
00025 int
00026 __register_atfork (prepare, parent, child, dso_handle)
00027      void (*prepare) (void);
00028      void (*parent) (void);
00029      void (*child) (void);
00030      void *dso_handle;
00031 {
00032   struct fork_handler *new_prepare = NULL;
00033   struct fork_handler *new_parent = NULL;
00034   struct fork_handler *new_child = NULL;
00035 
00036   if (prepare != NULL)
00037     {
00038       new_prepare = (struct fork_handler *) malloc (sizeof (*new_prepare));
00039       if (new_prepare == NULL)
00040        goto out1;
00041 
00042       new_prepare->handler = prepare;
00043       new_prepare->dso_handle = dso_handle;
00044     }
00045 
00046   if (parent != NULL)
00047     {
00048       new_parent = (struct fork_handler *) malloc (sizeof (*new_parent));
00049       if (new_parent == NULL)
00050        goto out2;
00051 
00052       new_parent->handler = parent;
00053       new_parent->dso_handle = dso_handle;
00054     }
00055 
00056   if (child != NULL)
00057     {
00058       new_child = (struct fork_handler *) malloc (sizeof (*new_child));
00059       if (new_child == NULL)
00060        {
00061          free (new_parent);
00062        out2:
00063          free (new_prepare);
00064        out1:
00065          return errno;
00066        }
00067 
00068       new_child->handler = child;
00069       new_child->dso_handle = dso_handle;
00070     }
00071 
00072   /* Get the lock to not conflict with running forks.  */
00073   __libc_lock_lock (__fork_block.lock);
00074 
00075   /* Now that we have all the handlers allocate enqueue them.  */
00076   if (new_prepare != NULL)
00077     list_add_tail (&new_prepare->list, &__fork_block.prepare_list);
00078   if (new_parent != NULL)
00079     list_add_tail (&new_parent->list, &__fork_block.parent_list);
00080   if (new_child != NULL)
00081     list_add_tail (&new_child->list, &__fork_block.child_list);
00082 
00083   /* Release the lock.  */
00084   __libc_lock_unlock (__fork_block.lock);
00085 
00086   return 0;
00087 }
00088 libc_hidden_def (__register_atfork)