+2003-12-28 Bruno Haible <bruno@clisp.org>
+
+ * wait-process.c (wait_subprocess): Add ignore_sigpipe argument.
+ * wait-process.c (wait_subprocess): Likewise. Handle SIGPIPE specially.
+ * execute.h (execute): Add ignore_sigpipe argument.
+ * execute.c (execute): Likewise.
+ * javacomp.c (compile_java_class): Always pass ignore_sigpipe = false.
+ * javaexec.c (execute_java_class): Likewise.
+
2003-09-12 Paul Eggert <eggert@twinsun.com>
* setenv.c (clearenv): Define via prototype.
int
execute (const char *progname,
const char *prog_path, char **prog_argv,
+ bool ignore_sigpipe,
bool null_stdin, bool null_stdout, bool null_stderr,
bool slave_process, bool exit_on_error)
{
unblock_fatal_signals ();
}
- return wait_subprocess (child, progname, null_stderr,
+ return wait_subprocess (child, progname, ignore_sigpipe, null_stderr,
slave_process, exit_on_error);
#endif
descriptors to /dev/null. Return its exit code.
If it didn't terminate correctly, exit if exit_on_error is true, otherwise
return 127.
+ If ignore_sigpipe is true, consider a subprocess termination due to SIGPIPE
+ as equivalent to a success. This is suitable for processes whose only
+ purpose is to write to standard output.
If slave_process is true, the child process will be terminated when its
creator receives a catchable fatal signal.
It is recommended that no signal is blocked or ignored while execute()
is called. See pipe.h for the reason. */
extern int execute (const char *progname,
const char *prog_path, char **prog_argv,
+ bool ignore_sigpipe,
bool null_stdin, bool null_stdout, bool null_stderr,
bool slave_process, bool exit_on_error);
argv[2] = command;
argv[3] = NULL;
exitstatus = execute (javac, "/bin/sh", argv, false, false, false,
- true, true);
+ false, true, true);
err = (exitstatus != 0);
freesa (command);
/* Remove zombie process from process list, and retrieve exit
status. */
- exitstatus = wait_subprocess (child, "gcj", true, true, false);
+ exitstatus =
+ wait_subprocess (child, "gcj", false, true, true, false);
if (exitstatus != 0)
gcj_present = false;
}
free (command);
}
- exitstatus = execute ("gcj", "gcj", argv, false, false, false, true,
- true);
+ exitstatus = execute ("gcj", "gcj", argv, false, false, false, false,
+ true, true);
err = (exitstatus != 0);
freesa (argv);
argv[0] = "javac";
argv[1] = NULL;
- exitstatus = execute ("javac", "javac", argv, false, true, true, true,
- false);
+ exitstatus = execute ("javac", "javac", argv, false, false, true, true,
+ true, false);
javac_present = (exitstatus == 0 || exitstatus == 1 || exitstatus == 2);
javac_tested = true;
}
}
exitstatus = execute ("javac", "javac", argv, false, false, false,
- true, true);
+ false, true, true);
err = (exitstatus != 0);
freesa (argv);
argv[0] = "jikes";
argv[1] = NULL;
- exitstatus = execute ("jikes", "jikes", argv, false, true, true, true,
- false);
+ exitstatus = execute ("jikes", "jikes", argv, false, false, true, true,
+ true, false);
jikes_present = (exitstatus == 0 || exitstatus == 1);
jikes_tested = true;
}
}
exitstatus = execute ("jikes", "jikes", argv, false, false, false,
- true, true);
+ false, true, true);
err = (exitstatus != 0);
freesa (argv);
argv[0] = "gij";
argv[1] = "--version";
argv[2] = NULL;
- exitstatus = execute ("gij", "gij", argv, false, true, true, true,
- false);
+ exitstatus = execute ("gij", "gij", argv, false, false, true, 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, true,
- false);
+ exitstatus = execute ("java", "java", argv, false, false, true, true,
+ true, false);
java_present = (exitstatus == 0);
java_tested = true;
}
argv[0] = "jre";
argv[1] = NULL;
- exitstatus = execute ("jre", "jre", argv, false, true, true, true,
- false);
+ exitstatus = execute ("jre", "jre", argv, false, false, true, 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, true,
- false);
+ exitstatus = execute ("jview", "jview", argv, false, false, true, true,
+ true, false);
jview_present = (exitstatus == 0 || exitstatus == 1);
jview_tested = true;
}
return 127. */
int
wait_subprocess (pid_t child, const char *progname,
- bool null_stderr,
+ bool ignore_sigpipe, bool null_stderr,
bool slave_process, bool exit_on_error)
{
#if HAVE_WAITID && defined WNOWAIT && 0
{
case CLD_KILLED:
case CLD_DUMPED:
+# ifdef SIGPIPE
+ if (info.si_status == SIGPIPE && ignore_sigpipe)
+ return 0;
+# endif
if (exit_on_error || !null_stderr)
error (exit_on_error ? EXIT_FAILURE : 0, 0,
_("%s subprocess got fatal signal %d"),
if (WIFSIGNALED (status))
{
+# ifdef SIGPIPE
+ if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe)
+ return 0;
+# endif
if (exit_on_error || !null_stderr)
error (exit_on_error ? EXIT_FAILURE : 0, 0,
_("%s subprocess got fatal signal %d"),
/* 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. */
+ return 127.
+ Arguments:
+ - child is the pid of the subprocess.
+ - progname is the name of the program executed by the subprocess, used for
+ error messages.
+ - If ignore_sigpipe is true, consider a subprocess termination due to
+ SIGPIPE as equivalent to a success. This is suitable for processes whose
+ only purpose is to write to standard output. This flag can be safely set
+ to false when the process' standard output is known to go to DEV_NULL.
+ - If null_stderr is true, the usual error message to stderr will be omitted.
+ This is suitable when the subprocess does not fulfill an important task.
+ - slave_process should be set to true if the process has been launched as a
+ slave process.
+ - If exit_on_error is true, any error will cause the main process to exit
+ with an error status. */
extern int wait_subprocess (pid_t child, const char *progname,
- bool null_stderr,
+ bool ignore_sigpipe, bool null_stderr,
bool slave_process, bool exit_on_error);
/* Register a subprocess as being a slave process. This means that the
+2003-12-28 Bruno Haible <bruno@clisp.org>
+
+ * msgexec.c (process_string): Pass ignore_sigpipe = false.
+ * msgfilter.c (process_string): Likewise.
+ * msggrep.c (is_string_selected): Likewise.
+ * msginit.c (project_id, project_id_version, get_user_email,
+ language_team_address): Likewise.
+ * read-java.c (execute_and_read_po_output): Likewise.
+ * read-tcl.c (msgdomain_read_tcl): Likewise.
+ * urlget.c (execute_it): Pass ignore_sigpipe = true.
+ (fetch): Pass ignore_sigpipe = true when fetching the file, = false
+ otherwise.
+
2003-12-14 Bruno Haible <bruno@clisp.org>
* x-c.c (SIZEOF): New macro.
close (fd[0]);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, sub_name, false, true, true);
+ /* FIXME: Should ignore_sigpipe be set to true here? It depends on the
+ semantics of the subprogram... */
+ exitstatus = wait_subprocess (child, sub_name, false, false, true, true);
if (exitcode < exitstatus)
exitcode = exitstatus;
}
close (fd[0]);
/* Remove zombie process from process list. */
- exitstatus = wait_subprocess (child, sub_name, false, true, true);
+ exitstatus = wait_subprocess (child, sub_name, false, false, true, true);
if (exitstatus != 0)
error (EXIT_FAILURE, 0, _("%s subprocess terminated with exit code %d"),
sub_name, exitstatus);
close (fd[0]);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, "grep", false, true, true);
+ exitstatus = wait_subprocess (child, "grep", false, false, true, true);
return (exitstatus == 0);
}
else
fclose (fp);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, prog, false, true, false);
+ exitstatus = wait_subprocess (child, prog, false, false, true, false);
if (exitstatus != 0)
{
error (0, 0, _("%s subprocess failed with exit code %d"),
fclose (fp);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, prog, false, true, false);
+ exitstatus = wait_subprocess (child, prog, false, false, true, false);
if (exitstatus != 0)
{
error (0, 0, _("%s subprocess failed with exit code %d"),
fclose (fp);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, prog, false, true, false);
+ exitstatus = wait_subprocess (child, prog, false, false, true, false);
if (exitstatus != 0)
{
error (0, 0, _("%s subprocess failed with exit code %d"),
fclose (fp);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, prog, false, true, false);
+ exitstatus = wait_subprocess (child, prog, false, false, true, false);
if (exitstatus != 0)
{
error (0, 0, _("%s subprocess failed with exit code %d"),
fclose (fp);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, progname, false, true, true);
+ exitstatus = wait_subprocess (child, progname, false, false, true, true);
if (exitstatus != 0)
error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"),
progname, exitstatus);
fclose (fp);
/* Remove zombie process from process list, and retrieve exit status. */
- exitstatus = wait_subprocess (child, "tclsh", false, true, true);
+ exitstatus = wait_subprocess (child, "tclsh", false, false, true, true);
if (exitstatus != 0)
{
if (exitstatus == 2)
{
(void) private_data;
- return execute (progname, prog_path, prog_argv, true, false, false, true,
- false)
+ return execute (progname, prog_path, prog_argv, true, true, false, false,
+ true, false)
!= 0;
}
argv[0] = "wget";
argv[1] = "--version";
argv[2] = NULL;
- exitstatus = execute ("wget", "wget", argv, false, true, true, true,
- false);
+ exitstatus = execute ("wget", "wget", argv, false, false, true, true,
+ true, false);
wget_present = (exitstatus == 0);
wget_tested = true;
}
argv[4] = "-T"; argv[5] = "30";
argv[6] = (char *) url;
argv[7] = NULL;
- exitstatus = execute ("wget", "wget", argv, false, false, false, true,
- false);
+ exitstatus = execute ("wget", "wget", argv, true, false, false, false,
+ true, false);
if (exitstatus != 127)
{
if (exitstatus != 0)
argv[0] = "lynx";
argv[1] = "--version";
argv[2] = NULL;
- exitstatus = execute ("lynx", "lynx", argv, false, true, true, true,
- false);
+ exitstatus = execute ("lynx", "lynx", argv, false, false, true, true,
+ true, false);
lynx_present = (exitstatus == 0);
lynx_tested = true;
}
argv[1] = "-source";
argv[2] = (char *) url;
argv[3] = NULL;
- exitstatus = execute ("lynx", "lynx", argv, false, false, false, true,
- false);
+ exitstatus = execute ("lynx", "lynx", argv, true, false, false, false,
+ true, false);
if (exitstatus != 127)
{
if (exitstatus != 0)
argv[0] = "curl";
argv[1] = "--version";
argv[2] = NULL;
- exitstatus = execute ("curl", "curl", argv, false, true, true, true,
- false);
+ exitstatus = execute ("curl", "curl", argv, false, false, true, true,
+ true, false);
curl_present = (exitstatus == 0 || exitstatus == 2);
curl_tested = true;
}
argv[1] = "--silent";
argv[2] = (char *) url;
argv[3] = NULL;
- exitstatus = execute ("curl", "curl", argv, false, false, false, true,
- false);
+ exitstatus = execute ("curl", "curl", argv, true, false, false, false,
+ true, false);
if (exitstatus != 127)
{
if (exitstatus != 0)