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