[Top][All Lists]
[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);
}
/*-------------------------------------------------------------------------.
- Re: sysval and doc fixes [was: GNU M4 1.4.4b released (beta release)],
Eric Blake <=