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