1 #include "threadimpl.h"
3 #define PIPEMNT "/mnt/temp"
6 procexec(Channel *pidc, int fd[3], char *prog, char *args[])
12 _threaddebug(DBGEXEC, "procexec %s", prog);
13 /* must be only thread in proc */
16 if(p->threads.head != t || p->threads.head->nextt != nil){
17 werrstr("not only thread in proc");
25 * We want procexec to behave like exec; if exec succeeds,
26 * never return, and if it fails, return with errstr set.
27 * Unfortunately, the exec happens in another proc since
28 * we have to wait for the exec'ed process to finish.
29 * To provide the semantics, we open a pipe with the
30 * write end close-on-exec and hand it to the proc that
31 * is doing the exec. If the exec succeeds, the pipe will
32 * close so that our read below fails. If the exec fails,
33 * then the proc doing the exec sends the errstr down the
36 if(bind("#|", PIPEMNT, MREPL) < 0)
38 if((p->exec.fd[0] = open(PIPEMNT "/data", OREAD)) < 0){
39 unmount(nil, PIPEMNT);
42 if((p->exec.fd[1] = open(PIPEMNT "/data1", OWRITE|OCEXEC)) < 0){
44 unmount(nil, PIPEMNT);
47 unmount(nil, PIPEMNT);
49 /* exec in parallel via the scheduler */
50 assert(p->needexec==0);
58 if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){ /* exec failed */
60 errstr(p->exitstr, ERRMAX);
68 if(fd[2] != fd[1] && fd[2] != fd[0])
73 /* wait for exec'ed program, then exit */
78 procexecl(Channel *pidc, int fd[3], char *f, ...)
80 procexec(pidc, fd, f, &f+1);