(root)/
glibc-2.38/
sysdeps/
pthread/
tst-fork1.c
       1  /* Copyright (C) 2002-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 <errno.h>
      19  #include <pthread.h>
      20  #include <stdio.h>
      21  #include <stdlib.h>
      22  #include <string.h>
      23  #include <unistd.h>
      24  #include <sys/wait.h>
      25  
      26  static void *
      27  thread_function (void * arg)
      28  {
      29    int i = (intptr_t) arg;
      30    int status;
      31    pid_t pid;
      32    pid_t pid2;
      33  
      34    pid = fork ();
      35    switch (pid)
      36      {
      37      case 0:
      38        printf ("%ld for %d\n", (long int) getpid (), i);
      39        struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 * i };
      40        nanosleep (&ts, NULL);
      41        _exit (i);
      42        break;
      43      case -1:
      44        printf ("fork: %m\n");
      45        return (void *) 1l;
      46        break;
      47      }
      48  
      49    pid2 = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
      50    if (pid2 != pid)
      51      {
      52        printf ("waitpid returned %ld, expected %ld\n",
      53  	      (long int) pid2, (long int) pid);
      54        return (void *) 1l;
      55      }
      56  
      57    printf ("%ld with %d, expected %d\n",
      58  	  (long int) pid, WEXITSTATUS (status), i);
      59  
      60    return WEXITSTATUS (status) == i ? NULL : (void *) 1l;
      61  }
      62  
      63  #define N 5
      64  static const int t[N] = { 7, 6, 5, 4, 3 };
      65  
      66  static int
      67  do_test (void)
      68  {
      69    pthread_t th[N];
      70    int i;
      71    int result = 0;
      72    pthread_attr_t at;
      73  
      74    if (pthread_attr_init (&at) != 0)
      75      {
      76        puts ("attr_init failed");
      77        return 1;
      78      }
      79  
      80    if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0)
      81      {
      82        puts ("attr_setstacksize failed");
      83        return 1;
      84      }
      85  
      86    for (i = 0; i < N; ++i)
      87      if (pthread_create (&th[i], NULL, thread_function,
      88  			(void *) (intptr_t) t[i]) != 0)
      89        {
      90  	printf ("creation of thread %d failed\n", i);
      91  	exit (1);
      92        }
      93  
      94    if (pthread_attr_destroy (&at) != 0)
      95      {
      96        puts ("attr_destroy failed");
      97        return 1;
      98      }
      99  
     100    for (i = 0; i < N; ++i)
     101      {
     102        void *v;
     103        if (pthread_join (th[i], &v) != 0)
     104  	{
     105  	  printf ("join of thread %d failed\n", i);
     106  	  result = 1;
     107  	}
     108        else if (v != NULL)
     109  	{
     110  	  printf ("join %d successful, but child failed\n", i);
     111  	  result = 1;
     112  	}
     113        else
     114  	printf ("join %d successful\n", i);
     115      }
     116  
     117    return result;
     118  }
     119  
     120  #include <support/test-driver.c>