m4-patches
[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: Gary V. Vaughan
Subject: Re: sysval and doc fixes [was: GNU M4 1.4.4b released (beta release)]
Date: Wed, 21 Jun 2006 12:44:35 +0100
User-agent: Thunderbird 1.5.0.2 (X11/20060519)

Hi Eric!

[Cc: trimmed]

Eric Blake wrote:
> 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

$ config.guess
i686-pc-linux-gnu
$ m4 --version
GNU M4 1.4.4
Written by Rene' Seindal.

Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ perl -e 'print "syscmd(/bin/echo ".("a "x2000000).")sysval"' | m4
127

But that is due to:

RETURN VALUE
       The value returned is -1 on error (e.g.  fork() failed), and the return
       status  of  the command otherwise.  This latter return status is in the
       format specified in wait(2).  Thus, the exit code of the  command  will
       be  WEXITSTATUS(status).   In  case  /bin/sh could not be executed, the
       exit status will be that of a command that does exit(127).

...which may not be true of all platform the GNU M4 builds on.

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

Nice catch :-)

In theory, this means we can't tell the the difference between a system
call failure and killed by signal 127 (TERMSIG is status&0x7f)... but
this is definitely an improvement, so please commit after taking my comments
below into consideration.

> 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.

I would call this signal<<8 to make it clearer that the signal number
bitpattern is not changed.

>       * 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.

Please port forward too :-)

> +* If syscmd or esyscmd is terminated by a signal, sysval now reports the
> +  signal value times 256, rather than 0.

   signal value left shifted 8 bits, to avoid confusion with actual exit
   statuses.

> 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.

                                signal number left shifted by 8 bits.


We can simplify the changes to src/builtin.c, and remove some redundancy.
And fix an uninitialised variable if sysval is expanded before syscmd
is used:

...

#if HAVE_SYS_WAIT_H
#  include <sys/wait.h>
#endif

...
^L
/*------------------------------------------------------------------------.
| This section contains macros to handle the builtins "syscmd", "esyscmd" |
| and "sysval".  "esyscmd" is GNU specific.                               |
`------------------------------------------------------------------------*/

#ifndef WEXITSTATUS
# define WEXITSTATUS(status) (((status) >> 8) & 0xff)
#endif
#ifndef WTERMSIG
# define WTERMSIG(status) ((status) & 0x7f)
#endif

/* Exit code from last "syscmd" command.  */
static int sysval = 0;

...

static void
m4_sysval (struct obstack *obs, int argc, token_data **argv)
{
  /* If previous syscmd call exited, SYSVAL is the exit status;
     if syscmd was killed by a signal, SYSVAL is signal number times 256,
     if syscmd could not execute command, SYSVAL is 127,
     else SYSVAL is 0 */
  shipout_int (obs, sysval == -1
                      ? 0x7f
                      : ((WEXITSTATUS (sysval))|(WTERMSIG (sysval) << 8)));
}

Cheers,
        Gary.
-- 
Gary V. Vaughan      ())_.  address@hidden,gnu.org}
Research Scientist   ( '/   http://blog.azazil.net
GNU Hacker           / )=   http://trac.azazil.net/projects/libtool
Technical Author   `(_~)_   http://sources.redhat.com/autobook

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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