diff options
author | ben <ben@rana> | 2016-04-27 07:52:41 -0500 |
---|---|---|
committer | ben <ben@rana> | 2016-04-27 07:52:41 -0500 |
commit | 85824350b5f65053053245d141aaf7d668089d28 (patch) | |
tree | 075fe72eef40032c692d31194b2faac58eec5d18 /sys/src/cmd/awk/popen.c | |
parent | 0f8168038af32828fcdc39575dea0e4de0c01122 (diff) |
remove ape regexp library, add utility for awk native port
Diffstat (limited to 'sys/src/cmd/awk/popen.c')
-rw-r--r-- | sys/src/cmd/awk/popen.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/sys/src/cmd/awk/popen.c b/sys/src/cmd/awk/popen.c new file mode 100644 index 000000000..bcb769ebd --- /dev/null +++ b/sys/src/cmd/awk/popen.c @@ -0,0 +1,91 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "awk.h" + +#define MAXFORKS 20 +#define NSYSFILE 3 +#define tst(a,b) (mode == OREAD? (b) : (a)) +#define RDR 0 +#define WTR 1 + +struct a_fork { + short done; + short fd; + int pid; + char status[128]; +}; +static struct a_fork the_fork[MAXFORKS]; + +Biobuf* +popen(char *cmd, int mode) +{ + int p[2]; + int myside, hisside, pid; + int i, ind; + + for (ind = 0; ind < MAXFORKS; ind++) + if (the_fork[ind].pid == 0) + break; + if (ind == MAXFORKS) + return nil; + if(pipe(p) < 0) + return nil; + myside = tst(p[WTR], p[RDR]); + hisside = tst(p[RDR], p[WTR]); + switch (pid = fork()) { + case -1: + return nil; + case 0: + /* myside and hisside reverse roles in child */ + close(myside); + dup(hisside, tst(0, 1)); + for (i=NSYSFILE; i<FOPEN_MAX; i++) + close(i); + execl("/bin/rc", "rc", "-c", cmd, nil); + exits("exec failed"); + default: + the_fork[ind].pid = pid; + the_fork[ind].fd = myside; + the_fork[ind].done = 0; + close(hisside); + return(Bfdopen(myside, mode)); + } +} + +int +pclose(Biobuf *ptr) +{ + int f, r, ind; + Waitmsg *status; + + f = Bfildes(ptr); + Bterm(ptr); + for (ind = 0; ind < MAXFORKS; ind++) + if (the_fork[ind].fd == f && the_fork[ind].pid != 0) + break; + if (ind == MAXFORKS) + return -1; + if (!the_fork[ind].done) { + do { + if((status = wait()) == nil) + r = -1; + else + r = status->pid; + for (f = 0; f < MAXFORKS; f++) { + if (r == the_fork[f].pid) { + the_fork[f].done = 1; + strecpy(the_fork[f].status, the_fork[f].status+512, status->msg); + break; + } + } + free(status); + } while(r != the_fork[ind].pid && r != -1); + if(r == -1) + strcpy(the_fork[ind].status, "No loved ones to wait for"); + } + the_fork[ind].pid = 0; + if(the_fork[ind].status[0] != '\0') + return 1; + return 0; +} |