=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/m4/gnum4.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- src/usr.bin/m4/gnum4.c 2000/06/28 10:01:27 1.7 +++ src/usr.bin/m4/gnum4.c 2000/07/24 23:08:25 1.8 @@ -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 #include +#include #include +#include #include #include #include #include #include #include +#include +#include #include "mdef.h" #include "stdd.h" #include "extern.h" @@ -477,4 +481,53 @@ do_regexp(argv[2], &re, argv[4], pmatch); 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()); + } }