pth_atfork1.c revision b32f58018498ea2225959b0ba11c18f0c433deef
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* Tests for fork in multi-threaded environment.
2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   Copyright (C) 2000 Free Software Foundation, Inc.
3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   The GNU C Library is free software; you can redistribute it and/or
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   modify it under the terms of the GNU Library General Public License as
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)   published by the Free Software Foundation; either version 2 of the
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   License, or (at your option) any later version.
9c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)   The GNU C Library is distributed in the hope that it will be useful,
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)   but WITHOUT ANY WARRANTY; without even the implied warranty of
12c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   Library General Public License for more details.
14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   You should have received a copy of the GNU Library General Public
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)   License along with the GNU C Library; see the file COPYING.LIB.  If not,
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)   Boston, MA 02111-1307, USA.  */
190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include <errno.h>
210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#if !defined(__APPLE__)
220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)# include <error.h>
230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#endif
24c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include <stdlib.h>
25c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include <pthread.h>
26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include <unistd.h>
27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include <sys/wait.h>
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <stdio.h>
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(__APPLE__)
310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include <string.h>  /* strerror */
32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstatic void error (int status, int errnum, char* msg)
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch{
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)   fprintf(stderr, "%s%s%s\n",
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           msg,
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           errnum ? ": " : "",
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)           errnum ? strerror(errnum) : "");
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)   if (errnum)
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      exit(errnum);
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)enum
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PREPARE_BIT = 1,
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PARENT_BIT = 2,
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CHILD_BIT = 4
48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstatic int var;
51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)prepare (void)
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles){
55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var |= PREPARE_BIT;
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstatic void
59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochparent (void)
60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch{
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var |= PARENT_BIT;
62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
63
64static void
65child (void)
66{
67  var |= CHILD_BIT;
68}
69
70
71static void *thread (void *arg);
72
73
74int
75main (void)
76{
77  pthread_t th;
78  void *res;
79
80  pthread_atfork (prepare, parent, child);
81
82  if (pthread_create (&th, NULL, thread, NULL) != 0)
83    error (EXIT_FAILURE, 0, "cannot create thread");
84
85  pthread_join (th, &res);
86
87  if ( ( int ) ( long int ) res != 0 )
88      error(EXIT_FAILURE, 0, "pthread_join res != 0" );
89
90  printf ( "all ok\n" );
91  return 0;
92}
93
94
95static void *
96thread (void *arg)
97{
98  int status;
99  pid_t pid;
100
101  pid = fork ();
102  if (pid == 0)
103    {
104      /* We check whether the `prepare' and `child' function ran.  */
105      exit (var != (PREPARE_BIT | CHILD_BIT));
106    }
107  else if (pid == (pid_t) -1)
108    error (EXIT_FAILURE, errno, "cannot fork");
109
110  if (waitpid (pid, &status, 0) != pid)
111    error (EXIT_FAILURE, errno, "wrong child");
112
113  if (WTERMSIG (status) != 0)
114    error (EXIT_FAILURE, 0, "Child terminated incorrectly");
115  status = WEXITSTATUS (status);
116
117  if (status == 0)
118    status = var != (PREPARE_BIT | PARENT_BIT);
119
120  return (void *) (long int) status;
121}
122