summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2000-07-24 23:08:26 +0000
committerMarc Espie <espie@cvs.openbsd.org>2000-07-24 23:08:26 +0000
commit76eb85ca193732f350422389bad4b476520bc8bc (patch)
tree23cac7523a298161f94d6a2ecd0ce330f92ba7f6
parent694bcd4b04b8f3bd12b98ce20e309dbe46fe9912 (diff)
Implement esyscmd
-rw-r--r--usr.bin/m4/eval.c8
-rw-r--r--usr.bin/m4/extern.h4
-rw-r--r--usr.bin/m4/gnum4.c55
-rw-r--r--usr.bin/m4/m4.16
-rw-r--r--usr.bin/m4/main.c5
-rw-r--r--usr.bin/m4/mdef.h3
6 files changed, 73 insertions, 8 deletions
diff --git a/usr.bin/m4/eval.c b/usr.bin/m4/eval.c
index ed8d15a4e04..c5fb8231935 100644
--- a/usr.bin/m4/eval.c
+++ b/usr.bin/m4/eval.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eval.c,v 1.26 2000/03/18 01:06:55 espie Exp $ */
+/* $OpenBSD: eval.c,v 1.27 2000/07/24 23:08:24 espie Exp $ */
/* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */
/*
@@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)eval.c 8.2 (Berkeley) 4/27/95";
#else
-static char rcsid[] = "$OpenBSD: eval.c,v 1.26 2000/03/18 01:06:55 espie Exp $";
+static char rcsid[] = "$OpenBSD: eval.c,v 1.27 2000/07/24 23:08:24 espie Exp $";
#endif
#endif /* not lint */
@@ -210,6 +210,10 @@ eval(argv, argc, td)
pbnum(sysval);
break;
+ case ESYSCMDTYPE:
+ if (argc > 2)
+ doesyscmd(argv[2]);
+ break;
case INCLTYPE:
if (argc > 2)
if (!doincl(argv[2]))
diff --git a/usr.bin/m4/extern.h b/usr.bin/m4/extern.h
index 4c2897d935c..264803e583f 100644
--- a/usr.bin/m4/extern.h
+++ b/usr.bin/m4/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.19 2000/07/02 01:17:00 espie Exp $ */
+/* $OpenBSD: extern.h,v 1.20 2000/07/24 23:08:25 espie Exp $ */
/* $NetBSD: extern.h,v 1.3 1996/01/13 23:25:24 pk Exp $ */
/*-
@@ -57,6 +57,8 @@ extern void doregexp __P((const char *[], int));
extern void doprintlineno __P((struct input_file *));
extern void doprintfilename __P((struct input_file *));
+
+extern void doesyscmd __P((const char *));
/* look.c */
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());
+ }
+}
diff --git a/usr.bin/m4/m4.1 b/usr.bin/m4/m4.1
index 14938325fb9..957fd988dd6 100644
--- a/usr.bin/m4/m4.1
+++ b/usr.bin/m4/m4.1
@@ -1,4 +1,4 @@
-.\" @(#) $OpenBSD: m4.1,v 1.17 2000/07/06 04:06:55 aaron Exp $
+.\" @(#) $OpenBSD: m4.1,v 1.18 2000/07/24 23:08:25 espie Exp $
.\"
.\"
.Dd January 26, 1993
@@ -139,6 +139,10 @@ Prints the names and definitions for the named items, or for everything
if no arguments are passed.
.It Ic errprint
Prints the first argument on the standard error output stream.
+.It Ic esyscmd
+Pass its first argument to a shell and returns the shell's standard output.
+Note that the shell shares its standard input and standard error with
+.Nm
.It Ic eval
Computes the first argument as an arithmetic expression using 32-bit
arithmetic.
diff --git a/usr.bin/m4/main.c b/usr.bin/m4/main.c
index 33a1c673644..68db31e7a65 100644
--- a/usr.bin/m4/main.c
+++ b/usr.bin/m4/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.34 2000/07/02 01:17:00 espie Exp $ */
+/* $OpenBSD: main.c,v 1.35 2000/07/24 23:08:25 espie Exp $ */
/* $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $ */
/*-
@@ -47,7 +47,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
#else
-static char rcsid[] = "$OpenBSD: main.c,v 1.34 2000/07/02 01:17:00 espie Exp $";
+static char rcsid[] = "$OpenBSD: main.c,v 1.35 2000/07/24 23:08:25 espie Exp $";
#endif
#endif /* not lint */
@@ -117,6 +117,7 @@ struct keyblk keywrds[] = { /* m4 keywords to be installed */
{ "builtin", BUILTINTYPE},
{ "patsubst", PATSTYPE},
{ "regexp", REGEXPTYPE},
+ { "esyscmd", ESYSCMDTYPE},
{ "__file__", FILENAMETYPE | NOARGS},
{ "__line__", LINETYPE | NOARGS},
#endif
diff --git a/usr.bin/m4/mdef.h b/usr.bin/m4/mdef.h
index 47200d93c57..e5f4f4891b5 100644
--- a/usr.bin/m4/mdef.h
+++ b/usr.bin/m4/mdef.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdef.h,v 1.16 2000/07/04 17:28:38 espie Exp $ */
+/* $OpenBSD: mdef.h,v 1.17 2000/07/24 23:08:25 espie Exp $ */
/* $NetBSD: mdef.h,v 1.7 1996/01/13 23:25:27 pk Exp $ */
/*
@@ -79,6 +79,7 @@
#define FILENAMETYPE 38
#define LINETYPE 39
#define REGEXPTYPE 40
+#define ESYSCMDTYPE 41
#define TYPEMASK 63 /* Keep bits really corresponding to a type. */
#define STATIC 128 /* Name is statically allocated, don't free. */