4 #include "threadimpl.h"
7 procexec(Channel *pidc, char *prog, char *args[])
13 _threaddebug(DBGEXEC, "procexec %s", prog);
14 /* must be only thread in proc */
17 if(p->threads.head != t || p->threads.head->nextt != nil){
18 werrstr("not only thread in proc");
26 * We want procexec to behave like exec; if exec succeeds,
27 * never return, and if it fails, return with errstr set.
28 * Unfortunately, the exec happens in another proc since
29 * we have to wait for the exec'ed process to finish.
30 * To provide the semantics, we open a pipe with the
31 * write end close-on-exec and hand it to the proc that
32 * is doing the exec. If the exec succeeds, the pipe will
33 * close so that our read below fails. If the exec fails,
34 * then the proc doing the exec sends the errstr down the
37 if(pipe(p->exec.fd) < 0)
39 snprint(p->exitstr, ERRMAX, "/fd/%d", p->exec.fd[1]);
40 if((n = open(p->exitstr, OWRITE|OCEXEC)) < 0){
48 /* exec in parallel via the scheduler */
49 assert(p->needexec==0);
56 if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){ /* exec failed */
58 errstr(p->exitstr, ERRMAX);
67 /* wait for exec'ed program, then exit */
72 procexecl(Channel *pidc, char *f, ...)
74 procexec(pidc, f, &f+1);