]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
SIGPIPE handling in subprocesses.
authorBruno Haible <bruno@clisp.org>
Mon, 5 Jan 2004 10:52:41 +0000 (10:52 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:11:33 +0000 (12:11 +0200)
15 files changed:
gettext-tools/lib/ChangeLog
gettext-tools/lib/execute.c
gettext-tools/lib/execute.h
gettext-tools/lib/javacomp.c
gettext-tools/lib/javaexec.c
gettext-tools/lib/wait-process.c
gettext-tools/lib/wait-process.h
gettext-tools/src/ChangeLog
gettext-tools/src/msgexec.c
gettext-tools/src/msgfilter.c
gettext-tools/src/msggrep.c
gettext-tools/src/msginit.c
gettext-tools/src/read-java.c
gettext-tools/src/read-tcl.c
gettext-tools/src/urlget.c

index 6ae58d663927daa0660b47e98c8642d91d8ef43f..554a0aadc1094b93236ccbe43652fc0cc4af2d3f 100644 (file)
@@ -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.
index 6abfc0a59bb3d1e46260f694736bcc672839eed0..86df308f2d20dc2504b21d327d154717a64b2313 100644 (file)
@@ -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
index d0df8e4e5184d4aa0392e3a635e5ec52e0d1b6c6..18c9c43264df6d248f50b6a2be5c5a9ff7a25602 100644 (file)
    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);
 
index 16aeaf8780e7d30f0f19b46fc954965cf545cce8..f00625467903686d184fe33af672a8329801ec31 100644 (file)
@@ -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);
index 0f56840b70a1e034c7fa845f6f35ae985e4ac1fa..2f9376e3e585db4cf1d46237f85a5539aaa3abe3 100644 (file)
@@ -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;
       }
index 9c042b3b4600617c5fdae5be0ab1e410eb26cc6d..0af9a183325bf1a050debaa246c6ea36d9c01679 100644 (file)
@@ -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"),
index 22001426368d3dd9a9d5ae25566ae1139f49019e..0d117f3b1af86ed0f8d560920613f2c009c4349a 100644 (file)
@@ -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
index 894166a8748daa4d554ea04b0ac702247e8e349d..b68bca81a7800658e51ce897197032862e897416 100644 (file)
@@ -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.
index 4b3f4221f5314fb4c3bbc9ac182d1196717f6275..424fd361af8162b9b38131fadff97f0c7206243d 100644 (file)
@@ -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;
     }
index e7b418c501ce381fc12a2c0fa506fd490707b666..abe12beb4375003dc6a1d40a1fa983b683fb1676 100644 (file)
@@ -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);
index 767627016874d9f1e86121ee7567b37f29eeb6e1..0df46b6add54425ada97179bbe091e6cfd44b433 100644 (file)
@@ -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
index 0aa4418c59aebe5cddb3e4bda51c185fd529f501..09646b4a3664e0cbbd8ef4c15abf8b81aa7eb9ec 100644 (file)
@@ -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"),
index d015e4db44b4f43f1df2c991386ec54e5ab3d519..b2c25d68392f254aef326a18ab9171afdb308604 100644 (file)
@@ -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);
index 4d41678306037bf7982df47f0d0be523b959851c..99ef094ab610f394ece15b4cc96f40bcf17d9f9c 100644 (file)
@@ -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)
index 700419be60fe3204e250359ec1b8373bfcdd5d2e..c7878268ac0821d8a3506a0edbf0f3cf95b256a9 100644 (file)
@@ -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)