bug-m4
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sysval and doc fixes [was: GNU M4 1.4.4b released (beta release)]


From: Eric Blake
Subject: Re: sysval and doc fixes [was: GNU M4 1.4.4b released (beta release)]
Date: Tue, 20 Jun 2006 22:08:42 -0600
User-agent: Thunderbird 1.5.0.4 (Windows/20060516)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Andreas Büning on 6/20/2006 1:22 PM:
> 
> pclose() and waitpid(), yes but not system(). system() is Standard C
> but even C99 doesn't seem to specify its return value except for
> system(NULL), neither does POSIX.1.

Which version of POSIX?  POSIX 2001 says this (albeit in CX shading, which
means it is an additional restriction of POSIX that a pure C99
implementation need not follow):

If command is not a null pointer, system() shall return the termination
status of the command language interpreter in the format specified by
waitpid().
http://www.opengroup.org/onlinepubs/009695399/functions/system.html

Therefore, it looks like OS/2 is not POSIX compliant, and we will have to
detect that with a configure test of some sort.  Is there any compile-time
test we can run that will reliably show when WEXITSTATUS doesn't work on
the result of system()?

Meanwhile, I noticed that sysval gave the value of 0 if the subprocess
dies from a signal:
$ echo 'syscmd(kill -1 $$)sysval' | m4
0

Whereas, on Solaris 8, fatal signals can't be confused with success:
$ echo 'syscmd(kill -1 $$)sysval' | /usr/ccs/bin/m4
256

And if system() fails with -1 (such as for E2BIG, when I exceed the 1MB
ARG_MAX limitation), Solaris still translated that to 127:
$ perl -e 'print "syscmd(/bin/echo ".("a "x2000000).")sysval"' |\
/usr/ccs/bin/m4 -B5000000
127

But the GNU version wasn't even checking for failure on syscmd, and only
partially on esyscmd, with a result of 255 on failure.

So I think this patch is worthwhile.  I'm hesitant to check it in without
some review; and it still doesn't solve the OS/2 issue.

2006-06-20  Eric Blake  <address@hidden>

        For compatibility with other m4 implementations, sysval returns
        signal*256 rather than 0 if syscmd is terminated by signal.
        * configure.ac (AC_CHECK_HEADERS): Check for sys/wait.h.
        * src/builtin.c (include): Add sys/wait.h, for platforms where
        stdlib.h does not provide status macros.
        (WTERMSIG, WIFSIGNALED, WIFEXITED): Provide fallback definitions.
        (m4_syscmd, m4_esyscmd): Check for errors and signals, and compute
        final sysval here.
        (m4_sysval): Use pre-computed value.
        * doc/m4.texinfo (Sysval): Document this, and add a test.
        * NEWS: Document this.

