Back to index

glibc  2.9
tst-atfork2.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
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 <dlfcn.h>
00021 #include <errno.h>
00022 #include <mcheck.h>
00023 #include <pthread.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <unistd.h>
00027 #include <sys/wait.h>
00028 
00029 
00030 /* Must be exported.  */
00031 int val;
00032 
00033 static void
00034 prepare (void)
00035 {
00036   val *= 2;
00037 }
00038 
00039 static void
00040 parent (void)
00041 {
00042   val += 4;
00043 }
00044 
00045 static void
00046 child (void)
00047 {
00048   val += 8;
00049 }
00050 
00051 
00052 static int
00053 do_test (void)
00054 {
00055   mtrace ();
00056 
00057   if (pthread_atfork (prepare, parent, child) != 0)
00058     {
00059       puts ("do_test: atfork failed");
00060       exit (1);
00061     }
00062 
00063   void *h = dlopen ("tst-atfork2mod.so", RTLD_LAZY);
00064   if (h == NULL)
00065     {
00066       printf ("dlopen failed: %s\n", dlerror ());
00067       exit (1);
00068     }
00069 
00070   /* First trial of fork.  */
00071   pid_t pid = fork ();
00072   if (pid == -1)
00073     {
00074       puts ("1st fork failed");
00075       exit (1);
00076     }
00077 
00078   if (pid == 0)
00079     {
00080       /* Child.  */
00081       if (val != 80)
00082        {
00083          printf ("1st: expected val=%d, got %d\n", 80, val);
00084          exit (2);
00085        }
00086 
00087       exit (0);
00088     }
00089 
00090   /* Parent.  */
00091   if (val != 24)
00092     {
00093       printf ("1st: expected val=%d, got %d\n", 24, val);
00094       exit (1);
00095     }
00096 
00097   int status;
00098   if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
00099     {
00100       puts ("1st waitpid failed");
00101       exit (1);
00102     }
00103 
00104   if (status != 0)
00105     exit (status);
00106 
00107   puts ("unloading now");
00108 
00109   /* Unload the module.  */
00110   if (dlclose (h) != 0)
00111     {
00112       puts ("dlclose failed");
00113       exit (1);
00114     }
00115 
00116   puts ("2nd fork");
00117 
00118   /* Second fork trial.   */
00119   val = 1;
00120   pid = fork ();
00121   if (pid == -1)
00122     {
00123       puts ("2nd fork failed");
00124       exit (1);
00125     }
00126 
00127   if (pid == 0)
00128     {
00129       /* Child.  */
00130       if (val != 10)
00131        {
00132          printf ("2nd: expected val=%d, got %d\n", 10, val);
00133          exit (3);
00134        }
00135 
00136       exit (0);
00137     }
00138 
00139   /* Parent.  */
00140   if (val != 6)
00141     {
00142       printf ("2nd: expected val=%d, got %d\n", 6, val);
00143       exit (1);
00144     }
00145 
00146   if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
00147     {
00148       puts ("2nd waitpid failed");
00149       exit (1);
00150     }
00151 
00152   if (status != 0)
00153     exit (status);
00154 
00155   return 0;
00156 }
00157 
00158 #define TEST_FUNCTION do_test ()
00159 #include "../test-skeleton.c"