diff options
author | Bruno Haible <bruno@clisp.org> | 2004-01-05 10:52:41 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-23 12:11:33 +0200 |
commit | 5c50e51761e92c0dd5ae178b8f00996951ad6fff (patch) | |
tree | 4e22b24b0ab5fe237ef05a5dc28065975891111f | |
parent | d0d82abfea6b3c6fdf29ec4cc460f8305cde95b4 (diff) | |
download | external_gettext-5c50e51761e92c0dd5ae178b8f00996951ad6fff.zip external_gettext-5c50e51761e92c0dd5ae178b8f00996951ad6fff.tar.gz external_gettext-5c50e51761e92c0dd5ae178b8f00996951ad6fff.tar.bz2 |
SIGPIPE handling in subprocesses.
-rw-r--r-- | gettext-tools/lib/ChangeLog | 9 | ||||
-rw-r--r-- | gettext-tools/lib/execute.c | 3 | ||||
-rw-r--r-- | gettext-tools/lib/execute.h | 4 | ||||
-rw-r--r-- | gettext-tools/lib/javacomp.c | 21 | ||||
-rw-r--r-- | gettext-tools/lib/javaexec.c | 16 | ||||
-rw-r--r-- | gettext-tools/lib/wait-process.c | 10 | ||||
-rw-r--r-- | gettext-tools/lib/wait-process.h | 18 | ||||
-rw-r--r-- | gettext-tools/src/ChangeLog | 13 | ||||
-rw-r--r-- | gettext-tools/src/msgexec.c | 4 | ||||
-rw-r--r-- | gettext-tools/src/msgfilter.c | 2 | ||||
-rw-r--r-- | gettext-tools/src/msggrep.c | 2 | ||||
-rw-r--r-- | gettext-tools/src/msginit.c | 8 | ||||
-rw-r--r-- | gettext-tools/src/read-java.c | 2 | ||||
-rw-r--r-- | gettext-tools/src/read-tcl.c | 2 | ||||
-rw-r--r-- | gettext-tools/src/urlget.c | 28 |
15 files changed, 97 insertions, 45 deletions
diff --git a/gettext-tools/lib/ChangeLog b/gettext-tools/lib/ChangeLog index 6ae58d6..554a0aa 100644 --- a/gettext-tools/lib/ChangeLog +++ b/gettext-tools/lib/ChangeLog @@ -1,3 +1,12 @@ +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. diff --git a/gettext-tools/lib/execute.c b/gettext-tools/lib/execute.c index 6abfc0a..86df308 100644 --- a/gettext-tools/lib/execute.c +++ b/gettext-tools/lib/execute.c @@ -117,6 +117,7 @@ nonintr_open (const char *pathname, int oflag, mode_t mode) 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) { @@ -306,7 +307,7 @@ execute (const char *progname, 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 diff --git a/gettext-tools/lib/execute.h b/gettext-tools/lib/execute.h index d0df8e4..18c9c43 100644 --- a/gettext-tools/lib/execute.h +++ b/gettext-tools/lib/execute.h @@ -25,12 +25,16 @@ 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); diff --git a/gettext-tools/lib/javacomp.c b/gettext-tools/lib/javacomp.c index 16aeaf8..f006254 100644 --- a/gettext-tools/lib/javacomp.c +++ b/gettext-tools/lib/javacomp.c @@ -163,7 +163,7 @@ compile_java_class (const char * const *java_sources, 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); @@ -239,7 +239,8 @@ compile_java_class (const char * const *java_sources, /* 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; } @@ -294,8 +295,8 @@ compile_java_class (const char * const *java_sources, 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); @@ -319,8 +320,8 @@ compile_java_class (const char * const *java_sources, 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; } @@ -372,7 +373,7 @@ compile_java_class (const char * const *java_sources, } exitstatus = execute ("javac", "javac", argv, false, false, false, - true, true); + false, true, true); err = (exitstatus != 0); freesa (argv); @@ -396,8 +397,8 @@ compile_java_class (const char * const *java_sources, 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; } @@ -451,7 +452,7 @@ compile_java_class (const char * const *java_sources, } exitstatus = execute ("jikes", "jikes", argv, false, false, false, - true, true); + false, true, true); err = (exitstatus != 0); freesa (argv); diff --git a/gettext-tools/lib/javaexec.c b/gettext-tools/lib/javaexec.c index 0f56840..2f9376e 100644 --- a/gettext-tools/lib/javaexec.c +++ b/gettext-tools/lib/javaexec.c @@ -211,8 +211,8 @@ execute_java_class (const char *class_name, 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; } @@ -264,8 +264,8 @@ execute_java_class (const char *class_name, 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; } @@ -318,8 +318,8 @@ execute_java_class (const char *class_name, 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; } @@ -375,8 +375,8 @@ execute_java_class (const char *class_name, 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; } diff --git a/gettext-tools/lib/wait-process.c b/gettext-tools/lib/wait-process.c index 9c042b3..0af9a18 100644 --- a/gettext-tools/lib/wait-process.c +++ b/gettext-tools/lib/wait-process.c @@ -252,7 +252,7 @@ unregister_slave_subprocess (pid_t child) 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 @@ -319,6 +319,10 @@ wait_subprocess (pid_t child, const char *progname, { 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"), @@ -382,6 +386,10 @@ wait_subprocess (pid_t child, const char *progname, 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"), diff --git a/gettext-tools/lib/wait-process.h b/gettext-tools/lib/wait-process.h index 2200142..0d117f3 100644 --- a/gettext-tools/lib/wait-process.h +++ b/gettext-tools/lib/wait-process.h @@ -36,9 +36,23 @@ extern "C" { /* 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 diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 894166a..b68bca8 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,16 @@ +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. diff --git a/gettext-tools/src/msgexec.c b/gettext-tools/src/msgexec.c index 4b3f422..424fd36 100644 --- a/gettext-tools/src/msgexec.c +++ b/gettext-tools/src/msgexec.c @@ -347,7 +347,9 @@ process_string (const message_ty *mp, const char *str, size_t len) 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; } diff --git a/gettext-tools/src/msgfilter.c b/gettext-tools/src/msgfilter.c index e7b418c..abe12be 100644 --- a/gettext-tools/src/msgfilter.c +++ b/gettext-tools/src/msgfilter.c @@ -679,7 +679,7 @@ process_string (const char *str, size_t len, char **resultp, size_t *lengthp) 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); diff --git a/gettext-tools/src/msggrep.c b/gettext-tools/src/msggrep.c index 7676270..0df46b6 100644 --- a/gettext-tools/src/msggrep.c +++ b/gettext-tools/src/msggrep.c @@ -605,7 +605,7 @@ is_string_selected (int grep_pass, const char *str, size_t len) 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 diff --git a/gettext-tools/src/msginit.c b/gettext-tools/src/msginit.c index 0aa4418..09646b4 100644 --- a/gettext-tools/src/msginit.c +++ b/gettext-tools/src/msginit.c @@ -953,7 +953,7 @@ project_id () 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"), @@ -1020,7 +1020,7 @@ project_id_version () 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"), @@ -1178,7 +1178,7 @@ you in case of unexpected technical problems.\n"); 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"), @@ -1257,7 +1257,7 @@ language_team_address () 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"), diff --git a/gettext-tools/src/read-java.c b/gettext-tools/src/read-java.c index d015e4d..b2c25d6 100644 --- a/gettext-tools/src/read-java.c +++ b/gettext-tools/src/read-java.c @@ -76,7 +76,7 @@ execute_and_read_po_output (const char *progname, 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); diff --git a/gettext-tools/src/read-tcl.c b/gettext-tools/src/read-tcl.c index 4d41678..99ef094 100644 --- a/gettext-tools/src/read-tcl.c +++ b/gettext-tools/src/read-tcl.c @@ -116,7 +116,7 @@ msgdomain_read_tcl (const char *locale_name, const char *directory) 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) diff --git a/gettext-tools/src/urlget.c b/gettext-tools/src/urlget.c index 700419b..c787826 100644 --- a/gettext-tools/src/urlget.c +++ b/gettext-tools/src/urlget.c @@ -229,8 +229,8 @@ execute_it (const char *progname, { (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; } @@ -287,8 +287,8 @@ fetch (const char *url, const char *file) 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; } @@ -304,8 +304,8 @@ fetch (const char *url, const char *file) 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) @@ -330,8 +330,8 @@ fetch (const char *url, const char *file) 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; } @@ -345,8 +345,8 @@ fetch (const char *url, const char *file) 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) @@ -371,8 +371,8 @@ fetch (const char *url, const char *file) 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; } @@ -386,8 +386,8 @@ fetch (const char *url, const char *file) 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) |