- --
Life is short - so eat dessert first!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEmMZJ84KuGfSFAYARAlxeAJwKqu7CgeM4nRc84ZclGDC60m4NHACfWcZN
lM235ZZ6ZwJMDwmbQ8j6pvM=
=sQsz
-----END PGP SIGNATURE-----
Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.1.1.1.2.22
diff -u -p -r1.1.1.1.2.22 NEWS
--- NEWS        18 Jun 2006 21:36:09 -0000      1.1.1.1.2.22
+++ NEWS        21 Jun 2006 04:06:08 -0000
@@ -6,6 +6,8 @@ Version 1.4.5 - ?? 2006, by ???  (CVS ve
 
 * Fix sysval on BeOS, OS/2, and other systems that store exit status
   in the low-order byte.
+* If syscmd or esyscmd is terminated by a signal, sysval now reports the
+  signal value times 256, rather than 0.
 
 Version 1.4.4b - 17 June 2006, by Eric Blake  (CVS version 1.4.4a)
 
Index: configure.ac
===================================================================
RCS file: /sources/m4/m4/configure.ac,v
retrieving revision 1.36.2.14
diff -u -p -r1.36.2.14 configure.ac
--- configure.ac        18 Jun 2006 20:38:02 -0000      1.36.2.14
+++ configure.ac        21 Jun 2006 04:06:08 -0000
@@ -31,7 +31,7 @@ AC_CONFIG_HEADERS([config.h:config-h.in]
 AC_PROG_CC
 M4_EARLY
 
-AC_CHECK_HEADERS([limits.h siginfo.h])
+AC_CHECK_HEADERS([limits.h siginfo.h sys/wait.h])
 AC_CHECK_HEADERS([signal.h sys/signal.h], [break])
 AC_TYPE_SIGNAL
 AC_TYPE_SIZE_T
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.1.1.1.2.21
diff -u -p -r1.1.1.1.2.21 m4.texinfo
--- doc/m4.texinfo      18 Jun 2006 21:36:09 -0000      1.1.1.1.2.21
+++ doc/m4.texinfo      21 Jun 2006 04:06:09 -0000
@@ -3148,6 +3148,18 @@ sysval
 @result{}0
 @end example
 
address@hidden results in 127 if there was a problem executing the
+command, for example if the system-imposed argument length is exceeded.
+If the command execution is terminated by a signal, rather than a normal
+exit, then the result is the signal number times 256.
+
address@hidden
+syscmd(`kill -1 $$')
address@hidden
+sysval
address@hidden
address@hidden example
+
 @node Maketemp,  , Sysval, UNIX commands
 @section Making names for temporary files
 
Index: src/builtin.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/builtin.c,v
retrieving revision 1.1.1.1.2.12
diff -u -p -r1.1.1.1.2.12 builtin.c
--- src/builtin.c       18 Jun 2006 21:31:56 -0000      1.1.1.1.2.12
+++ src/builtin.c       21 Jun 2006 04:06:09 -0000
@@ -28,6 +28,10 @@ extern FILE *popen ();
 
 #include "regex.h"
 
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+
 #define ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
 
 /* Initialisation of builtin and predefined macros.  The table
@@ -748,6 +752,15 @@ m4_defn (struct obstack *obs, int argc, 
 #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
 
 /* Exit code from last "syscmd" command.  */
 static int sysval;
@@ -755,11 +768,20 @@ static int sysval;
 static void
 m4_syscmd (struct obstack *obs, int argc, token_data **argv)
 {
+  int val;
   if (bad_argc (argv[0], argc, 2, 2))
     return;
 
   debug_flush_files ();
-  sysval = system (ARG (1));
+  val = system (ARG (1));
+  if (val == -1)
+    sysval = 127;
+  else if (WIFEXITED (val))
+    sysval = WEXITSTATUS (val);
+  else if (WIFSIGNALED (val))
+    sysval = WTERMSIG (val) * 256;
+  else
+    sysval = 127;
 }
 
 static void
@@ -778,20 +800,29 @@ m4_esyscmd (struct obstack *obs, int arg
     {
       M4ERROR ((warning_status, errno,
                "Cannot open pipe to command \"%s\"", ARG (1)));
-      sysval = 0xffff;
+      sysval = 127;
     }
   else
     {
+      int val;
       while ((ch = getc (pin)) != EOF)
        obstack_1grow (obs, (char) ch);
-      sysval = pclose (pin);
+      val = pclose (pin);
+      if (val == -1)
+       sysval = 127;
+      else if (WIFEXITED (val))
+       sysval = WEXITSTATUS (val);
+      else if (WIFSIGNALED (val))
+       sysval = WTERMSIG (val) * 256;
+      else
+       sysval = 127;
     }
 }
 
 static void
 m4_sysval (struct obstack *obs, int argc, token_data **argv)
 {
-  shipout_int (obs, WEXITSTATUS (sysval));
+  shipout_int (obs, sysval);
 }
 
 /*-------------------------------------------------------------------------.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]