Blame


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