Add termsigp argument to execute() and wait_process().
authorBruno Haible <bruno@clisp.org>
Tue, 10 Jun 2008 15:38:39 +0000 (17:38 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 10 Jun 2008 15:39:26 +0000 (17:39 +0200)
ChangeLog
NEWS
lib/csharpcomp.c
lib/csharpexec.c
lib/execute.c
lib/execute.h
lib/javacomp.c
lib/javaexec.c
lib/javaversion.c
lib/wait-process.c
lib/wait-process.h

index 21f2937..2e60a11 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-06-10  Bruno Haible  <bruno@clisp.org>
+
+       * lib/wait-process.h (wait_subprocess): Add termsigp argument.
+       * lib/wait-process.c (wait_subprocess): Likewise.
+       * lib/execute.h (execute): Add termsigp argument.
+       * lib/execute.c (execute): Likewise.
+       * lib/csharpcomp.c (compile_csharp_using_pnet,
+       compile_csharp_using_mono, compile_csharp_using_sscli): Update.
+       * lib/csharpexec.c (execute_csharp_using_pnet,
+       execute_csharp_using_mono, execute_csharp_using_sscli): Update.
+       * lib/javacomp.c (compile_using_envjavac, compile_using_gcj,
+       compile_using_javac, compile_using_jikes, is_envjavac_gcj,
+       is_envjavac_gcj43, is_gcj_present, is_gcj_43, is_javac_present,
+       is_jikes_present): Update.
+       * lib/javaexec.c (execute_java_class): Update.
+       * lib/javaversion.c (execute_and_read_line): Update.
+       * NEWS: Document the changes.
+       Reported by Eric Blake.
+
 2008-06-10  Eric Blake  <ebb9@byu.net>
 
        Add missing include.
diff --git a/NEWS b/NEWS
index 6c7d4dd..75735e5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,11 @@ User visible incompatible changes
 
 Date        Modules         Changes
 
+2008-06-10  execute         The execute function takes an additional termsigp
+                            argument. Passing termsigp = NULL is ok.
+            wait-process    The wait_subprocess function takes an additional
+                            termsigp argument. Passing termsigp = NULL is ok.
+
 2008-05-10  linebreak       The module is split into several modules unilbrk/*.
                             The include file is changed from "linebreak.h" to
                             "unilbrk.h". Two functions are renamed:
index dc83985..1e84f05 100644 (file)
@@ -1,5 +1,5 @@
 /* Compile a C# program.
-   Copyright (C) 2003-2007 Free Software Foundation, Inc.
+   Copyright (C) 2003-2008 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -83,7 +83,7 @@ compile_csharp_using_pnet (const char * const *sources,
       argv[1] = "--version";
       argv[2] = NULL;
       exitstatus = execute ("cscc", "cscc", argv, false, false, true, true,
-                           true, false);
+                           true, false, NULL);
       cscc_present = (exitstatus == 0);
       cscc_tested = true;
     }
@@ -151,7 +151,7 @@ compile_csharp_using_pnet (const char * const *sources,
        }
 
       exitstatus = execute ("cscc", "cscc", argv, false, false, false, false,
-                           true, true);
+                           true, true, NULL);
 
       for (i = 0; i < sources_count; i++)
        if (argv[argc - sources_count + i] != sources[i])
@@ -219,7 +219,7 @@ compile_csharp_using_mono (const char * const *sources,
          /* Remove zombie process from process list, and retrieve exit
             status.  */
          exitstatus =
-           wait_subprocess (child, "mcs", false, true, true, false);
+           wait_subprocess (child, "mcs", false, true, true, false, NULL);
          if (exitstatus != 0)
            mcs_present = false;
        }
