]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/test/setjmp/tst-vfork-longjmp.c
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / test / setjmp / tst-vfork-longjmp.c
1 /* make sure we can vfork/exec across setjmp/longjmp's
2  * and make sure signal block masks don't get corrupted
3  * in the process.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 #include <unistd.h>
10 #include <errno.h>
11 #include <setjmp.h>
12 #include <signal.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <string.h>
16
17 int verbose = 0;
18
19 static int execute_child(const char *prog)
20 {
21         int status;
22         pid_t child;
23         child = vfork();
24         if (child == 0) {
25                 execlp(prog, prog, NULL);
26                 perror("Could not execute specified prog");
27                 _exit(1);
28         } else if (child == 1)
29                 return 1;
30         wait(&status);
31         return WEXITSTATUS(status);
32 }
33
34 sigset_t orig_mask;
35
36 static int check_sig_mask(void)
37 {
38         int status;
39         pid_t child;
40
41         child = vfork();
42         if (child == 0) {
43                 int ret;
44                 sigset_t child_mask;
45                 memset(&child_mask, 0x00, sizeof(child_mask));
46                 ret = sigprocmask(SIG_BLOCK, NULL, &child_mask);
47                 if (ret != 0) {
48                         perror("could not get child sig block mask");
49                         _exit(1);
50                 }
51                 ret = memcmp(&orig_mask, &child_mask, sizeof(orig_mask));
52                 if (verbose) {
53                         printf("sigmsk: %08lx%08lx ", child_mask.__val[1], child_mask.__val[0]);
54                         printf("sigmsk: %08lx%08lx ", orig_mask.__val[1], orig_mask.__val[0]);
55                         printf("%i\n", ret);
56                 }
57                 _exit(ret);
58         } else if (child == 1)
59                 return 1;
60         wait(&status);
61         return WEXITSTATUS(status);
62 }
63
64 int main(int argc, char *argv[])
65 {
66         const char *prog;
67         jmp_buf env;
68         sigjmp_buf sigenv;
69         int max;
70         /* values modified between setjmp/longjmp cannot be local to this func */
71         static int cnt, ret;
72
73         memset(&orig_mask, 0x00, sizeof(orig_mask));
74         ret = sigprocmask(SIG_BLOCK, NULL, &orig_mask);
75         if (ret != 0) {
76                 perror("could not get orig sig block mask");
77                 return 1;
78         }
79
80         prog = (argc > 1 ? argv[1] : "true");
81         ret = 0;
82         verbose = 0;
83         max = 10;
84
85         /* test vfork()/exec() inside of sigsetjmp/siglongjmp */
86         cnt = 0;
87         sigsetjmp(sigenv, 1);
88         ++cnt;
89         if (verbose)
90                 printf("sigsetjmp loop %i\n", cnt);
91         ret |= check_sig_mask();
92         ret |= execute_child(prog);
93         if (cnt < max)
94                 siglongjmp(sigenv, 0);
95
96         /* test vfork()/sigprocmask() inside of setjmp/longjmp */
97         cnt = 0;
98         setjmp(env);
99         ++cnt;
100         if (verbose)
101                 printf("setjmp loop %i\n", cnt);
102         ret |= check_sig_mask();
103         ret |= execute_child(prog);
104         if (cnt < max)
105                 longjmp(env, 0);
106
107         return ret;
108 }