1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "threadimpl.h"
5
6 #define PIPEMNT "/mnt/temp"
7
8 void
procexec(Channel * pidc,char * prog,char * args[])9 procexec(Channel *pidc, char *prog, char *args[])
10 {
11 int n;
12 Proc *p;
13 Thread *t;
14
15 _threaddebug(DBGEXEC, "procexec %s", prog);
16 /* must be only thread in proc */
17 p = _threadgetproc();
18 t = p->thread;
19 if(p->threads.head != t || p->threads.head->nextt != nil){
20 werrstr("not only thread in proc");
21 Bad:
22 if(pidc)
23 sendul(pidc, ~0);
24 return;
25 }
26
27 /*
28 * We want procexec to behave like exec; if exec succeeds,
29 * never return, and if it fails, return with errstr set.
30 * Unfortunately, the exec happens in another proc since
31 * we have to wait for the exec'ed process to finish.
32 * To provide the semantics, we open a pipe with the
33 * write end close-on-exec and hand it to the proc that
34 * is doing the exec. If the exec succeeds, the pipe will
35 * close so that our read below fails. If the exec fails,
36 * then the proc doing the exec sends the errstr down the
37 * pipe to us.
38 */
39 if(bind("#|", PIPEMNT, MREPL) < 0)
40 goto Bad;
41 if((p->exec.fd[0] = open(PIPEMNT "/data", OREAD)) < 0){
42 unmount(nil, PIPEMNT);
43 goto Bad;
44 }
45 if((p->exec.fd[1] = open(PIPEMNT "/data1", OWRITE|OCEXEC)) < 0){
46 close(p->exec.fd[0]);
47 unmount(nil, PIPEMNT);
48 goto Bad;
49 }
50 unmount(nil, PIPEMNT);
51
52 /* exec in parallel via the scheduler */
53 assert(p->needexec==0);
54 p->exec.prog = prog;
55 p->exec.args = args;
56 p->needexec = 1;
57 _sched();
58
59 close(p->exec.fd[1]);
60 if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){ /* exec failed */
61 p->exitstr[n] = '\0';
62 errstr(p->exitstr, ERRMAX);
63 close(p->exec.fd[0]);
64 goto Bad;
65 }
66 close(p->exec.fd[0]);
67
68 if(pidc)
69 sendul(pidc, t->ret);
70
71 /* wait for exec'ed program, then exit */
72 _schedexecwait();
73 }
74
75 void
procexecl(Channel * pidc,char * f,...)76 procexecl(Channel *pidc, char *f, ...)
77 {
78 procexec(pidc, f, &f+1);
79 }
80
81