1 #include <sched.h>
2 #include <signal.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <stackinfo.h>
9 
10 #ifndef TEST_CLONE_FLAGS
11 #define TEST_CLONE_FLAGS 0
12 #endif
13 
14 static int sig;
15 
16 static int
f(void * a)17 f (void *a)
18 {
19   puts ("in f");
20   union sigval sival;
21   sival.sival_int = getpid ();
22   printf ("pid = %d\n", sival.sival_int);
23   if (sigqueue (getppid (), sig, sival) != 0)
24     return 1;
25   return 0;
26 }
27 
28 
29 static int
do_test(void)30 do_test (void)
31 {
32   int mypid = getpid ();
33 
34   sig = SIGRTMIN;
35   sigset_t ss;
36   sigemptyset (&ss);
37   sigaddset (&ss, sig);
38   if (sigprocmask (SIG_BLOCK, &ss, NULL) != 0)
39     {
40       printf ("sigprocmask failed: %m\n");
41       return 1;
42     }
43 
44 #ifdef __ia64__
45   extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base,
46 		       size_t __child_stack_size, int __flags,
47 		       void *__arg, ...);
48   char st[256 * 1024] __attribute__ ((aligned));
49   pid_t p = __clone2 (f, st, sizeof (st), TEST_CLONE_FLAGS, 0);
50 #else
51   char st[128 * 1024] __attribute__ ((aligned));
52 # if _STACK_GROWS_DOWN
53   pid_t p = clone (f, st + sizeof (st), TEST_CLONE_FLAGS, 0);
54 # elif _STACK_GROWS_UP
55   pid_t p = clone (f, st, TEST_CLONE_FLAGS, 0);
56 # else
57 #  error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
58 # endif
59 #endif
60   if (p == -1)
61     {
62       printf("clone failed: %m\n");
63       return 1;
64     }
65   printf ("new thread: %d\n", (int) p);
66 
67   siginfo_t si;
68   do
69     if (sigwaitinfo (&ss, &si) < 0)
70       {
71 	printf("sigwaitinfo failed: %m\n");
72 	kill (p, SIGKILL);
73 	return 1;
74       }
75   while  (si.si_signo != sig || si.si_code != SI_QUEUE);
76 
77   int e;
78   if (waitpid (p, &e, __WCLONE) != p)
79     {
80       puts ("waitpid failed");
81       kill (p, SIGKILL);
82       return 1;
83     }
84   if (!WIFEXITED (e))
85     {
86       if (WIFSIGNALED (e))
87 	printf ("died from signal %s\n", strsignal (WTERMSIG (e)));
88       else
89 	puts ("did not terminate correctly");
90       return 1;
91     }
92   if (WEXITSTATUS (e) != 0)
93     {
94       printf ("exit code %d\n", WEXITSTATUS (e));
95       return 1;
96     }
97 
98   if (si.si_int != (int) p)
99     {
100       printf ("expected PID %d, got si_int %d\n", (int) p, si.si_int);
101       kill (p, SIGKILL);
102       return 1;
103     }
104 
105   if (si.si_pid != p)
106     {
107       printf ("expected PID %d, got si_pid %d\n", (int) p, (int) si.si_pid);
108       kill (p, SIGKILL);
109       return 1;
110     }
111 
112   if (getpid () != mypid)
113     {
114       puts ("my PID changed");
115       return 1;
116     }
117 
118   return 0;
119 }
120 
121 #define TEST_FUNCTION do_test ()
122 #include "../test-skeleton.c"
123