@@ -332,7 +332,8 @@ compile_csharp_using_mono (const char * const *sources,
       fclose (fp);
 
       /* Remove zombie process from process list, and retrieve exit status.  */
-      exitstatus = wait_subprocess (child, "mcs", false, false, true, true);
+      exitstatus =
+       wait_subprocess (child, "mcs", false, false, true, true, NULL);
 
       for (i = 1 + (output_is_library ? 1 : 0);
           i < 1 + (output_is_library ? 1 : 0)
@@ -408,7 +409,7 @@ compile_csharp_using_sscli (const char * const *sources,
          /* Remove zombie process from process list, and retrieve exit
             status.  */
          exitstatus =
-           wait_subprocess (child, "csc", false, true, true, false);
+           wait_subprocess (child, "csc", false, true, true, false, NULL);
          if (exitstatus != 0)
            csc_present = false;
        }
@@ -486,7 +487,7 @@ compile_csharp_using_sscli (const char * const *sources,
        }
 
       exitstatus = execute ("csc", "csc", argv, false, false, false, false,
-                           true, true);
+                           true, true, NULL);
 
       for (i = 2; i < 3 + libdirs_count + libraries_count; i++)
        freea (argv[i]);
index 88f06b9..c1fc27a 100644 (file)
@@ -1,5 +1,5 @@
 /* Execute a C# program.
-   Copyright (C) 2003-2007 Free Software Foundation, Inc.
+   Copyright (C) 2003-2008 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -109,7 +109,7 @@ execute_csharp_using_pnet (const char *assembly_path,
       argv[1] = "--version";
       argv[2] = NULL;
       exitstatus = execute ("ilrun", "ilrun", argv, false, false, true, true,
-                           true, false);
+                           true, false, NULL);
       ilrun_present = (exitstatus == 0);
       ilrun_tested = true;
     }
@@ -179,7 +179,7 @@ execute_csharp_using_mono (const char *assembly_path,
       argv[1] = "--version";
       argv[2] = NULL;
       exitstatus = execute ("mono", "mono", argv, false, false, true, true,
-                           true, false);
+                           true, false, NULL);
       mono_present = (exitstatus == 0);
       mono_tested = true;
     }
@@ -240,7 +240,7 @@ execute_csharp_using_sscli (const char *assembly_path,
       argv[0] = "clix";
       argv[1] = NULL;
       exitstatus = execute ("clix", "clix", argv, false, false, true, true,
-                           true, false);
+                           true, false, NULL);
       clix_present = (exitstatus == 0 || exitstatus == 1);
       clix_tested = true;
     }
index cfac196..751dcb3 100644 (file)
@@ -117,7 +117,8 @@ 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)
+        bool slave_process, bool exit_on_error,
+        int *termsigp)
 {
 #if defined _MSC_VER || defined __MINGW32__
 
@@ -173,6 +174,9 @@ execute (const char *progname,
   if (null_stdin)
     dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
 
+  if (termsigp != NULL)
+    *termsigp = 0;
+
   if (exitcode == -1)
     {
       if (exit_on_error || !null_stderr)
@@ -251,6 +255,8 @@ execute (const char *progname,
        posix_spawnattr_destroy (&attrs);
       if (slave_process)
        unblock_fatal_signals ();
+      if (termsigp != NULL)
+       *termsigp = 0;
       if (exit_on_error || !null_stderr)
        error (exit_on_error ? EXIT_FAILURE : 0, err,
               _("%s subprocess failed"), progname);
@@ -293,6 +299,8 @@ execute (const char *progname,
     {
       if (slave_process)
        unblock_fatal_signals ();
+      if (termsigp != NULL)
+       *termsigp = 0;
       if (exit_on_error || !null_stderr)
        error (exit_on_error ? EXIT_FAILURE : 0, errno,
               _("%s subprocess failed"), progname);
@@ -306,7 +314,7 @@ execute (const char *progname,
     }
 
   return wait_subprocess (child, progname, ignore_sigpipe, null_stderr,
-                         slave_process, exit_on_error);
+                         slave_process, exit_on_error, termsigp);
 
 #endif
 }
index 8b99d58..b456aaf 100644 (file)
@@ -1,5 +1,5 @@
 /* Creation of autonomous subprocesses.
-   Copyright (C) 2001-2003 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2008 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
    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.
+   If termsigp is not NULL, *termsig will be set to the signal that terminated
+   the subprocess (if supported by the platform: not on native Windows
+   platforms), otherwise 0.
    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);
+                   bool slave_process, bool exit_on_error,
+                   int *termsigp);
 
 #endif /* _EXECUTE_H */
index a05267a..b3ec627 100644 (file)
@@ -1,5 +1,5 @@
 /* Compile a Java program.
-   Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006-2008 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -268,7 +268,7 @@ compile_using_envjavac (const char *javac,
   argv[2] = command;
   argv[3] = NULL;
   exitstatus = execute (javac, "/bin/sh", argv, false, false, false,
-                       null_stderr, true, true);
+                       null_stderr, true, true, NULL);
   err = (exitstatus != 0);
 
   freea (command);
@@ -350,7 +350,7 @@ compile_using_gcj (const char * const *java_sources,
     }
 
   exitstatus = execute ("gcj", "gcj", argv, false, false, false, null_stderr,
-                       true, true);
+                       true, true, NULL);
   err = (exitstatus != 0);
 
   if (ftarget_arg != NULL)
@@ -421,7 +421,7 @@ compile_using_javac (const char * const *java_sources,
     }
 
   exitstatus = execute ("javac", "javac", argv, false, false, false,
-                       null_stderr, true, true);
+                       null_stderr, true, true, NULL);
   err = (exitstatus != 0);
 
   freea (argv);
@@ -476,7 +476,7 @@ compile_using_jikes (const char * const *java_sources,
     }
 
   exitstatus = execute ("jikes", "jikes", argv, false, false, false,
-                       null_stderr, true, true);
+                       null_stderr, true, true, NULL);
   err = (exitstatus != 0);
 
   freea (argv);
@@ -605,7 +605,8 @@ is_envjavac_gcj (const char *javac)
       fclose (fp);
 
       /* Remove zombie process from process list, and retrieve exit status.  */
-      exitstatus = wait_subprocess (child, javac, true, true, true, false);
+      exitstatus =
+       wait_subprocess (child, javac, true, true, true, false, NULL);
       if (exitstatus != 0)
        envjavac_gcj = false;
 
@@ -689,7 +690,8 @@ is_envjavac_gcj43 (const char *javac)
       fclose (fp);
 
       /* Remove zombie process from process list, and retrieve exit status.  */
-      exitstatus = wait_subprocess (child, javac, true, true, true, false);
+      exitstatus =
+       wait_subprocess (child, javac, true, true, true, false, NULL);
       if (exitstatus != 0)
        envjavac_gcj43 = false;
 
@@ -1367,7 +1369,7 @@ is_gcj_present (void)
          /* Remove zombie process from process list, and retrieve exit
             status.  */
          exitstatus =
-           wait_subprocess (child, "gcj", false, true, true, false);
+           wait_subprocess (child, "gcj", false, true, true, false, NULL);
          if (exitstatus != 0)
            gcj_present = false;
        }
