Blob


1 #include "mk.h"
2 #include <sys/wait.h>
3 #include <signal.h>
4 #include <sys/stat.h>
5 #include <sys/time.h>
7 char *shell = "/bin/sh";
8 char *shellname = "sh";
10 extern char **environ;
12 static void
13 mkperror(char *s)
14 {
15 fprint(2, "%s: %r\n", s);
16 }
18 void
19 readenv(void)
20 {
21 char **p, *s;
22 Word *w;
24 for(p = environ; *p; p++){
25 s = shname(*p);
26 if(*s == '=') {
27 *s = 0;
28 w = newword(s+1);
29 } else
30 w = newword("");
31 if (symlook(*p, S_INTERNAL, 0))
32 continue;
33 s = strdup(*p);
34 setvar(s, (void *)w);
35 symlook(s, S_EXPORTED, (void*)"")->value = (void*)"";
36 }
37 }
39 /*
40 * done on child side of fork, so parent's env is not affected
41 * and we don't care about freeing memory because we're going
42 * to exec immediately after this.
43 */
44 void
45 exportenv(Envy *e)
46 {
47 int i;
48 char **p;
49 char buf[4096];
51 p = 0;
52 for(i = 0; e->name; e++, i++) {
53 p = (char**) Realloc(p, (i+2)*sizeof(char*));
54 if(e->values)
55 sprint(buf, "%s=%s", e->name, wtos(e->values, IWS));
56 else
57 sprint(buf, "%s=", e->name);
58 p[i] = strdup(buf);
59 }
60 p[i] = 0;
61 environ = p;
62 }
64 int
65 waitfor(char *msg)
66 {
67 int status;
68 int pid;
70 *msg = 0;
71 pid = wait(&status);
72 if(pid > 0) {
73 if(status&0x7f) {
74 if(status&0x80)
75 snprint(msg, ERRMAX, "signal %d, core dumped", status&0x7f);
76 else
77 snprint(msg, ERRMAX, "signal %d", status&0x7f);
78 } else if(status&0xff00)
79 snprint(msg, ERRMAX, "exit(%d)", (status>>8)&0xff);
80 }
81 return pid;
82 }
84 void
85 expunge(int pid, char *msg)
86 {
87 if(strcmp(msg, "interrupt"))
88 kill(pid, SIGINT);
89 else
90 kill(pid, SIGHUP);
91 }
93 int
94 execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
95 {
96 char *p;
97 int tot, n, pid, in[2], out[2];
99 if(buf && pipe(out) < 0){
100 mkperror("pipe");
101 Exit();
103 pid = fork();
104 if(pid < 0){
105 mkperror("mk fork");
106 Exit();
108 if(pid == 0){
109 if(buf)
110 close(out[0]);
111 if(pipe(in) < 0){
112 mkperror("pipe");
113 Exit();
115 pid = fork();
116 if(pid < 0){
117 mkperror("mk fork");
118 Exit();
120 if(pid != 0){
121 dup2(in[0], 0);
122 if(buf){
123 dup2(out[1], 1);
124 close(out[1]);
126 close(in[0]);
127 close(in[1]);
128 if (e)
129 exportenv(e);
130 if(shflags)
131 execl(shell, shellname, shflags, args, 0);
132 else
133 execl(shell, shellname, args, 0);
134 mkperror(shell);
135 _exit(1);
137 close(out[1]);
138 close(in[0]);
139 if(DEBUG(D_EXEC))
140 fprint(1, "starting: %s\n", cmd);
141 p = cmd+strlen(cmd);
142 while(cmd < p){
143 n = write(in[1], cmd, p-cmd);
144 if(n < 0)
145 break;
146 cmd += n;
148 close(in[1]);
149 _exit(0);
151 if(buf){
152 close(out[1]);
153 tot = 0;
154 for(;;){
155 if (buf->current >= buf->end)
156 growbuf(buf);
157 n = read(out[0], buf->current, buf->end-buf->current);
158 if(n <= 0)
159 break;
160 buf->current += n;
161 tot += n;
163 if (tot && buf->current[-1] == '\n')
164 buf->current--;
165 close(out[0]);
167 return pid;
170 int
171 pipecmd(char *cmd, Envy *e, int *fd)
173 int pid, pfd[2];
175 if(DEBUG(D_EXEC))
176 fprint(1, "pipecmd='%s'\n", cmd);/**/
178 if(fd && pipe(pfd) < 0){
179 mkperror("pipe");
180 Exit();
182 pid = fork();
183 if(pid < 0){
184 mkperror("mk fork");
185 Exit();
187 if(pid == 0){
188 if(fd){
189 close(pfd[0]);
190 dup2(pfd[1], 1);
191 close(pfd[1]);
193 if(e)
194 exportenv(e);
195 if(shflags)
196 execl(shell, shellname, shflags, "-c", cmd, 0);
197 else
198 execl(shell, shellname, "-c", cmd, 0);
199 mkperror(shell);
200 _exit(1);
202 if(fd){
203 close(pfd[1]);
204 *fd = pfd[0];
206 return pid;
209 void
210 Exit(void)
212 while(wait(0) >= 0)
214 exits("error");
217 static struct
219 int sig;
220 char *msg;
221 } sigmsgs[] =
223 SIGALRM, "alarm",
224 SIGFPE, "sys: fp: fptrap",
225 SIGPIPE, "sys: write on closed pipe",
226 SIGILL, "sys: trap: illegal instruction",
227 SIGSEGV, "sys: segmentation violation",
228 0, 0
229 };
231 static void
232 notifyf(int sig)
234 int i;
236 for(i = 0; sigmsgs[i].msg; i++)
237 if(sigmsgs[i].sig == sig)
238 killchildren(sigmsgs[i].msg);
240 /* should never happen */
241 signal(sig, SIG_DFL);
242 kill(getpid(), sig);
245 void
246 catchnotes()
248 int i;
250 for(i = 0; sigmsgs[i].msg; i++)
251 signal(sigmsgs[i].sig, notifyf);
254 char*
255 maketmp(int *pfd)
257 static char temp[] = "/tmp/mkargXXXXXX";
258 static char buf[100];
259 int fd;
261 strcpy(buf, temp);
262 fd = mkstemp(buf);
263 if(fd < 0)
264 return 0;
265 *pfd = fd;
266 return buf;
269 int
270 chgtime(char *name)
272 if(access(name, 0) >= 0)
273 return utimes(name, 0);
274 return close(creat(name, 0666));
277 void
278 rcopy(char **to, Resub *match, int n)
280 int c;
281 char *p;
283 *to = match->s.sp; /* stem0 matches complete target */
284 for(to++, match++; --n > 0; to++, match++){
285 if(match->s.sp && match->e.ep){
286 p = match->e.ep;
287 c = *p;
288 *p = 0;
289 *to = strdup(match->s.sp);
290 *p = c;
292 else
293 *to = 0;
297 ulong
298 mkmtime(char *name)
300 struct stat st;
302 if(stat(name, &st) < 0)
303 return 0;
305 return st.st_mtime;