m4-discuss
[Top][All Lists]
Advanced

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

Re: system(), Solaris, and the 'execute' module


From: Bruno Haible
Subject: Re: system(), Solaris, and the 'execute' module
Date: Sun, 1 Jun 2008 11:58:21 +0200
User-agent: KMail/1.5.4

Hi Eric,

> | It seems that your problem is that you want execute a script via system()
> | and at the same time force a particular shell, namely the $CONFIG_SHELL 
> found
> | at configure time?
> 
> Something along those lines - POSIX doesn't require m4 to use system(2),
> merely that it treat the argument to the syscmd macro as a shell command.
>   But if you want a POSIX-compliant m4 on Solaris, then syscmd must not use
> /bin/sh, since /bin/sh doesn't obey the POSIX rules of parsing shell
> commands.

What about OSF/1 4.0 and 5.1? On these systems, CONFIG_SHELL gets set to
/bin/ksh. I take this as an indication that /bin/sh is not POSIX conforming
either. The manual pages of system() and popen() don't give an indication
how to influence which shell these functions use.

> | 3) You are assuming a program being built. But gnulib is also used to build
> |    libraries, such as libgettextpo or Simon's crypto libraries. What effect
> |    would it have to put values-xpg4.o into such a shared library? It would
> |    probably cause a change of behaviour to _all_ programs linked with such a
> |    library.
> 
> Good points.  But all it can do is make the program more likely to be
> POSIX compliant.  In other words, I'm not yet convinced that always using
> xpg4 semantics is bad.

But when we offer gnulib as a library, some things - like whether to use
XPG4 semantics or not - must remain among the freedom of the user of the
library.

> | and use the 'execute'
> | module instead. It allows you to specify the program to be launched 
> explicitly,
> | without any hacks.
> 
> Does the execute module allow distinguishing exits due to signals from
> regular exits?  M4 is currently documented as treating the sysval macro
> differently to allow the user to distinguish between signals, but it looks
> like wait_subprocess collapses all non-fatal signals into 127

Currently the 'execute' module indeed does not allow to distinguish between
launch failure and fatal signals. I could imagine to provide this info through
an optional parameter. But how do you want to treat the portability problem
to mingw here?

How does m4 treat mingw at all? Which shell does it use in 'syscmd' and
'esyscmd'?

> Also, m4 currently uses both system (for syscmd) and popen (for esyscmd);
> it looks like the pipe module (specifically create_pipe_in) is the
> counterpart for esyscmd (although it uses fd rather than FILE *, so it
> would need some wrapping with fdopen before being used in m4).

Yes, popen "r" is essentially equivalent to create_pipe_in() and fdopen().

> it looks like execute.c blindly undefines open, but this conflicts with
> "fcntl--.h" from the fcntl-safer module.  Does the code properly make sure
> that if fd 0, 1, and/or 2 were closed before creating the child process,
> that the new fds created for communication with the child do not interfere
> with the three automatic stdio streams?

I think that the open() calls are protected by dup2() and close(), but indeed
there is a problem with the file descriptors created by the pipe() call. Fixed
as shown below.

Bruno


2008-06-01  Bruno Haible  <address@hidden>

        * lib/pipe.c: Include unistd-safer.h.
        (create_pipe): Ensure the returned file descriptors are not in {0,1,2}.
        * modules/pipe (Depends-on): Add unistd-safer.

*** lib/pipe.c.orig     2008-06-01 11:54:43.000000000 +0200
--- lib/pipe.c  2008-06-01 11:53:20.000000000 +0200
***************
*** 29,34 ****
--- 29,35 ----
  
  #include "error.h"
  #include "fatal-signal.h"
+ #include "unistd-safer.h"
  #include "wait-process.h"
  #include "gettext.h"
  
***************
*** 147,156 ****
    prog_argv = prepare_spawn (prog_argv);
  
    if (pipe_stdout)
!     if (_pipe (ifd, 4096, O_BINARY | O_NOINHERIT) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
    if (pipe_stdin)
!     if (_pipe (ofd, 4096, O_BINARY | O_NOINHERIT) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
  /* Data flow diagram:
   *
--- 148,159 ----
    prog_argv = prepare_spawn (prog_argv);
  
    if (pipe_stdout)
!     if (_pipe (ifd, 4096, O_BINARY | O_NOINHERIT) < 0
!       || (ifd[0] = fd_safer (ifd[0])) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
    if (pipe_stdin)
!     if (_pipe (ofd, 4096, O_BINARY | O_NOINHERIT) < 0
!       || (ofd[1] = fd_safer (ofd[1])) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
  /* Data flow diagram:
   *
***************
*** 254,263 ****
  # endif
  
    if (pipe_stdout)
!     if (pipe (ifd) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
    if (pipe_stdin)
!     if (pipe (ofd) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
  /* Data flow diagram:
   *
--- 257,268 ----
  # endif
  
    if (pipe_stdout)
!     if (pipe (ifd) < 0
!       || (ifd[0] = fd_safer (ifd[0])) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
    if (pipe_stdin)
!     if (pipe (ofd) < 0
!       || (ofd[1] = fd_safer (ofd[1])) < 0)
        error (EXIT_FAILURE, errno, _("cannot create pipe"));
  /* Data flow diagram:
   *
*** modules/pipe.orig   2008-06-01 11:54:43.000000000 +0200
--- modules/pipe        2008-06-01 11:35:05.000000000 +0200
***************
*** 16,21 ****
--- 16,22 ----
  stdbool
  strpbrk
  unistd
+ unistd-safer
  environ
  
  configure.ac:





reply via email to

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