| @@ -0,0 +1,74 @@ |
| | 1 | #include <u.h> |
| | 2 | #include <libc.h> |
| | 3 | #include <thread.h> |
| | 4 | |
| | 5 | typedef struct Exec Exec; |
| | 6 | |
| | 7 | struct Exec { |
| | 8 | /* these two specify what program (and arguments) to run using procexec */ |
| | 9 | char *file; |
| | 10 | char **argv; |
| | 11 | |
| | 12 | /* this will have either -1 or the actual pid of the executed program sent over */ |
| | 13 | Channel *pid; |
| | 14 | }; |
| | 15 | |
| | 16 | void |
| | 17 | pexec(void *args) |
| | 18 | { |
| | 19 | Exec *e = args; |
| | 20 | procexec(e->pid, e->file, e->argv); |
| | 21 | } |
| | 22 | |
| | 23 | void |
| | 24 | threadmain(int, char **) |
| | 25 | { |
| | 26 | Exec e; |
| | 27 | int i, n, pid; |
| | 28 | Channel *waitc; |
| | 29 | Waitmsg *w; |
| | 30 | char *argv[] = {"rc", "-c", "sleep 2", nil}; |
| | 31 | |
| | 32 | quotefmtinstall(); |
| | 33 | |
| | 34 | /* this HAS to be called before spawning other threads |
| | 35 | * otherwise those threads won't send their status |
| | 36 | */ |
| | 37 | waitc = threadwaitchan(); |
| | 38 | |
| | 39 | /* that's where we get the pid from */ |
| | 40 | e.pid = chancreate(sizeof(int), 0); |
| | 41 | |
| | 42 | for(n = i = 0; i < 3; n++, i++){ |
| | 43 | /* last process always fails to demonstrate the error status */ |
| | 44 | if(i == 2) |
| | 45 | argv[2] = "this breaks"; |
| | 46 | e.file = "/bin/rc"; |
| | 47 | e.argv = argv; |
| | 48 | proccreate(pexec, &e, 4096); |
| | 49 | |
| | 50 | /* receive the pid */ |
| | 51 | recv(e.pid, &pid); |
| | 52 | if(pid < 0) |
| | 53 | sysfatal("procexec failed"); |
| | 54 | |
| | 55 | fprint(2, "pid %d running\n", pid); |
| | 56 | } |
| | 57 | |
| | 58 | /* won't get any new pids at this point */ |
| | 59 | chanfree(e.pid); |
| | 60 | |
| | 61 | /* wait until all processes are finished |
| | 62 | * we know how many there are so it's pretty easy |
| | 63 | */ |
| | 64 | while(n > 0){ |
| | 65 | /* w (Waitmsg) points to the result of a finished process */ |
| | 66 | w = recvp(waitc); |
| | 67 | fprint(2, "pid %d: %q\n", w->pid, w->msg); |
| | 68 | /* each one of them is allocated with malloc */ |
| | 69 | free(w); |
| | 70 | n--; |
| | 71 | } |
| | 72 | |
| | 73 | threadexitsall(nil); |
| | 74 | } |