blob: 99a087fd44804e71781d51a329fced7e5ede6638 [file] [log] [blame]
sewardj2cb00342002-06-28 01:46:26 +00001/* Tests for fork in multi-threaded environment.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20#include <errno.h>
sewardj6e9de462011-06-28 07:25:29 +000021#if !defined(__APPLE__)
sewardj4bdd5052006-10-17 01:28:48 +000022# include <error.h>
23#endif
sewardj2cb00342002-06-28 01:46:26 +000024#include <stdlib.h>
25#include <pthread.h>
26#include <unistd.h>
27#include <sys/wait.h>
28#include <stdio.h>
29
sewardj6e9de462011-06-28 07:25:29 +000030#if defined(__APPLE__)
sewardj4bdd5052006-10-17 01:28:48 +000031#include <string.h> /* strerror */
32static void error (int status, int errnum, char* msg)
33{
34 fprintf(stderr, "%s%s%s\n",
35 msg,
36 errnum ? ": " : "",
37 errnum ? strerror(errnum) : "");
38 if (errnum)
39 exit(errnum);
40}
41#endif
42
sewardj2cb00342002-06-28 01:46:26 +000043enum
44{
45 PREPARE_BIT = 1,
46 PARENT_BIT = 2,
47 CHILD_BIT = 4
48};
49
50static int var;
51
52static void
53prepare (void)
54{
sewardj2cb00342002-06-28 01:46:26 +000055 var |= PREPARE_BIT;
56}
57
58static void
59parent (void)
60{
sewardj2cb00342002-06-28 01:46:26 +000061 var |= PARENT_BIT;
62}
63
64static void
65child (void)
66{
sewardj2cb00342002-06-28 01:46:26 +000067 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
daywalker9e625b82003-05-05 11:04:37 +000087 if ( ( int ) ( long int ) res != 0 )
88 error(EXIT_FAILURE, 0, "pthread_join res != 0" );
89
90 printf ( "all ok\n" );
91 return 0;
sewardj2cb00342002-06-28 01:46:26 +000092}
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}