diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2000-07-24 23:08:26 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2000-07-24 23:08:26 +0000 |
commit | 76eb85ca193732f350422389bad4b476520bc8bc (patch) | |
tree | 23cac7523a298161f94d6a2ecd0ce330f92ba7f6 /usr.bin/m4/gnum4.c | |
parent | 694bcd4b04b8f3bd12b98ce20e309dbe46fe9912 (diff) |
Implement esyscmd
Diffstat (limited to 'usr.bin/m4/gnum4.c')
-rw-r--r-- | usr.bin/m4/gnum4.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/usr.bin/m4/gnum4.c b/usr.bin/m4/gnum4.c index 9fd15a7dc2b..d1efae77903 100644 --- a/usr.bin/m4/gnum4.c +++ b/usr.bin/m4/gnum4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gnum4.c,v 1.7 2000/06/28 10:01:27 espie Exp $ */ +/* $OpenBSD: gnum4.c,v 1.8 2000/07/24 23:08:25 espie Exp $ */ /* * Copyright (c) 1999 Marc Espie @@ -31,13 +31,17 @@ #include <sys/param.h> #include <sys/types.h> +#include <sys/wait.h> #include <ctype.h> +#include <paths.h> #include <regex.h> #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <err.h> +#include <errno.h> +#include <unistd.h> #include "mdef.h" #include "stdd.h" #include "extern.h" @@ -478,3 +482,52 @@ doregexp(argv, argc) free(pmatch); regfree(&re); } + +void +doesyscmd(cmd) + const char *cmd; +{ + int p[2]; + pid_t pid, cpid; + char *argv[4]; + int cc; + int status; + + /* Follow gnu m4 documentation: first flush buffers. */ + fflush(NULL); + + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = (char *)cmd; + argv[3] = NULL; + + /* Just set up standard output, share stderr and stdin with m4 */ + if (pipe(p) == -1) + err(1, "bad pipe"); + switch(cpid = fork()) { + case -1: + err(1, "bad fork"); + /* NOTREACHED */ + case 0: + (void) close(p[0]); + (void) dup2(p[1], 1); + (void) close(p[1]); + execv(_PATH_BSHELL, argv); + exit(1); + default: + /* Read result in two stages, since m4's buffer is + * pushback-only. */ + (void) close(p[1]); + do { + char result[BUFSIZE]; + cc = read(p[0], result, sizeof result); + if (cc > 0) + addchars(result, cc); + } while (cc > 0 || (cc == -1 && errno == EINTR)); + + (void) close(p[0]); + while ((pid = wait(&status)) != cpid && pid >= 0) + continue; + pbstr(getstring()); + } +} |