3 char *shell = "/bin/rc";
4 char *shellname = "rc";
6 static Word *encodenulls(char*, int);
18 rfork(RFENVG); /* use copy of the current environment variables */
20 envf = open("/env", OREAD);
23 while((n = dirread(envf, &e)) > 0){
24 for(i = 0; i < n; i++){
26 /* don't import funny names, NULL values,
27 * or internal mk variables
29 if(len <= 0 || *shname(e[i].name) != '\0')
31 if (symlook(e[i].name, S_INTERNAL, 0))
33 snprint(nam, sizeof nam, "/env/%s", e[i].name);
38 if(read(f, p, len) != len){
48 w = encodenulls(p, len);
50 p = strdup(e[i].name);
51 setvar(p, (void *) w);
52 symlook(p, S_EXPORTED, (void*)"")->u.ptr = "";
59 /* break string of values into words at 01's or nulls*/
61 encodenulls(char *s, int n)
68 for (cp = s; *cp && *cp != '\0'; cp++)
75 head = w = newword(s);
83 /* as well as 01's, change blanks to nulls, so that rc will
84 * treat the words as separate arguments
89 int f, n, hasvalue, first;
95 sy = symlook(e->name, S_VAR, 0);
96 if (e->values == 0 || e->values->s == 0 || e->values->s[0] == 0)
100 if(sy == 0 && !hasvalue) /* non-existant null symbol */
102 snprint(nam, sizeof nam, "/env/%s", e->name);
103 if (sy != 0 && !hasvalue) { /* Remove from environment */
104 /* we could remove it from the symbol table
105 * too, but we're in the child copy, and it
106 * would still remain in the parent's table.
110 e->values = 0; /* memory leak */
114 f = create(nam, OWRITE, 0666L);
116 fprint(2, "can't create %s, f=%d\n", nam, f);
121 for (w = e->values; w; w = w->next) {
127 if (write (f, "\0", 1) != 1)
130 if (write(f, w->s, n) != n)
144 if((w=wait()) == nil)
146 strecpy(msg, msg+ERRMAX, w->msg);
153 expunge(int pid, char *msg)
155 postnote(PNPROC, pid, msg);
159 execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
162 int tot, n, pid, in[2], out[2];
164 if(buf && pipe(out) < 0){
168 pid = rfork(RFPROC|RFFDG|RFENVG);
196 execl(shell, shellname, shflags, args, nil);
198 execl(shell, shellname, args, nil);
206 n = write(in[1], cmd, p-cmd);
218 if (buf->current >= buf->end)
220 n = read(out[0], buf->current, buf->end-buf->current);
226 if (tot && buf->current[-1] == '\n')
234 pipecmd(char *cmd, Envy *e, int *fd)
239 fprint(1, "pipecmd='%s'\n", cmd);/**/
241 if(fd && pipe(pfd) < 0){
245 pid = rfork(RFPROC|RFFDG|RFENVG);
259 execl(shell, shellname, shflags, "-c", cmd, nil);
261 execl(shell, shellname, "-c", cmd, nil);
275 while(waitpid() >= 0)
281 notifyf(void *a, char *msg)
286 if(++nnote > 100){ /* until andrew fixes his program */
287 fprint(2, "mk: too many notes\n");
291 if(strcmp(msg, "interrupt")!=0 && strcmp(msg, "hangup")!=0)
300 atnotify(notifyf, 1);
306 static char temp[] = "/tmp/mkargXXXXXX";
317 if(access(name, AEXIST) >= 0) {
319 sbuf.mtime = time((long *)0);
320 return dirwstat(name, &sbuf);
322 return close(create(name, OWRITE, 0666));
326 rcopy(char **to, Resub *match, int n)
331 *to = match->sp; /* stem0 matches complete target */
332 for(to++, match++; --n > 0; to++, match++){
333 if(match->sp && match->ep){
337 *to = strdup(match->sp);
346 dirtime(char *dir, char *path)
353 fd = open(dir, OREAD);
355 while((n = dirread(fd, &d)) > 0){
358 /* defensive driving: this does happen */
361 snprint(buf, sizeof buf, "%s%s", path,
363 if(symlook(buf, S_TIME, 0) == nil)
364 symlook(strdup(buf), S_TIME,
365 (void*)mtime)->u.value = mtime;
382 if(strcmp(dir, "/") == 0)
383 strecpy(buf, buf + sizeof buf - 1, dir);
385 snprint(buf, sizeof buf, "%s/", dir);
391 if(symlook(sym, S_BULKED, 0))
394 symlook(ss, S_BULKED, (void*)ss);
399 mkmtime(char *name, int force)
407 strecpy(buf, buf + sizeof buf - 1, name);
411 s = utfrrune(name, '/');
426 sym = symlook(name, S_TIME, 0);
431 if((d = dirstat(name)) == nil)