Blame


1 1544f909 2004-12-25 devnull #include "threadimpl.h"
2 1544f909 2004-12-25 devnull
3 1544f909 2004-12-25 devnull static Lock thewaitlock;
4 1544f909 2004-12-25 devnull static Channel *thewaitchan;
5 1544f909 2004-12-25 devnull
6 1544f909 2004-12-25 devnull static void
7 8cbd854a 2004-12-27 devnull execproc(void *v)
8 955a2ca7 2004-12-27 devnull {
9 8cbd854a 2004-12-27 devnull int pid;
10 1544f909 2004-12-25 devnull Channel *c;
11 8cbd854a 2004-12-27 devnull Execjob *e;
12 1544f909 2004-12-25 devnull Waitmsg *w;
13 1544f909 2004-12-25 devnull
14 8cbd854a 2004-12-27 devnull e = v;
15 9e4b56e7 2012-10-22 rsc pid = _threadspawn(e->fd, e->cmd, e->argv, e->dir);
16 8cbd854a 2004-12-27 devnull sendul(e->c, pid);
17 8cbd854a 2004-12-27 devnull if(pid > 0){
18 8cbd854a 2004-12-27 devnull w = waitfor(pid);
19 1544f909 2004-12-25 devnull if((c = thewaitchan) != nil)
20 1544f909 2004-12-25 devnull sendp(c, w);
21 1544f909 2004-12-25 devnull else
22 1544f909 2004-12-25 devnull free(w);
23 1544f909 2004-12-25 devnull }
24 8cbd854a 2004-12-27 devnull threadexits(nil);
25 1544f909 2004-12-25 devnull }
26 1544f909 2004-12-25 devnull
27 8cbd854a 2004-12-27 devnull int
28 9e4b56e7 2012-10-22 rsc _runthreadspawn(int *fd, char *cmd, char **argv, char *dir)
29 8cbd854a 2004-12-27 devnull {
30 8cbd854a 2004-12-27 devnull int pid;
31 8cbd854a 2004-12-27 devnull Execjob e;
32 8cbd854a 2004-12-27 devnull
33 8cbd854a 2004-12-27 devnull e.fd = fd;
34 8cbd854a 2004-12-27 devnull e.cmd = cmd;
35 8cbd854a 2004-12-27 devnull e.argv = argv;
36 9e4b56e7 2012-10-22 rsc e.dir = dir;
37 8cbd854a 2004-12-27 devnull e.c = chancreate(sizeof(void*), 0);
38 8cbd854a 2004-12-27 devnull proccreate(execproc, &e, 65536);
39 8cbd854a 2004-12-27 devnull pid = recvul(e.c);
40 8cbd854a 2004-12-27 devnull chanfree(e.c);
41 8cbd854a 2004-12-27 devnull return pid;
42 8cbd854a 2004-12-27 devnull }
43 8cbd854a 2004-12-27 devnull
44 1544f909 2004-12-25 devnull Channel*
45 1544f909 2004-12-25 devnull threadwaitchan(void)
46 1544f909 2004-12-25 devnull {
47 1544f909 2004-12-25 devnull if(thewaitchan)
48 1544f909 2004-12-25 devnull return thewaitchan;
49 1544f909 2004-12-25 devnull lock(&thewaitlock);
50 1544f909 2004-12-25 devnull if(thewaitchan){
51 1544f909 2004-12-25 devnull unlock(&thewaitlock);
52 1544f909 2004-12-25 devnull return thewaitchan;
53 1544f909 2004-12-25 devnull }
54 1544f909 2004-12-25 devnull thewaitchan = chancreate(sizeof(Waitmsg*), 4);
55 1544f909 2004-12-25 devnull chansetname(thewaitchan, "threadwaitchan");
56 1544f909 2004-12-25 devnull unlock(&thewaitlock);
57 1544f909 2004-12-25 devnull return thewaitchan;
58 1544f909 2004-12-25 devnull }
59 1544f909 2004-12-25 devnull
60 1544f909 2004-12-25 devnull int
61 9e4b56e7 2012-10-22 rsc _threadspawn(int fd[3], char *cmd, char *argv[], char *dir)
62 1544f909 2004-12-25 devnull {
63 1544f909 2004-12-25 devnull int i, n, p[2], pid;
64 1544f909 2004-12-25 devnull char exitstr[100];
65 1544f909 2004-12-25 devnull
66 0829f75b 2009-08-18 rsc notifyoff("sys: child"); /* do not let child note kill us */
67 1544f909 2004-12-25 devnull if(pipe(p) < 0)
68 1544f909 2004-12-25 devnull return -1;
69 1544f909 2004-12-25 devnull if(fcntl(p[0], F_SETFD, 1) < 0 || fcntl(p[1], F_SETFD, 1) < 0){
70 1544f909 2004-12-25 devnull close(p[0]);
71 1544f909 2004-12-25 devnull close(p[1]);
72 1544f909 2004-12-25 devnull return -1;
73 1544f909 2004-12-25 devnull }
74 1544f909 2004-12-25 devnull switch(pid = fork()){
75 1544f909 2004-12-25 devnull case -1:
76 1544f909 2004-12-25 devnull close(p[0]);
77 1544f909 2004-12-25 devnull close(p[1]);
78 1544f909 2004-12-25 devnull return -1;
79 1544f909 2004-12-25 devnull case 0:
80 4940b552 2006-02-12 devnull /* can't RFNOTEG - will lose tty */
81 9e4b56e7 2012-10-22 rsc if(dir != nil )
82 9e4b56e7 2012-10-22 rsc chdir(dir); /* best effort */
83 1544f909 2004-12-25 devnull dup2(fd[0], 0);
84 1544f909 2004-12-25 devnull dup2(fd[1], 1);
85 1544f909 2004-12-25 devnull dup2(fd[2], 2);
86 17558fbe 2006-06-04 devnull if(!isatty(0) && !isatty(1) && !isatty(2))
87 17558fbe 2006-06-04 devnull rfork(RFNOTEG);
88 1544f909 2004-12-25 devnull for(i=3; i<100; i++)
89 1544f909 2004-12-25 devnull if(i != p[1])
90 1544f909 2004-12-25 devnull close(i);
91 1544f909 2004-12-25 devnull execvp(cmd, argv);
92 1544f909 2004-12-25 devnull fprint(p[1], "%d", errno);
93 1544f909 2004-12-25 devnull close(p[1]);
94 1544f909 2004-12-25 devnull _exit(0);
95 1544f909 2004-12-25 devnull }
96 1544f909 2004-12-25 devnull
97 1544f909 2004-12-25 devnull close(p[1]);
98 1544f909 2004-12-25 devnull n = read(p[0], exitstr, sizeof exitstr-1);
99 1544f909 2004-12-25 devnull close(p[0]);
100 1544f909 2004-12-25 devnull if(n > 0){ /* exec failed */
101 286f6852 2006-05-12 devnull free(waitfor(pid));
102 1544f909 2004-12-25 devnull exitstr[n] = 0;
103 1544f909 2004-12-25 devnull errno = atoi(exitstr);
104 1544f909 2004-12-25 devnull return -1;
105 1544f909 2004-12-25 devnull }
106 1544f909 2004-12-25 devnull
107 1544f909 2004-12-25 devnull close(fd[0]);
108 1544f909 2004-12-25 devnull if(fd[1] != fd[0])
109 1544f909 2004-12-25 devnull close(fd[1]);
110 1544f909 2004-12-25 devnull if(fd[2] != fd[1] && fd[2] != fd[0])
111 1544f909 2004-12-25 devnull close(fd[2]);
112 1544f909 2004-12-25 devnull return pid;
113 1544f909 2004-12-25 devnull }
114 1544f909 2004-12-25 devnull
115 1544f909 2004-12-25 devnull int
116 e127e40b 2004-12-27 devnull threadspawn(int fd[3], char *cmd, char *argv[])
117 e127e40b 2004-12-27 devnull {
118 9e4b56e7 2012-10-22 rsc return _runthreadspawn(fd, cmd, argv, nil);
119 e127e40b 2004-12-27 devnull }
120 e127e40b 2004-12-27 devnull
121 e127e40b 2004-12-27 devnull int
122 9e4b56e7 2012-10-22 rsc threadspawnd(int fd[3], char *cmd, char *argv[], char *dir)
123 9e4b56e7 2012-10-22 rsc {
124 9e4b56e7 2012-10-22 rsc return _runthreadspawn(fd, cmd, argv, dir);
125 9e4b56e7 2012-10-22 rsc }
126 9e4b56e7 2012-10-22 rsc
127 9e4b56e7 2012-10-22 rsc int
128 3d867865 2005-01-18 devnull threadspawnl(int fd[3], char *cmd, ...)
129 3d867865 2005-01-18 devnull {
130 3d867865 2005-01-18 devnull char **argv, *s;
131 3d867865 2005-01-18 devnull int n, pid;
132 3d867865 2005-01-18 devnull va_list arg;
133 3d867865 2005-01-18 devnull
134 3d867865 2005-01-18 devnull va_start(arg, cmd);
135 3d867865 2005-01-18 devnull for(n=0; va_arg(arg, char*) != nil; n++)
136 3d867865 2005-01-18 devnull ;
137 3d867865 2005-01-18 devnull n++;
138 3d867865 2005-01-18 devnull va_end(arg);
139 3d867865 2005-01-18 devnull
140 3d867865 2005-01-18 devnull argv = malloc(n*sizeof(argv[0]));
141 3d867865 2005-01-18 devnull if(argv == nil)
142 3d867865 2005-01-18 devnull return -1;
143 3d867865 2005-01-18 devnull
144 3d867865 2005-01-18 devnull va_start(arg, cmd);
145 3d867865 2005-01-18 devnull for(n=0; (s=va_arg(arg, char*)) != nil; n++)
146 3d867865 2005-01-18 devnull argv[n] = s;
147 3d867865 2005-01-18 devnull argv[n] = 0;
148 3d867865 2005-01-18 devnull va_end(arg);
149 3d867865 2005-01-18 devnull
150 3d867865 2005-01-18 devnull pid = threadspawn(fd, cmd, argv);
151 3d867865 2005-01-18 devnull free(argv);
152 3d867865 2005-01-18 devnull return pid;
153 3d867865 2005-01-18 devnull }
154 3d867865 2005-01-18 devnull
155 3d867865 2005-01-18 devnull int
156 1544f909 2004-12-25 devnull _threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[])
157 1544f909 2004-12-25 devnull {
158 1544f909 2004-12-25 devnull int pid;
159 1544f909 2004-12-25 devnull
160 1544f909 2004-12-25 devnull pid = threadspawn(fd, cmd, argv);
161 1544f909 2004-12-25 devnull if(cpid){
162 1544f909 2004-12-25 devnull if(pid < 0)
163 1544f909 2004-12-25 devnull chansendul(cpid, ~0);
164 1544f909 2004-12-25 devnull else
165 1544f909 2004-12-25 devnull chansendul(cpid, pid);
166 1544f909 2004-12-25 devnull }
167 1544f909 2004-12-25 devnull return pid;
168 1544f909 2004-12-25 devnull }
169 1544f909 2004-12-25 devnull
170 1544f909 2004-12-25 devnull void
171 1544f909 2004-12-25 devnull threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[])
172 1544f909 2004-12-25 devnull {
173 1544f909 2004-12-25 devnull if(_threadexec(cpid, fd, cmd, argv) >= 0)
174 1544f909 2004-12-25 devnull threadexits("threadexec");
175 1544f909 2004-12-25 devnull }
176 1544f909 2004-12-25 devnull
177 1544f909 2004-12-25 devnull void
178 1544f909 2004-12-25 devnull threadexecl(Channel *cpid, int fd[3], char *cmd, ...)
179 1544f909 2004-12-25 devnull {
180 1544f909 2004-12-25 devnull char **argv, *s;
181 1544f909 2004-12-25 devnull int n, pid;
182 1544f909 2004-12-25 devnull va_list arg;
183 1544f909 2004-12-25 devnull
184 1544f909 2004-12-25 devnull va_start(arg, cmd);
185 1544f909 2004-12-25 devnull for(n=0; va_arg(arg, char*) != nil; n++)
186 1544f909 2004-12-25 devnull ;
187 1544f909 2004-12-25 devnull n++;
188 1544f909 2004-12-25 devnull va_end(arg);
189 1544f909 2004-12-25 devnull
190 1544f909 2004-12-25 devnull argv = malloc(n*sizeof(argv[0]));
191 1544f909 2004-12-25 devnull if(argv == nil){
192 1544f909 2004-12-25 devnull if(cpid)
193 1544f909 2004-12-25 devnull chansendul(cpid, ~0);
194 1544f909 2004-12-25 devnull return;
195 1544f909 2004-12-25 devnull }
196 1544f909 2004-12-25 devnull
197 1544f909 2004-12-25 devnull va_start(arg, cmd);
198 1544f909 2004-12-25 devnull for(n=0; (s=va_arg(arg, char*)) != nil; n++)
199 1544f909 2004-12-25 devnull argv[n] = s;
200 1544f909 2004-12-25 devnull argv[n] = 0;
201 1544f909 2004-12-25 devnull va_end(arg);
202 1544f909 2004-12-25 devnull
203 1544f909 2004-12-25 devnull pid = _threadexec(cpid, fd, cmd, argv);
204 1544f909 2004-12-25 devnull free(argv);
205 1544f909 2004-12-25 devnull
206 1544f909 2004-12-25 devnull if(pid >= 0)
207 1544f909 2004-12-25 devnull threadexits("threadexecl");
208 1544f909 2004-12-25 devnull }