summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2009-03-02 06:54:28 -0700
committerEric Blake <ebb9@byu.net>2009-03-13 06:55:13 -0600
commit54a1ab447fc79ed0f817e6b8e140ac2fd49b6e62 (patch)
tree161d60f9f7037b935daece637e0225351344ecaa
parentdda0922ce08566dc37d4521495f78a0fbc9bc5f7 (diff)
downloadm4-54a1ab447fc79ed0f817e6b8e140ac2fd49b6e62.tar.gz
Use gnulib pipe module instead of popen(3).
* ltdl/m4/gnulib-cache.m4: Import pipe and wait-process modules. * modules/gnu.c (M4_SYSVAL_EXITBITS, M4_SYSVAL_TERMSIGBITS): Delete. (esyscmd): Rewrite with pipe module. Resolves a failure on AIX, reported by Gary V. Vaughan. Signed-off-by: Eric Blake <ebb9@byu.net> (cherry picked from commit 9915ef54d55fae837209bc87d35c777715653bed)
-rw-r--r--ChangeLog7
-rw-r--r--ltdl/m4/gnulib-cache.m44
-rw-r--r--modules/gnu.c122
3 files changed, 73 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index 13c88952..b5f6487a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2009-03-13 Eric Blake <ebb9@byu.net>
+ Use gnulib pipe module instead of popen(3).
+ * ltdl/m4/gnulib-cache.m4: Import pipe and wait-process modules.
+ * modules/gnu.c (M4_SYSVAL_EXITBITS, M4_SYSVAL_TERMSIGBITS):
+ Delete.
+ (esyscmd): Rewrite with pipe module.
+ Resolves a failure on AIX, reported by Gary V. Vaughan.
+
Use gnulib execute module instead of system(3).
* ltdl/m4/gnulib-cache.m4: Import execute module.
* m4/utility.c (m4_info_name): New function.
diff --git a/ltdl/m4/gnulib-cache.m4 b/ltdl/m4/gnulib-cache.m4
index 050fff45..9e664dab 100644
--- a/ltdl/m4/gnulib-cache.m4
+++ b/ltdl/m4/gnulib-cache.m4
@@ -15,7 +15,7 @@
# Specification in the form of a command-line invocation:
-# gnulib-tool --import --dir=. --local-dir=local --lib=libgnu --source-base=gnu --m4-base=ltdl/m4 --doc-base=doc --tests-base=tests/gnu --aux-dir=build-aux --with-tests --libtool --macro-prefix=M4 assert autobuild avltree-oset binary-io clean-temp cloexec close-stream closein config-h configmake dirname error execute exit fdl-1.3 fflush filenamecat flexmember fopen fopen-safer freadptr freadseek fseeko gendocs gettext git-version-gen gnumakefile gnupload gpl-3.0 intprops memchr2 memmem mkstemp obstack obstack-printf-posix progname propername quote regex regexprops-generic sprintf-posix stdbool stdlib-safer strnlen strtod strtol tempname unlocked-io vasnprintf-posix verify verror xalloc xalloc-die xmemdup0 xprintf-posix xstrndup xvasprintf-posix
+# gnulib-tool --import --dir=. --local-dir=local --lib=libgnu --source-base=gnu --m4-base=ltdl/m4 --doc-base=doc --tests-base=tests/gnu --aux-dir=build-aux --with-tests --libtool --macro-prefix=M4 assert autobuild avltree-oset binary-io clean-temp cloexec close-stream closein config-h configmake dirname error execute exit fdl-1.3 fflush filenamecat flexmember fopen fopen-safer freadptr freadseek fseeko gendocs gettext git-version-gen gnumakefile gnupload gpl-3.0 intprops memchr2 memmem mkstemp obstack obstack-printf-posix pipe progname propername quote regex regexprops-generic sprintf-posix stdbool stdlib-safer strnlen strtod strtol tempname unlocked-io vasnprintf-posix verify verror wait-process xalloc xalloc-die xmemdup0 xprintf-posix xstrndup xvasprintf-posix
# Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([local])
@@ -55,6 +55,7 @@ gl_MODULES([
mkstemp
obstack
obstack-printf-posix
+ pipe
progname
propername
quote
@@ -71,6 +72,7 @@ gl_MODULES([
vasnprintf-posix
verify
verror
+ wait-process
xalloc
xalloc-die
xmemdup0
diff --git a/modules/gnu.c b/modules/gnu.c
index 122e9669..e833f552 100644
--- a/modules/gnu.c
+++ b/modules/gnu.c
@@ -28,10 +28,10 @@
# include "m4private.h"
#endif
-#include <sys/wait.h>
-
#include "modules/m4.h"
+#include "pipe.h"
#include "quotearg.h"
+#include "wait-process.h"
/* Rename exported symbols for dlpreload()ing. */
#define m4_builtin_table gnu_LTX_m4_builtin_table
@@ -639,35 +639,8 @@ M4BUILTIN_HANDLER (debugmode)
}
-/* Helper macros for readability. */
-#if UNIX || defined WEXITSTATUS
-# define M4_SYSVAL_EXITBITS(status) \
- (WIFEXITED (status) ? WEXITSTATUS (status) : 0)
-# define M4_SYSVAL_TERMSIGBITS(status) \
- (WIFSIGNALED (status) ? WTERMSIG (status) << 8 : 0)
-
-#else /* !UNIX && !defined WEXITSTATUS */
-/* Platforms such as mingw do not support the notion of reporting
- which signal terminated a process. Furthermore if WEXITSTATUS was
- not provided, then the exit value is in the low eight bits. */
-# define M4_SYSVAL_EXITBITS(status) status
-# define M4_SYSVAL_TERMSIGBITS(status) 0
-#endif /* !UNIX && !defined WEXITSTATUS */
-
-/* Fallback definitions if <stdlib.h> or <sys/wait.h> are inadequate. */
-/* FIXME - this may fit better as a gnulib module. */
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(status) (((status) >> 8) & 0xff)
-#endif
-#ifndef WTERMSIG
-# define WTERMSIG(status) ((status) & 0x7f)
-#endif
-#ifndef WIFSIGNALED
-# define WIFSIGNALED(status) (WTERMSIG (status) != 0)
-#endif
-#ifndef WIFEXITED
-# define WIFEXITED(status) (WTERMSIG (status) == 0)
-#endif
+/* FIXME */
+#define SYSCMD_SHELL "/bin/sh"
/* Same as the sysymd builtin from m4.c module, but expand to the
output of SHELL-COMMAND. */
@@ -686,7 +659,14 @@ M4BUILTIN_HANDLER (esyscmd)
if (m4_set_sysval && m4_sysval_flush)
{
+ pid_t child;
+ int fd;
FILE *pin;
+ int status;
+ int sig_status;
+ const char *prog_args[4] = { "sh", "-c" };
+ const char *caller;
+ const char *shell = SYSCMD_SHELL;
if (m4_get_safer_opt (context))
{
@@ -705,42 +685,66 @@ M4BUILTIN_HANDLER (esyscmd)
}
m4_sysval_flush (context, false);
+#if W32_NATIVE
+ shell = prog_args[0] = "cmd";
+ prog_args[1] = "/c";
+#endif
+ prog_args[2] = cmd;
+ caller = m4_info_name (me);
errno = 0;
- pin = popen (cmd, "r");
- if (pin == NULL)
+ child = create_pipe_in (caller, shell/*FIXME*/, (char **) prog_args,
+ NULL, false, true, false, &fd);
+ if (child == -1)
{
- m4_error (context, 0, errno, me,
- _("cannot run command %s"),
+ m4_error (context, 0, errno, me, _("cannot run command %s"),
quotearg_style (locale_quoting_style, cmd));
m4_set_sysval (127);
+ return;
}
- else
+ pin = fdopen (fd, "r");
+ if (!pin)
{
- while (1)
+ m4_error (context, 0, errno, me, _("cannot run command %s"),
+ quotearg_style (locale_quoting_style, cmd));
+ m4_set_sysval (127);
+ close (fd);
+ return;
+ }
+ while (1)
+ {
+ size_t avail = obstack_room (obs);
+ if (!avail)
+ {
+ int ch = getc (pin);
+ if (ch == EOF)
+ break;
+ obstack_1grow (obs, ch);
+ }
+ else
{
- size_t avail = obstack_room (obs);
- if (!avail)
- {
- int ch = getc (pin);
- if (ch == EOF)
- break;
- obstack_1grow (obs, ch);
- }
- else
- {
- size_t len = fread (obstack_next_free (obs), 1, avail, pin);
- if (len <= 0)
- break;
- obstack_blank_fast (obs, len);
- }
+ size_t len = fread (obstack_next_free (obs), 1, avail, pin);
+ if (len <= 0)
+ break;
+ obstack_blank_fast (obs, len);
}
- if (ferror (pin))
- m4_warn (context, errno, me, _("cannot read pipe to command %s"),
- quotearg_style (locale_quoting_style, cmd));
- int result = pclose (pin);
- m4_set_sysval (result == -1 ? 127
- : (M4_SYSVAL_EXITBITS (result)
- | M4_SYSVAL_TERMSIGBITS (result)));
+ }
+ if (ferror (pin) || fclose (pin))
+ m4_error (context, EXIT_FAILURE, errno, me,
+ _("cannot read pipe to command %s"),
+ quotearg_style (locale_quoting_style, cmd));
+ status = wait_subprocess (child, caller, false, false, true, false,
+ &sig_status);
+ if (sig_status)
+ {
+ assert (status == 127);
+ m4_set_sysval (sig_status << 8);
+ }
+ else
+ {
+ if (status == 127 && errno)
+ m4_error (context, 0, errno, me, _("cannot run command %s"),
+ quotearg_style (locale_quoting_style, cmd));
+ m4_set_sysval (status);
}
}
else