Blob


1 #include "threadimpl.h"
3 #undef pipe
4 #undef wait
6 static int sigpid;
7 static int threadpassfd;
9 static void
10 child(void)
11 {
12 int status, pid;
13 pid = wait(&status);
14 if(pid < 0)
15 fprint(2, "wait: %r\n");
16 else if(WIFEXITED(status))
17 _exit(WEXITSTATUS(status));
18 print("pid %d if %d %d\n", pid, WIFEXITED(status), WEXITSTATUS(status));
19 _exit(97);
20 }
22 static void
23 sigpass(int sig)
24 {
25 if(sig == SIGCHLD)
26 child();
27 else
28 kill(sigpid, sig);
29 }
31 void
32 _threadsetupdaemonize(void)
33 {
34 int i, n, pid;
35 int p[2];
36 char buf[20];
38 sigpid = 1;
40 threadlinklibrary();
42 if(pipe(p) < 0)
43 sysfatal("passer pipe: %r");
45 /* hide these somewhere they won't cause harm */
46 if(dup(p[0], 98) < 0 || dup(p[1], 99) < 0)
47 sysfatal("passer pipe dup: %r");
48 close(p[0]);
49 close(p[1]);
50 p[0] = 98;
51 p[1] = 99;
53 /* close on exec */
54 if(fcntl(p[0], F_SETFD, 1) < 0 || fcntl(p[1], F_SETFD, 1) < 0)
55 sysfatal("passer pipe pipe fcntl: %r");
57 signal(SIGCHLD, sigpass);
58 switch(pid = fork()){
59 case -1:
60 sysfatal("passer fork: %r");
61 default:
62 close(p[1]);
63 break;
64 case 0:
65 signal(SIGCHLD, SIG_DFL);
66 rfork(RFNOTEG);
67 close(p[0]);
68 threadpassfd = p[1];
69 return;
70 }
72 sigpid = pid;
73 for(i=0; i<NSIG; i++){
74 struct sigaction sa;
76 memset(&sa, 0, sizeof sa);
77 sa.sa_handler = sigpass;
78 sa.sa_flags |= SA_RESTART;
79 sigaction(i, &sa, nil);
80 }
82 for(;;){
83 n = read(p[0], buf, sizeof buf-1);
84 if(n == 0) /* program exited */
85 child();
86 if(n > 0)
87 break;
88 print("passer read: %r\n");
89 }
90 buf[n] = 0;
91 _exit(atoi(buf));
92 }
94 void
95 threaddaemonize(void)
96 {
97 if(threadpassfd >= 0){
98 write(threadpassfd, "0", 1);
99 close(threadpassfd);
100 threadpassfd = -1;