@@ -1482,7 +1484,7 @@ is_gcj_43 (void)
          /* Remove zombie process from process list, and retrieve exit
             status.  */
          exitstatus =
-           wait_subprocess (child, "gcj", false, true, true, false);
+           wait_subprocess (child, "gcj", false, true, true, false, NULL);
          if (exitstatus != 0)
            gcj_43 = false;
        }
@@ -1791,7 +1793,7 @@ is_javac_present (void)
       argv[0] = "javac";
       argv[1] = NULL;
       exitstatus = execute ("javac", "javac", argv, false, false, true, true,
-                           true, false);
+                           true, false, NULL);
       javac_present = (exitstatus == 0 || exitstatus == 1 || exitstatus == 2);
       javac_tested = true;
     }
@@ -2055,7 +2057,7 @@ is_jikes_present (void)
       argv[0] = "jikes";
       argv[1] = NULL;
       exitstatus = execute ("jikes", "jikes", argv, false, false, true, true,
-                           true, false);
+                           true, false, NULL);
       jikes_present = (exitstatus == 0 || exitstatus == 1);
       jikes_tested = true;
     }
index 4192248..8235b2d 100644 (file)
@@ -1,5 +1,5 @@
 /* Execute a Java program.
-   Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006-2008 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -209,7 +209,7 @@ execute_java_class (const char *class_name,
        argv[1] = "--version";
        argv[2] = NULL;
        exitstatus = execute ("gij", "gij", argv, false, false, true, true,
-                             true, false);
+                             true, false, NULL);
        gij_present = (exitstatus == 0);
        gij_tested = true;
       }
@@ -262,7 +262,7 @@ execute_java_class (const char *class_name,
        argv[1] = "-version";
        argv[2] = NULL;
        exitstatus = execute ("java", "java", argv, false, false, true, true,
-                             true, false);
+                             true, false, NULL);
        java_present = (exitstatus == 0);
        java_tested = true;
       }
@@ -316,7 +316,7 @@ execute_java_class (const char *class_name,
        argv[0] = "jre";
        argv[1] = NULL;
        exitstatus = execute ("jre", "jre", argv, false, false, true, true,
-                             true, false);
+                             true, false, NULL);
        jre_present = (exitstatus == 0 || exitstatus == 1);
        jre_tested = true;
       }
@@ -373,7 +373,7 @@ execute_java_class (const char *class_name,
        argv[1] = "-?";
        argv[2] = NULL;
        exitstatus = execute ("jview", "jview", argv, false, false, true, true,
-                             true, false);
+                             true, false, NULL);
        jview_present = (exitstatus == 0 || exitstatus == 1);
        jview_tested = true;
       }
index 4ce564b..003919e 100644 (file)
@@ -1,5 +1,5 @@
 /* Determine the Java version supported by javaexec.
-   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2006-2008 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2006.
 
    This program is free software: you can redistribute it and/or modify
@@ -90,7 +90,8 @@ execute_and_read_line (const char *progname,
   fclose (fp);
 
   /* Remove zombie process from process list, and retrieve exit status.  */
