Back to index

glibc  2.9
tst-fork1.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Roland McGrath <roland@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 <pthread.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <unistd.h>
00026 #include <sys/wait.h>
00027 
00028 static void *
00029 thread_function (void * arg)
00030 {
00031   int i = (intptr_t) arg;
00032   int status;
00033   pid_t pid;
00034   pid_t pid2;
00035 
00036   pid = fork ();
00037   switch (pid)
00038     {
00039     case 0:
00040       printf ("%ld for %d\n", (long int) getpid (), i);
00041       struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 * i };
00042       nanosleep (&ts, NULL);
00043       _exit (i);
00044       break;
00045     case -1:
00046       printf ("fork: %m\n");
00047       return (void *) 1l;
00048       break;
00049     }
00050 
00051   pid2 = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
00052   if (pid2 != pid)
00053     {
00054       printf ("waitpid returned %ld, expected %ld\n",
00055              (long int) pid2, (long int) pid);
00056       return (void *) 1l;
00057     }
00058 
00059   printf ("%ld with %d, expected %d\n",
00060          (long int) pid, WEXITSTATUS (status), i);
00061 
00062   return WEXITSTATUS (status) == i ? NULL : (void *) 1l;
00063 }
00064 
00065 #define N 5
00066 static const int t[N] = { 7, 6, 5, 4, 3 };
00067 
00068 int
00069 main (void)
00070 {
00071   pthread_t th[N];
00072   int i;
00073   int result = 0;
00074   pthread_attr_t at;
00075 
00076   if (pthread_attr_init (&at) != 0)
00077     {
00078       puts ("attr_init failed");
00079       return 1;
00080     }
00081 
00082   if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0)
00083     {
00084       puts ("attr_setstacksize failed");
00085       return 1;
00086     }
00087 
00088   for (i = 0; i < N; ++i)
00089     if (pthread_create (&th[i], NULL, thread_function,
00090                      (void *) (intptr_t) t[i]) != 0)
00091       {
00092        printf ("creation of thread %d failed\n", i);
00093        exit (1);
00094       }
00095 
00096   if (pthread_attr_destroy (&at) != 0)
00097     {
00098       puts ("attr_destroy failed");
00099       return 1;
00100     }
00101 
00102   for (i = 0; i < N; ++i)
00103     {
00104       void *v;
00105       if (pthread_join (th[i], &v) != 0)
00106        {
00107          printf ("join of thread %d failed\n", i);
00108          result = 1;
00109        }
00110       else if (v != NULL)
00111        {
00112          printf ("join %d successful, but child failed\n", i);
00113          result = 1;
00114        }
00115       else
00116        printf ("join %d successful\n", i);
00117     }
00118 
00119   return result;
00120 }