changeset 10197:d079dd7b69bc

Add termsigp argument to execute() and wait_process().
author Bruno Haible <bruno@clisp.org>
date Tue, 10 Jun 2008 17:38:39 +0200
parents a59b1061e84a
children 5056e8a13405
files 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
diffstat 11 files changed, 91 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,11 @@
 
 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:
--- a/lib/csharpcomp.c
+++ b/lib/csharpcomp.c
@@ -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 @@
       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 @@
 	}
 
       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 @@
 	  /* 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 @@
       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 @@
 	  /* 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 @@
 	}
 
       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]);
--- a/lib/csharpexec.c
+++ b/lib/csharpexec.c
@@ -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 @@
       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 @@
       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 @@
       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;
     }
--- a/lib/execute.c
+++ b/lib/execute.c
@@ -117,7 +117,8 @@
 	 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 @@
   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 @@
 	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 @@
     {
       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 @@
     }
 
   return wait_subprocess (child, progname, ignore_sigpipe, null_stderr,
-			  slave_process, exit_on_error);
+			  slave_process, exit_on_error, termsigp);
 
 #endif
 }
--- a/lib/execute.h
+++ b/lib/execute.h
@@ -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
@@ -29,12 +29,16 @@
    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 */
--- a/lib/javacomp.c
+++ b/lib/javacomp.c
@@ -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 @@
   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 @@
     }
 
   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 @@
     }
 
   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 @@
     }
 
   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 @@
       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 @@
       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 @@
 	  /* 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 @@
 	  /* 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 @@
       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 @@
       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;
     }
--- a/lib/javaexec.c
+++ b/lib/javaexec.c
@@ -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 @@
 	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 @@
 	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 @@
 	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 @@
 	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;
       }
--- a/lib/javaversion.c
+++ b/lib/javaversion.c
@@ -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 @@
   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);
--- a/lib/wait-process.c
+++ b/lib/wait-process.c
@@ -250,7 +250,8 @@
 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 @@
      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 @@
     {
     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 @@
   /* waitpid() is just as portable as wait() nowadays.  */
   WAIT_T status;
 
+  if (termsigp != NULL)
+    *termsigp = 0;
   *(int *) &status = 0;
   for (;;)
     {
@@ -385,6 +393,8 @@
 
   if (WIFSIGNALED (status))
     {
+      if (termsigp != NULL)
+	*termsigp = WTERMSIG (status);
 # ifdef SIGPIPE
       if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe)
 	return 0;
--- a/lib/wait-process.h
+++ b/lib/wait-process.h
@@ -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 @@
    - 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