-  exitstatus = wait_subprocess (child, progname, true, false, true, false);
+  exitstatus =
+    wait_subprocess (child, progname, true, false, true, false, NULL);
   if (exitstatus != 0)
     {
       free (line);
index e98c644..5852726 100644 (file)
@@ -250,7 +250,8 @@ unregister_slave_subprocess (pid_t child)
 int
 wait_subprocess (pid_t child, const char *progname,
                 bool ignore_sigpipe, bool null_stderr,
-                bool slave_process, bool exit_on_error)
+                bool slave_process, bool exit_on_error,
+                int *termsigp)
 {
 #if HAVE_WAITID && defined WNOWAIT && 0
   /* Commented out because waitid() without WEXITED and with WNOWAIT doesn't
@@ -263,6 +264,9 @@ wait_subprocess (pid_t child, const char *progname,
      before unregister_slave_subprocess() - this process gets a fatal signal,
      it would kill the other totally unrelated process.  */
   siginfo_t info;
+
+  if (termsigp != NULL)
+    *termsigp = 0;
   for (;;)
     {
       if (waitid (P_PID, child, &info, WEXITED | (slave_process ? WNOWAIT : 0))
@@ -317,6 +321,8 @@ wait_subprocess (pid_t child, const char *progname,
     {
     case CLD_KILLED:
     case CLD_DUMPED:
+      if (termsigp != NULL)
+       *termsigp = info.si_status; /* TODO: or info.si_signo? */
 # ifdef SIGPIPE
       if (info.si_status == SIGPIPE && ignore_sigpipe)
        return 0;
@@ -342,6 +348,8 @@ wait_subprocess (pid_t child, const char *progname,
   /* waitpid() is just as portable as wait() nowadays.  */
   WAIT_T status;
 
+  if (termsigp != NULL)
+    *termsigp = 0;
   *(int *) &status = 0;
   for (;;)
     {
@@ -385,6 +393,8 @@ wait_subprocess (pid_t child, const char *progname,
 
   if (WIFSIGNALED (status))
     {
+      if (termsigp != NULL)
+       *termsigp = WTERMSIG (status);
 # ifdef SIGPIPE
       if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe)
        return 0;
index d5beebc..3d7a4cf 100644 (file)
@@ -1,5 +1,5 @@
 /* Waiting for a subprocess to finish.
-   Copyright (C) 2001-2003, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006, 2008 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -47,10 +47,14 @@ extern "C" {
    - 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.  */
+     with an error status.
+   - If termsigp is not NULL, *termsig will be set to the signal that
+     terminated the subprocess (if supported by the platform: not on native
+     Windows platforms), otherwise 0.  */
 extern int wait_subprocess (pid_t child, const char *progname,
                            bool ignore_sigpipe, bool null_stderr,
-                           bool slave_process, bool exit_on_error);
+                           bool slave_process, bool exit_on_error,
+                           int *termsigp);
 
 /* Register a subprocess as being a slave process.  This means that the
    subprocess will be terminated when its creator receives a catchable fatal