+2001-10-10 Bruno Haible <haible@clisp.cons.org>
+
+ * wait-process.h (wait_subprocess): New argument 'exit_on_error'.
+ * wait-process.c (wait_subprocess): Implement 'exit_on_error' handling.
+ Treat exitcode 127 like a failure to create the subprocess.
+ * execute.h (execute): New argument 'exit_on_error'.
+ * execute.c (execute): Implement 'exit_on_error' handling.
+ * pipe.h (create_pipe_out, create_pipe_in, create_pipe_bidi): New
+ arguments 'null_stderr' and 'exit_on_error'.
+ * pipe-in.c (create_pipe_in): Implement 'null_stderr' and
+ 'exit_on_error' handling.
+ * pipe-out.c (create_pipe_out): Likewise.
+ * pipe-bidi.c (create_pipe_bidi): Likewise.
+ * javacomp.c: Include pipe.h, wait-process.h, safe-read.h.
+ (compile_java_class): Update for changed execute(). When testing for
+ gcj, ignore gcj version 2.xx, require at least gcj 3.0.
+ * javaexec.c (execute_java_class): Update for changed execute().
+ * Makefile.am (libnlsut_a_SOURCES): Add safe-read.c.
+ (libnlsut_a_HEADER): Add safe-read.h.
+ (UNUSED_SOURCE): Remove safe-read.c.
+ (UNUSED_HEADER): Remove safe-read.h.
+
2001-09-25 Bruno Haible <haible@clisp.cons.org>
Upgrade to automake-1.5.
libnlsut_a_SOURCES = addext.c argmatch.c backupfile.c basename.c c-ctype.c \
concatpath.c copy-file.c execute.c findprog.c fstrcmp.c full-write.c gcd.c \
getopt.c getopt1.c hash.c javacomp.c javaexec.c linebreak.c localcharset.c \
-mbswidth.c obstack.c pipe-bidi.c pipe-in.c pipe-out.c progname.c sh-quote.c \
-tmpdir.c wait-process.c xerror.c xgetcwd.c xmalloc.c xstrdup.c
+mbswidth.c obstack.c pipe-bidi.c pipe-in.c pipe-out.c progname.c safe-read.c \
+sh-quote.c tmpdir.c wait-process.c xerror.c xgetcwd.c xmalloc.c xstrdup.c
libnlsut_a_HEADER = argmatch.h backupfile.h basename.h c-ctype.h copy-file.h \
execute.h findprog.h fstrcmp.h full-write.h gcd.h getopt.h hash.h javacomp.h \
javaexec.h lbrkprop.h linebreak.h mbswidth.h obstack.h pathmax.h pipe.h \
-progname.h sh-quote.h system.h tmpdir.h utf8-ucs4.h utf16-ucs4.h \
+progname.h safe-read.h sh-quote.h system.h tmpdir.h utf8-ucs4.h utf16-ucs4.h \
wait-process.h xerror.h xmalloc.h
# Sources that are compiled only on platforms that lack the functions.
# Unused sources.
-UNUSED_SOURCE = memmove.c safe-read.c
+UNUSED_SOURCE = memmove.c
-UNUSED_HEADER = safe-read.h
+UNUSED_HEADER =
libnlsut_a_LIBADD = @ALLOCA@ @LIBOBJS@
/* Execute a command, optionally redirecting any of the three standard file
- descriptors to /dev/null. Exit if it didn't terminate correctly.
- Otherwise return its exit code. */
+ descriptors to /dev/null. Return its exit code.
+ If it didn't terminate correctly, exit if exit_on_error is true, otherwise
+ return 127. */
int
-execute (progname, prog_path, prog_argv, null_stdin, null_stdout, null_stderr)
+execute (progname, prog_path, prog_argv, null_stdin, null_stdout, null_stderr, exit_on_error)
const char *progname;
const char *prog_path;
char **prog_argv;
bool null_stdin;
bool null_stdout;
bool null_stderr;
+ bool exit_on_error;
{
+ /* Note about 127: Some errors during posix_spawnp() cause the function
+ posix_spawnp() to return an error code; some other errors cause the
+ subprocess to exit with return code 127. It is implementation
+ dependent which error is reported which way. We treat both cases as
+ equivalent. */
#if HAVE_POSIX_SPAWN
posix_spawn_file_actions_t actions;
+ bool actions_allocated;
int err;
pid_t child;
#else
#endif
#if HAVE_POSIX_SPAWN
+ actions_allocated = false;
if ((err = posix_spawn_file_actions_init (&actions)) != 0
- || (null_stdin
- && (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO,
- "/dev/null", O_RDONLY, 0))
- != 0)
- || (null_stdout
- && (err = posix_spawn_file_actions_addopen (&actions, STDOUT_FILENO,
- "/dev/null", O_RDWR, 0))
- != 0)
- || (null_stderr
- && (err = posix_spawn_file_actions_addopen (&actions, STDERR_FILENO,
- "/dev/null", O_RDWR, 0))
- != 0)
- || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
- environ)) != 0)
- error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ || (actions_allocated = true,
+ (null_stdin
+ && (err = posix_spawn_file_actions_addopen (&actions,
+ STDIN_FILENO,
+ "/dev/null", O_RDONLY,
+ 0))
+ != 0)
+ || (null_stdout
+ && (err = posix_spawn_file_actions_addopen (&actions,
+ STDOUT_FILENO,
+ "/dev/null", O_RDWR,
+ 0))
+ != 0)
+ || (null_stderr
+ && (err = posix_spawn_file_actions_addopen (&actions,
+ STDERR_FILENO,
+ "/dev/null", O_RDWR,
+ 0))
+ != 0)
+ || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
+ environ))
+ != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ if (exit_on_error)
+ error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ else
+ return 127;
+ }
posix_spawn_file_actions_destroy (&actions);
#else
/* Use vfork() instead of fork() for efficiency. */
_exit (-1);
}
if (child == -1)
- error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ {
+ if (exit_on_error)
+ error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ else
+ return 127;
+ }
#endif
- return wait_subprocess (child, progname);
+ return wait_subprocess (child, progname, exit_on_error);
}
#include <stdbool.h>
/* Execute a command, optionally redirecting any of the three standard file
- descriptors to /dev/null. Exit if it didn't terminate correctly.
- Otherwise return its exit code. */
+ descriptors to /dev/null. Return its exit code.
+ If it didn't terminate correctly, exit if exit_on_error is true, otherwise
+ return 127. */
extern int execute PARAMS ((const char *progname,
const char *prog_path, char **prog_argv,
bool null_stdin,
- bool null_stdout, bool null_stderr));
+ bool null_stdout, bool null_stderr,
+ bool exit_on_error));
#endif /* _EXECUTE_H */
#include <string.h>
#include "execute.h"
+#include "pipe.h"
+#include "wait-process.h"
#include "setenv.h"
#include "sh-quote.h"
+#include "safe-read.h"
#include "xmalloc.h"
#include "error.h"
#include "libgettext.h"
Program from A C O g T
$JAVAC unknown N n/a -O -g true
- gcj -C GCC 3.0 Y --classpath=P -O -g gcj --version >/dev/null
+ gcj -C GCC 3.0 Y --classpath=P -O -g gcj --version | grep '^[3-9]' >/dev/null
javac JDK 1.1.8 Y -classpath P -O -g javac 2>/dev/null; test $? = 1
javac JDK 1.3.0 Y -classpath P -O -g javac 2>/dev/null; test $? -le 2
jikes Jikes 1.14 N -classpath P -O -g jikes 2>/dev/null; test $? = 1
argv[1] = "-c";
argv[2] = command;
argv[3] = NULL;
- exitstatus = execute (javac, "/bin/sh", argv, false, false, false);
+ exitstatus = execute (javac, "/bin/sh", argv, false, false, false,
+ true);
err = (exitstatus != 0);
/* Reset CLASSPATH. */
if (!gcj_tested)
{
- /* Test for presence of gcj: "gcj --version > /dev/null" */
+ /* Test for presence of gcj:
+ "gcj --version 2> /dev/null | grep '^[3-9]' > /dev/null" */
char *argv[3];
+ pid_t child;
+ int fd[1];
int exitstatus;
argv[0] = "gcj";
argv[1] = "--version";
argv[2] = NULL;
- exitstatus = execute ("gcj", "gcj", argv, false, true, true);
- gcj_present = (exitstatus == 0);
+ child = create_pipe_in ("gcj", "gcj", argv, "/dev/null", true, false,
+ fd);
+ gcj_present = false;
+ if (child != -1)
+ {
+ /* Read the subprocess output, a single line, and test whether
+ it starts with a digit >= 3. */
+ char c;
+
+ if (safe_read (fd[0], &c, 1) > 0)
+ gcj_present = (c >= '3' && c <= '9');
+ while (safe_read (fd[0], &c, 1) > 0)
+ ;
+
+ close (fd[0]);
+
+ /* Remove zombie process from process list, and retrieve exit
+ status. */
+ exitstatus = wait_subprocess (child, "gcj", false);
+ if (exitstatus != 0)
+ gcj_present = false;
+ }
gcj_tested = true;
}
free (command);
}
- exitstatus = execute ("gcj", "gcj", argv, false, false, false);
+ exitstatus = execute ("gcj", "gcj", argv, false, false, false, true);
err = (exitstatus != 0);
/* Reset CLASSPATH. */
argv[0] = "javac";
argv[1] = NULL;
- exitstatus = execute ("javac", "javac", argv, false, true, true);
+ exitstatus = execute ("javac", "javac", argv, false, true, true,
+ false);
javac_present = (exitstatus == 0 || exitstatus == 1 || exitstatus == 2);
javac_tested = true;
}
free (command);
}
- exitstatus = execute ("javac", "javac", argv, false, false, false);
+ exitstatus = execute ("javac", "javac", argv, false, false, false,
+ true);
err = (exitstatus != 0);
/* Reset CLASSPATH. */
argv[0] = "jikes";
argv[1] = NULL;
- exitstatus = execute ("jikes", "jikes", argv, false, true, true);
+ exitstatus = execute ("jikes", "jikes", argv, false, true, true,
+ false);
jikes_present = (exitstatus == 0 || exitstatus == 1);
jikes_tested = true;
}
free (command);
}
- exitstatus = execute ("jikes", "jikes", argv, false, false, false);
+ exitstatus = execute ("jikes", "jikes", argv, false, false, false,
+ true);
err = (exitstatus != 0);
/* Reset CLASSPATH. */
argv[0] = "gij";
argv[1] = "--version";
argv[2] = NULL;
- exitstatus = execute ("gij", "gij", argv, false, true, true);
+ exitstatus = execute ("gij", "gij", argv, false, true, true, false);
gij_present = (exitstatus == 0);
gij_tested = true;
}
argv[0] = "java";
argv[1] = "-version";
argv[2] = NULL;
- exitstatus = execute ("java", "java", argv, false, true, true);
+ exitstatus = execute ("java", "java", argv, false, true, true, false);
java_present = (exitstatus == 0);
java_tested = true;
}
argv[0] = "jre";
argv[1] = NULL;
- exitstatus = execute ("jre", "jre", argv, false, true, true);
+ exitstatus = execute ("jre", "jre", argv, false, true, true, false);
jre_present = (exitstatus == 0 || exitstatus == 1);
jre_tested = true;
}
argv[0] = "jview";
argv[1] = "-?";
argv[2] = NULL;
- exitstatus = execute ("jview", "jview", argv, false, true, true);
+ exitstatus = execute ("jview", "jview", argv, false, true, true,
+ false);
jview_present = (exitstatus == 0 || exitstatus == 1);
jview_tested = true;
}
#include "pipe.h"
#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
*
*/
pid_t
-create_pipe_bidi (progname, prog_path, prog_argv, fd)
+create_pipe_bidi (progname, prog_path, prog_argv, null_stderr, exit_on_error, fd)
const char *progname;
const char *prog_path;
char **prog_argv;
+ bool null_stderr;
+ bool exit_on_error;
int fd[2];
{
int ifd[2];
int ofd[2];
#if HAVE_POSIX_SPAWN
posix_spawn_file_actions_t actions;
+ bool actions_allocated;
int err;
pid_t child;
#else
*/
#if HAVE_POSIX_SPAWN
+ actions_allocated = false;
if ((err = posix_spawn_file_actions_init (&actions)) != 0
- || (err = posix_spawn_file_actions_adddup2 (&actions,
- ofd[0], STDIN_FILENO)) != 0
- || (err = posix_spawn_file_actions_adddup2 (&actions,
- ifd[1], STDOUT_FILENO)) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0
- || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
- environ)) != 0)
- error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ || (actions_allocated = true,
+ (err = posix_spawn_file_actions_adddup2 (&actions,
+ ofd[0], STDIN_FILENO)) != 0
+ || (err = posix_spawn_file_actions_adddup2 (&actions,
+ ifd[1], STDOUT_FILENO))
+ != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0
+ || (null_stderr
+ && (err = posix_spawn_file_actions_addopen (&actions,
+ STDERR_FILENO,
+ "/dev/null", O_RDWR,
+ 0))
+ != 0)
+ || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
+ environ)) != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ if (exit_on_error)
+ error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ else
+ {
+ close (ifd[0]);
+ close (ifd[1]);
+ close (ofd[0]);
+ close (ofd[1]);
+ return -1;
+ }
+ }
posix_spawn_file_actions_destroy (&actions);
#else
/* Use vfork() instead of fork() for efficiency. */
&& close (ofd[0]) >= 0
&& close (ifd[1]) >= 0
&& close (ofd[1]) >= 0
- && close (ifd[0]) >= 0)
+ && close (ifd[0]) >= 0
+ && (!null_stderr
+ || ((nulloutfd = open ("/dev/null", O_RDWR, 0)) >= 0
+ && (nulloutfd == STDERR_FILENO
+ || (dup2 (nulloutfd, STDERR_FILENO) >= 0
+ && close (nulloutfd) >= 0)))))
execvp (prog_path, prog_argv);
_exit (-1);
}
if (child == -1)
- error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ {
+ if (exit_on_error)
+ error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ else
+ {
+ close (ifd[0]);
+ close (ifd[1]);
+ close (ofd[0]);
+ close (ofd[1]);
+ return -1;
+ }
+ }
#endif
close (ofd[0]);
close (ifd[1]);
*
*/
pid_t
-create_pipe_in (progname, prog_path, prog_argv, prog_stdin, fd)
+create_pipe_in (progname, prog_path, prog_argv, prog_stdin, null_stderr, exit_on_error, fd)
const char *progname;
const char *prog_path;
char **prog_argv;
const char *prog_stdin;
+ bool null_stderr;
+ bool exit_on_error;
int fd[1];
{
int ifd[2];
#if HAVE_POSIX_SPAWN
posix_spawn_file_actions_t actions;
+ bool actions_allocated;
int err;
pid_t child;
#else
*/
#if HAVE_POSIX_SPAWN
+ actions_allocated = false;
if ((err = posix_spawn_file_actions_init (&actions)) != 0
- || (err = posix_spawn_file_actions_adddup2 (&actions,
- ifd[1], STDOUT_FILENO)) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0
- || (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO,
- prog_stdin, O_RDONLY,
- 0)) != 0
- || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
- environ)) != 0)
- error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ || (actions_allocated = true,
+ (err = posix_spawn_file_actions_adddup2 (&actions,
+ ifd[1], STDOUT_FILENO)) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0
+ || (null_stderr
+ && (err = posix_spawn_file_actions_addopen (&actions,
+ STDERR_FILENO,
+ "/dev/null", O_RDWR,
+ 0))
+ != 0)
+ || (err = posix_spawn_file_actions_addopen (&actions,
+ STDIN_FILENO,
+ prog_stdin, O_RDONLY,
+ 0)) != 0
+ || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
+ environ)) != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ if (exit_on_error)
+ error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ else
+ {
+ close (ifd[0]);
+ close (ifd[1]);
+ return -1;
+ }
+ }
posix_spawn_file_actions_destroy (&actions);
#else
/* Use vfork() instead of fork() for efficiency. */
{
/* Child process code. */
int stdinfd;
+ int nulloutfd;
if (dup2 (ifd[1], STDOUT_FILENO) >= 0
&& close (ifd[1]) >= 0
&& close (ifd[0]) >= 0
+ && (!null_stderr
+ || ((nulloutfd = open ("/dev/null", O_RDWR, 0)) >= 0
+ && (nulloutfd == STDERR_FILENO
+ || (dup2 (nulloutfd, STDERR_FILENO) >= 0
+ && close (nulloutfd) >= 0))))
&& (stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
&& (stdinfd == STDIN_FILENO
|| (dup2 (stdinfd, STDIN_FILENO) >= 0
_exit (-1);
}
if (child == -1)
- error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ {
+ if (exit_on_error)
+ error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ else
+ {
+ close (ifd[0]);
+ close (ifd[1]);
+ return -1;
+ }
+ }
#endif
close (ifd[1]);
*
*/
pid_t
-create_pipe_out (progname, prog_path, prog_argv, prog_stdout, fd)
+create_pipe_out (progname, prog_path, prog_argv, prog_stdout, null_stderr, exit_on_error, fd)
const char *progname;
const char *prog_path;
char **prog_argv;
const char *prog_stdout;
+ bool null_stderr;
+ bool exit_on_error;
int fd[1];
{
int ofd[2];
#if HAVE_POSIX_SPAWN
posix_spawn_file_actions_t actions;
+ bool actions_allocated;
int err;
pid_t child;
#else
*/
#if HAVE_POSIX_SPAWN
+ actions_allocated = false;
if ((err = posix_spawn_file_actions_init (&actions)) != 0
- || (err = posix_spawn_file_actions_adddup2 (&actions,
- ofd[0], STDIN_FILENO)) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0
- || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
- || (err = posix_spawn_file_actions_addopen (&actions, STDOUT_FILENO,
- prog_stdout, O_WRONLY,
- 0)) != 0
- || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
- environ)) != 0)
- error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ || (actions_allocated = true,
+ (err = posix_spawn_file_actions_adddup2 (&actions,
+ ofd[0], STDIN_FILENO)) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
+ || (null_stderr
+ && (err = posix_spawn_file_actions_addopen (&actions,
+ STDERR_FILENO,
+ "/dev/null", O_RDWR,
+ 0))
+ != 0)
+ || (err = posix_spawn_file_actions_addopen (&actions,
+ STDOUT_FILENO,
+ prog_stdout, O_WRONLY,
+ 0)) != 0
+ || (err = posix_spawnp (&child, prog_path, &actions, NULL, prog_argv,
+ environ)) != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ if (exit_on_error)
+ error (EXIT_FAILURE, err, _("%s subprocess failed"), progname);
+ else
+ {
+ close (ofd[0]);
+ close (ofd[1]);
+ return -1;
+ }
+ }
posix_spawn_file_actions_destroy (&actions);
#else
/* Use vfork() instead of fork() for efficiency. */
if (dup2 (ofd[0], STDIN_FILENO) >= 0
&& close (ofd[0]) >= 0
&& close (ofd[1]) >= 0
+ && (!null_stderr
+ || ((nulloutfd = open ("/dev/null", O_RDWR, 0)) >= 0
+ && (nulloutfd == STDERR_FILENO
+ || (dup2 (nulloutfd, STDERR_FILENO) >= 0
+ && close (nulloutfd) >= 0))))
&& (stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
&& (stdoutfd == STDOUT_FILENO
|| (dup2 (stdoutfd, STDOUT_FILENO) >= 0
_exit (-1);
}
if (child == -1)
- error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ {
+ if (exit_on_error)
+ error (EXIT_FAILURE, errno, _("%s subprocess failed"), progname);
+ else
+ {
+ close (ifd[0]);
+ close (ifd[1]);
+ return -1;
+ }
+ }
#endif
close (ofd[0]);
#endif
#include <sys/types.h>
+#include <stdbool.h>
+
+/* All these functions create a subprocess and don't wait for its termination.
+ They return the process id of the subprocess. They also return in fd[]
+ one or two file descriptors for communication with the subprocess.
+ If the subprocess creation fails: if exit_on_error is true, the main
+ process exits with an error message; otherwise, -1 is returned and fd[]
+ remain uninitialized.
+
+ After finishing communication, the caller should call wait_subprocess()
+ to get rid of the subprocess in the process table.
+
+ If exit_on_error is false, a child process id of -1 should be treated the
+ same way as a subprocess which accepts no input, produces no output and
+ terminates with exit code 127. Why? Some errors during posix_spawnp()
+ cause the function posix_spawnp() to return an error code; some other
+ errors cause the subprocess to exit with return code 127. It is
+ implementation dependent which error is reported which way. The caller
+ must treat both cases as equivalent. */
+
/* Open a pipe for output to a child process.
* The child's stdout goes to a file.
*
*/
extern pid_t create_pipe_out PARAMS ((const char *progname,
const char *prog_path, char **prog_argv,
- const char *prog_stdout,
+ const char *prog_stdout, bool null_stderr,
+ bool exit_on_error,
int fd[1]));
/* Open a pipe for input from a child process.
*/
extern pid_t create_pipe_in PARAMS ((const char *progname,
const char *prog_path, char **prog_argv,
- const char *prog_stdin,
+ const char *prog_stdin, bool null_stderr,
+ bool exit_on_error,
int fd[1]));
/* Open a bidirectional pipe.
*/
extern pid_t create_pipe_bidi PARAMS ((const char *progname,
const char *prog_path, char **prog_argv,
+ bool null_stderr,
+ bool exit_on_error,
int fd[2]));
#endif /* _PIPE_H */
int
-wait_subprocess (child, progname)
+wait_subprocess (child, progname, exit_on_error)
pid_t child;
const char *progname;
+ bool exit_on_error;
{
/* waitpid() is just as portable as wait() nowadays. */
WAIT_T status;
break;
}
#endif
- error (EXIT_FAILURE, errno, _("%s subprocess"), progname);
+ if (exit_on_error)
+ error (EXIT_FAILURE, errno, _("%s subprocess"), progname);
+ else
+ return 127;
}
if (!WIFSTOPPED (status))
}
if (WCOREDUMP (status) || WTERMSIG (status) != 0)
- error (EXIT_FAILURE, 0, _("%s subprocess got fatal signal"), progname);
+ {
+ if (exit_on_error)
+ error (EXIT_FAILURE, 0, _("%s subprocess got fatal signal"), progname);
+ else
+ return 127;
+ }
+ if (WEXITSTATUS (status) == 127)
+ {
+ if (exit_on_error)
+ error (EXIT_FAILURE, 0, _("%s subprocess failed"), progname);
+ else
+ return 127;
+ }
return WEXITSTATUS (status);
}
#endif
#include <sys/types.h>
-/* Wait for a subprocess to finish. Exit if it didn't terminate
- correctly. Otherwise return its exit code. */
-extern int wait_subprocess PARAMS ((pid_t child, const char *progname));
+#include <stdbool.h>
+
+/* Wait for a subprocess to finish. Return its exit code.
+ If it didn't terminate correctly, exit if exit_on_error is true, otherwise
+ return 127. */
+extern int wait_subprocess PARAMS ((pid_t child, const char *progname,
+ bool exit_on_error));
#endif /* _WAIT_PROCESS_H */
+2001-10-10 Bruno Haible <haible@clisp.cons.org>
+
+ * javacomp.m4 (gt_JAVACOMP): Ignore gcj version 2.xx, require at least
+ gcj 3.0.
+
2001-09-27 Bruno Haible <haible@clisp.cons.org>
* gettext.m4 (AM_GNU_GETTEXT): Inline AM_WITH_NLS call.
if test -n "$JAVAC"; then
ac_result="$JAVAC"
else
- if gcj --version >/dev/null 2>/dev/null; then
+ if gcj --version 2>/dev/null | grep '^[3-9]' >/dev/null; then
HAVE_GCJ=1
ac_result="gcj -C"
else
+2001-10-10 Bruno Haible <haible@clisp.cons.org>
+
+ * msgexec.c (process_string): Update for changed create_pipe_bidi(),
+ wait_subprocess().
+ * msggrep.c (is_string_selected): Update for changed create_pipe_out(),
+ wait_subprocess().
+ * read-java.c (execute_and_read_po_output): Update for changed
+ create_pipe_in(), wait_subprocess().
+
2001-01-08 Bruno Haible <haible@clisp.cons.org>
* xgettext.c (remember_a_message): When the comment tag is seen,
int exitstatus;
/* Open a bidirectional pipe to a subprocess. */
- child = create_pipe_bidi (sub_name, sub_path, sub_argv, fd);
+ child = create_pipe_bidi (sub_name, sub_path, sub_argv, false, true, fd);
/* Enable non-blocking I/O. This permits the read() and write() calls
to return -1/EAGAIN without blocking; this is important for polling
close (fd[0]);
/* Remove zombie process from process list. */
- exitstatus = wait_subprocess (child, sub_name);
+ exitstatus = wait_subprocess (child, sub_name, true);
if (exitstatus != 0)
error (EXIT_FAILURE, 0, _("%s subprocess terminated with exit code %d"),
sub_name, exitstatus);
/* Open a pipe to a grep subprocess. */
child = create_pipe_out ("grep", grep_path, grep_argv[grep_pass],
- "/dev/null", fd);
+ "/dev/null", false, true, fd);
nwritten = full_write (fd[0], str, len);
if (nwritten != (ssize_t) len)
close (fd[0]);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, "grep");
+ exitstatus = wait_subprocess (child, "grep", true);
return (exitstatus == 0);
}
else
int exitstatus;
/* Open a pipe to the JVM. */
- child = create_pipe_in (progname, prog_path, prog_argv, "/dev/null", fd);
+ child = create_pipe_in (progname, prog_path, prog_argv, "/dev/null", false,
+ true, fd);
fp = fdopen (fd[0], "r");
if (fp == NULL)
fclose (fp);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, progname);
+ exitstatus = wait_subprocess (child, progname, true);
if (exitstatus != 0)
error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"),
progname, exitstatus);