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 void13 mkperror(char *s)14 {15 fprint(2, "%s: %r\n", s);16 }18 void19 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 } else30 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 affected41 * and we don't care about freeing memory because we're going42 * to exec immediately after this.43 */44 void45 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 else57 sprint(buf, "%s=", e->name);58 p[i] = strdup(buf);59 }60 p[i] = 0;61 environ = p;62 }64 int65 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 else77 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 void85 expunge(int pid, char *msg)86 {87 if(strcmp(msg, "interrupt"))88 kill(pid, SIGINT);89 else90 kill(pid, SIGHUP);91 }93 int94 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();102 }103 pid = fork();104 if(pid < 0){105 mkperror("mk fork");106 Exit();107 }108 if(pid == 0){109 if(buf)110 close(out[0]);111 if(pipe(in) < 0){112 mkperror("pipe");113 Exit();114 }115 pid = fork();116 if(pid < 0){117 mkperror("mk fork");118 Exit();119 }120 if(pid != 0){121 dup2(in[0], 0);122 if(buf){123 dup2(out[1], 1);124 close(out[1]);125 }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 else133 execl(shell, shellname, args, 0);134 mkperror(shell);135 _exit(1);136 }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;147 }148 close(in[1]);149 _exit(0);150 }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;162 }163 if (tot && buf->current[-1] == '\n')164 buf->current--;165 close(out[0]);166 }167 return pid;168 }170 int171 pipecmd(char *cmd, Envy *e, int *fd)172 {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();181 }182 pid = fork();183 if(pid < 0){184 mkperror("mk fork");185 Exit();186 }187 if(pid == 0){188 if(fd){189 close(pfd[0]);190 dup2(pfd[1], 1);191 close(pfd[1]);192 }193 if(e)194 exportenv(e);195 if(shflags)196 execl(shell, shellname, shflags, "-c", cmd, 0);197 else198 execl(shell, shellname, "-c", cmd, 0);199 mkperror(shell);200 _exit(1);201 }202 if(fd){203 close(pfd[1]);204 *fd = pfd[0];205 }206 return pid;207 }209 void210 Exit(void)211 {212 while(wait(0) >= 0)213 ;214 exits("error");215 }217 static struct218 {219 int sig;220 char *msg;221 } sigmsgs[] =222 {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, 0229 };231 static void232 notifyf(int sig)233 {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);243 }245 void246 catchnotes()247 {248 int i;250 for(i = 0; sigmsgs[i].msg; i++)251 signal(sigmsgs[i].sig, notifyf);252 }254 char*255 maketmp(int *pfd)256 {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;267 }269 int270 chgtime(char *name)271 {272 if(access(name, 0) >= 0)273 return utimes(name, 0);274 return close(creat(name, 0666));275 }277 void278 rcopy(char **to, Resub *match, int n)279 {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;291 }292 else293 *to = 0;294 }295 }297 ulong298 mkmtime(char *name)299 {300 struct stat st;302 if(stat(name, &st) < 0)303 return 0;305 return st.st_mtime;306 }