(root)/
glibc-2.38/
sysdeps/
pthread/
tst-atfork2.c
       1  /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
       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
       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.
       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
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <dlfcn.h>
      19  #include <errno.h>
      20  #include <mcheck.h>
      21  #include <pthread.h>
      22  #include <stdio.h>
      23  #include <stdlib.h>
      24  #include <unistd.h>
      25  #include <sys/wait.h>
      26  
      27  
      28  /* Must be exported.  */
      29  int val;
      30  
      31  static void
      32  prepare (void)
      33  {
      34    val *= 2;
      35  }
      36  
      37  static void
      38  parent (void)
      39  {
      40    val += 4;
      41  }
      42  
      43  static void
      44  child (void)
      45  {
      46    val += 8;
      47  }
      48  
      49  
      50  static int
      51  do_test (void)
      52  {
      53    mtrace ();
      54  
      55    if (pthread_atfork (prepare, parent, child) != 0)
      56      {
      57        puts ("do_test: atfork failed");
      58        exit (1);
      59      }
      60  
      61    void *h = dlopen ("tst-atfork2mod.so", RTLD_LAZY);
      62    if (h == NULL)
      63      {
      64        printf ("dlopen failed: %s\n", dlerror ());
      65        exit (1);
      66      }
      67  
      68    /* First trial of fork.  */
      69    pid_t pid = fork ();
      70    if (pid == -1)
      71      {
      72        puts ("1st fork failed");
      73        exit (1);
      74      }
      75  
      76    if (pid == 0)
      77      {
      78        /* Child.  */
      79        if (val != 80)
      80  	{
      81  	  printf ("1st: expected val=%d, got %d\n", 80, val);
      82  	  exit (2);
      83  	}
      84  
      85        exit (0);
      86      }
      87  
      88    /* Parent.  */
      89    if (val != 24)
      90      {
      91        printf ("1st: expected val=%d, got %d\n", 24, val);
      92        exit (1);
      93      }
      94  
      95    int status;
      96    if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
      97      {
      98        puts ("1st waitpid failed");
      99        exit (1);
     100      }
     101  
     102    if (status != 0)
     103      exit (status);
     104  
     105    puts ("unloading now");
     106  
     107    /* Unload the module.  */
     108    if (dlclose (h) != 0)
     109      {
     110        puts ("dlclose failed");
     111        exit (1);
     112      }
     113  
     114    puts ("2nd fork");
     115  
     116    /* Second fork trial.   */
     117    val = 1;
     118    pid = fork ();
     119    if (pid == -1)
     120      {
     121        puts ("2nd fork failed");
     122        exit (1);
     123      }
     124  
     125    if (pid == 0)
     126      {
     127        /* Child.  */
     128        if (val != 10)
     129  	{
     130  	  printf ("2nd: expected val=%d, got %d\n", 10, val);
     131  	  exit (3);
     132  	}
     133  
     134        exit (0);
     135      }
     136  
     137    /* Parent.  */
     138    if (val != 6)
     139      {
     140        printf ("2nd: expected val=%d, got %d\n", 6, val);
     141        exit (1);
     142      }
     143  
     144    if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
     145      {
     146        puts ("2nd waitpid failed");
     147        exit (1);
     148      }
     149  
     150    if (status != 0)
     151      exit (status);
     152  
     153    return 0;
     154  }
     155  
     156  #define TEST_FUNCTION do_test ()
     157  #include "../test-skeleton.c"