Showing the changes to example.c (1 of 3 files). Show all
Unified · Split
| @@ -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 | +} | |