Blame


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