Blame


1 a0a331aa 2005-01-06 devnull #include <u.h>
2 a0a331aa 2005-01-06 devnull #include <sys/time.h>
3 a0a331aa 2005-01-06 devnull #include <sys/resource.h>
4 ddb664da 2004-12-28 devnull #include "threadimpl.h"
5 ddb664da 2004-12-28 devnull
6 230ead2f 2005-01-04 devnull #undef waitpid
7 ddb664da 2004-12-28 devnull #undef pipe
8 ddb664da 2004-12-28 devnull #undef wait
9 ddb664da 2004-12-28 devnull
10 ddb664da 2004-12-28 devnull static int sigpid;
11 ddb664da 2004-12-28 devnull static int threadpassfd;
12 ddb664da 2004-12-28 devnull
13 ddb664da 2004-12-28 devnull static void
14 ddb664da 2004-12-28 devnull child(void)
15 ddb664da 2004-12-28 devnull {
16 1d2533d0 2004-12-28 devnull int status, pid;
17 a0a331aa 2005-01-06 devnull struct rlimit rl;
18 230ead2f 2005-01-04 devnull
19 230ead2f 2005-01-04 devnull notedisable("sys: child");
20 230ead2f 2005-01-04 devnull pid = waitpid(sigpid, &status, 0);
21 230ead2f 2005-01-04 devnull if(pid < 0){
22 230ead2f 2005-01-04 devnull fprint(2, "%s: wait: %r\n", argv0);
23 230ead2f 2005-01-04 devnull _exit(97);
24 230ead2f 2005-01-04 devnull }
25 230ead2f 2005-01-04 devnull if(WIFEXITED(status))
26 1d2533d0 2004-12-28 devnull _exit(WEXITSTATUS(status));
27 230ead2f 2005-01-04 devnull if(WIFSIGNALED(status)){
28 a0a331aa 2005-01-06 devnull /*
29 a0a331aa 2005-01-06 devnull * Make sure we don't scribble over the nice
30 a0a331aa 2005-01-06 devnull * core file that our child just wrote out.
31 a0a331aa 2005-01-06 devnull */
32 a0a331aa 2005-01-06 devnull rl.rlim_cur = 0;
33 a0a331aa 2005-01-06 devnull rl.rlim_max = 0;
34 a0a331aa 2005-01-06 devnull setrlimit(RLIMIT_CORE, &rl);
35 a0a331aa 2005-01-06 devnull
36 230ead2f 2005-01-04 devnull signal(WTERMSIG(status), SIG_DFL);
37 230ead2f 2005-01-04 devnull raise(WTERMSIG(status));
38 230ead2f 2005-01-04 devnull _exit(98); /* not reached */
39 230ead2f 2005-01-04 devnull }
40 230ead2f 2005-01-04 devnull fprint(2, "%s: wait pid %d status 0x%ux\n", pid, status);
41 230ead2f 2005-01-04 devnull _exit(99);
42 ddb664da 2004-12-28 devnull }
43 ddb664da 2004-12-28 devnull
44 ddb664da 2004-12-28 devnull static void
45 ddb664da 2004-12-28 devnull sigpass(int sig)
46 ddb664da 2004-12-28 devnull {
47 ddb664da 2004-12-28 devnull if(sig == SIGCHLD)
48 ddb664da 2004-12-28 devnull child();
49 ddb664da 2004-12-28 devnull else
50 ddb664da 2004-12-28 devnull kill(sigpid, sig);
51 ddb664da 2004-12-28 devnull }
52 ddb664da 2004-12-28 devnull
53 ddb664da 2004-12-28 devnull void
54 ddb664da 2004-12-28 devnull _threadsetupdaemonize(void)
55 ddb664da 2004-12-28 devnull {
56 ddb664da 2004-12-28 devnull int i, n, pid;
57 ddb664da 2004-12-28 devnull int p[2];
58 ddb664da 2004-12-28 devnull char buf[20];
59 ddb664da 2004-12-28 devnull
60 ddb664da 2004-12-28 devnull sigpid = 1;
61 ddb664da 2004-12-28 devnull
62 ddb664da 2004-12-28 devnull threadlinklibrary();
63 ddb664da 2004-12-28 devnull
64 ddb664da 2004-12-28 devnull if(pipe(p) < 0)
65 ddb664da 2004-12-28 devnull sysfatal("passer pipe: %r");
66 ddb664da 2004-12-28 devnull
67 ddb664da 2004-12-28 devnull /* hide these somewhere they won't cause harm */
68 ddb664da 2004-12-28 devnull if(dup(p[0], 98) < 0 || dup(p[1], 99) < 0)
69 ddb664da 2004-12-28 devnull sysfatal("passer pipe dup: %r");
70 ddb664da 2004-12-28 devnull close(p[0]);
71 ddb664da 2004-12-28 devnull close(p[1]);
72 ddb664da 2004-12-28 devnull p[0] = 98;
73 ddb664da 2004-12-28 devnull p[1] = 99;
74 ddb664da 2004-12-28 devnull
75 ddb664da 2004-12-28 devnull /* close on exec */
76 ddb664da 2004-12-28 devnull if(fcntl(p[0], F_SETFD, 1) < 0 || fcntl(p[1], F_SETFD, 1) < 0)
77 ddb664da 2004-12-28 devnull sysfatal("passer pipe pipe fcntl: %r");
78 ddb664da 2004-12-28 devnull
79 230ead2f 2005-01-04 devnull noteenable("sys: child");
80 1d2533d0 2004-12-28 devnull signal(SIGCHLD, sigpass);
81 ddb664da 2004-12-28 devnull switch(pid = fork()){
82 ddb664da 2004-12-28 devnull case -1:
83 ddb664da 2004-12-28 devnull sysfatal("passer fork: %r");
84 ddb664da 2004-12-28 devnull default:
85 ddb664da 2004-12-28 devnull close(p[1]);
86 ddb664da 2004-12-28 devnull break;
87 ddb664da 2004-12-28 devnull case 0:
88 230ead2f 2005-01-04 devnull for(i=0; i<100; i++) sched_yield();
89 230ead2f 2005-01-04 devnull notedisable("sys: child");
90 1d2533d0 2004-12-28 devnull signal(SIGCHLD, SIG_DFL);
91 ddb664da 2004-12-28 devnull rfork(RFNOTEG);
92 ddb664da 2004-12-28 devnull close(p[0]);
93 ddb664da 2004-12-28 devnull threadpassfd = p[1];
94 ddb664da 2004-12-28 devnull return;
95 ddb664da 2004-12-28 devnull }
96 ddb664da 2004-12-28 devnull
97 ddb664da 2004-12-28 devnull sigpid = pid;
98 ddb664da 2004-12-28 devnull for(i=0; i<NSIG; i++){
99 ddb664da 2004-12-28 devnull struct sigaction sa;
100 ddb664da 2004-12-28 devnull
101 ddb664da 2004-12-28 devnull memset(&sa, 0, sizeof sa);
102 ddb664da 2004-12-28 devnull sa.sa_handler = sigpass;
103 ddb664da 2004-12-28 devnull sa.sa_flags |= SA_RESTART;
104 ddb664da 2004-12-28 devnull sigaction(i, &sa, nil);
105 ddb664da 2004-12-28 devnull }
106 ddb664da 2004-12-28 devnull
107 ddb664da 2004-12-28 devnull for(;;){
108 ddb664da 2004-12-28 devnull n = read(p[0], buf, sizeof buf-1);
109 230ead2f 2005-01-04 devnull if(n == 0){ /* program exited */
110 ddb664da 2004-12-28 devnull child();
111 230ead2f 2005-01-04 devnull }
112 ddb664da 2004-12-28 devnull if(n > 0)
113 ddb664da 2004-12-28 devnull break;
114 d54ead7f 2004-12-28 devnull print("passer read: %r\n");
115 ddb664da 2004-12-28 devnull }
116 ddb664da 2004-12-28 devnull buf[n] = 0;
117 ddb664da 2004-12-28 devnull _exit(atoi(buf));
118 ddb664da 2004-12-28 devnull }
119 ddb664da 2004-12-28 devnull
120 ddb664da 2004-12-28 devnull void
121 230ead2f 2005-01-04 devnull _threaddaemonize(void)
122 ddb664da 2004-12-28 devnull {
123 1d2533d0 2004-12-28 devnull if(threadpassfd >= 0){
124 1d2533d0 2004-12-28 devnull write(threadpassfd, "0", 1);
125 1d2533d0 2004-12-28 devnull close(threadpassfd);
126 1d2533d0 2004-12-28 devnull threadpassfd = -1;
127 1d2533d0 2004-12-28 devnull }
128 ddb664da 2004-12-28 devnull }