Re: system(), Solaris, and the 'execute' module

Bruno Haible <[email protected]>
Newsgroups gmane.comp.lib.gnulib.bugs,gmane.comp.gnu.m4.general
Message-ID <[email protected]>
Eric Blake wrote on 2008-06-02:
> |> Does the execute module allow distinguishing exits due to signals from
> |> regular exits?  M4 is currently documented as treating the sysval macro
> |> differently to allow the user to distinguish between signals, but it looks
> |> like wait_subprocess collapses all non-fatal signals into 127
> |
> | Currently the 'execute' module indeed does not allow to distinguish between
> | launch failure and fatal signals. I could imagine to provide this info through
> | an optional parameter. But how do you want to treat the portability problem
> | to mingw here?
> 
> mingw doesn't have signals, so the optional parameter would never be
> populated.
> 
> | How does m4 treat mingw at all? Which shell does it use in 'syscmd' and
> | 'esyscmd'?
> 
> The m4 documentation currently mentions that syscmd uses whatever system()
> provides (probably 'cmd.exe /c' for mingw); and that POSIX compliance is
> only attempted for platforms where the m4 macro __unix__ is defined (mingw
> defines __windows__, not __unix__).  At any rate, on mingw, syscmd is
> certainly nowhere near a POSIX-compliant command parser, and the m4
> testsuite intentionally skips all tests that try to do anything with a
> shell metacharacter or other action that just won't work without /bin/sh
> as the interpreter (syscmd still works for some things regardless of
> shell, such as a recursive invocation of m4 with arguments that do not
> contain shell metacharacters).

OK, if you are ready to accept a documented misfeature of 'm4' on mingw, I can
also accept a documented misfeature of the execute() function on mingw.

I added an optional output parameter for the termination signal.


2008-06-10  Bruno Haible  <[email protected]>

	* 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.

*** NEWS.orig	2008-06-10 17:25:45.000000000 +0200
--- NEWS	2008-06-10 14:19:56.000000000 +0200
***************
*** 6,11 ****
--- 6,16 ----
  
  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:
*** lib/wait-process.h.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/wait-process.h	2008-06-10 14:00:12.000000000 +0200
***************
*** 1,5 ****
  /* Waiting for a subprocess to finish.
!    Copyright (C) 2001-2003, 2006 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Waiting for a subprocess to finish.
!    Copyright (C) 2001-2003, 2006, 2008 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 47,56 ****
     - 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 ignore_sigpipe, bool null_stderr,
! 			    bool slave_process, bool exit_on_error);
  
  /* Register a subprocess as being a slave process.  This means that the
     subprocess will be terminated when its creator receives a catchable fatal
--- 47,60 ----
     - 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.
!    - 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,
! 			    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
*** lib/wait-process.c.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/wait-process.c	2008-06-10 14:12:39.000000000 +0200
***************
*** 250,256 ****
  int
  wait_subprocess (pid_t child, const char *progname,
  		 bool ignore_sigpipe, bool null_stderr,
! 		 bool slave_process, bool exit_on_error)
  {
  #if HAVE_WAITID && defined WNOWAIT && 0
    /* Commented out because waitid() without WEXITED and with WNOWAIT doesn't
--- 250,257 ----
  int
  wait_subprocess (pid_t child, const char *progname,
  		 bool ignore_sigpipe, bool null_stderr,
! 		 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,268 ****
--- 264,272 ----
       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,322 ****
--- 321,328 ----
      {
      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,347 ****
--- 348,355 ----
    /* waitpid() is just as portable as wait() nowadays.  */
    WAIT_T status;
  
+   if (termsigp != NULL)
+     *termsigp = 0;
    *(int *) &status = 0;
    for (;;)
      {
***************
*** 385,390 ****
--- 393,400 ----
  
    if (WIFSIGNALED (status))
      {
+       if (termsigp != NULL)
+ 	*termsigp = WTERMSIG (status);
  # ifdef SIGPIPE
        if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe)
  	return 0;
*** lib/execute.h.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/execute.h	2008-06-10 14:18:51.000000000 +0200
***************
*** 1,5 ****
  /* Creation of autonomous subprocesses.
!    Copyright (C) 2001-2003 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Creation of autonomous subprocesses.
!    Copyright (C) 2001-2003, 2008 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 29,40 ****
     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);
  
  #endif /* _EXECUTE_H */
--- 29,44 ----
     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,
! 		    int *termsigp);
  
  #endif /* _EXECUTE_H */
*** lib/execute.c.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/execute.c	2008-06-10 14:22:48.000000000 +0200
***************
*** 117,123 ****
  	 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)
  {
  #if defined _MSC_VER || defined __MINGW32__
  
--- 117,124 ----
  	 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,
! 	 int *termsigp)
  {
  #if defined _MSC_VER || defined __MINGW32__
  
***************
*** 173,178 ****
--- 174,182 ----
    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,256 ****
--- 255,262 ----
  	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,298 ****
--- 299,306 ----
      {
        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,312 ****
      }
  
    return wait_subprocess (child, progname, ignore_sigpipe, null_stderr,
! 			  slave_process, exit_on_error);
  
  #endif
  }
--- 314,320 ----
      }
  
    return wait_subprocess (child, progname, ignore_sigpipe, null_stderr,
! 			  slave_process, exit_on_error, termsigp);
  
  #endif
  }
*** lib/csharpcomp.c.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/csharpcomp.c	2008-06-10 14:27:24.000000000 +0200
***************
*** 1,5 ****
  /* Compile a C# program.
!    Copyright (C) 2003-2007 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2003.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Compile a C# program.
!    Copyright (C) 2003-2008 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2003.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 83,89 ****
        argv[1] = "--version";
        argv[2] = NULL;
        exitstatus = execute ("cscc", "cscc", argv, false, false, true, true,
! 			    true, false);
        cscc_present = (exitstatus == 0);
        cscc_tested = true;
      }
--- 83,89 ----
        argv[1] = "--version";
        argv[2] = NULL;
        exitstatus = execute ("cscc", "cscc", argv, false, false, true, true,
! 			    true, false, NULL);
        cscc_present = (exitstatus == 0);
        cscc_tested = true;
      }
***************
*** 151,157 ****
  	}
  
        exitstatus = execute ("cscc", "cscc", argv, false, false, false, false,
! 			    true, true);
  
        for (i = 0; i < sources_count; i++)
  	if (argv[argc - sources_count + i] != sources[i])
--- 151,157 ----
  	}
  
        exitstatus = execute ("cscc", "cscc", argv, false, false, false, false,
! 			    true, true, NULL);
  
        for (i = 0; i < sources_count; i++)
  	if (argv[argc - sources_count + i] != sources[i])
***************
*** 219,225 ****
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "mcs", false, true, true, false);
  	  if (exitstatus != 0)
  	    mcs_present = false;
  	}
--- 219,225 ----
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "mcs", false, true, true, false, NULL);
  	  if (exitstatus != 0)
  	    mcs_present = false;
  	}
***************
*** 332,338 ****
        fclose (fp);
  
        /* Remove zombie process from process list, and retrieve exit status.  */
!       exitstatus = wait_subprocess (child, "mcs", false, false, true, true);
  
        for (i = 1 + (output_is_library ? 1 : 0);
  	   i < 1 + (output_is_library ? 1 : 0)
--- 332,339 ----
        fclose (fp);
  
        /* Remove zombie process from process list, and retrieve exit status.  */
!       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,414 ****
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "csc", false, true, true, false);
  	  if (exitstatus != 0)
  	    csc_present = false;
  	}
--- 409,415 ----
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "csc", false, true, true, false, NULL);
  	  if (exitstatus != 0)
  	    csc_present = false;
  	}
***************
*** 486,492 ****
  	}
  
        exitstatus = execute ("csc", "csc", argv, false, false, false, false,
! 			    true, true);
  
        for (i = 2; i < 3 + libdirs_count + libraries_count; i++)
  	freea (argv[i]);
--- 487,493 ----
  	}
  
        exitstatus = execute ("csc", "csc", argv, false, false, false, false,
! 			    true, true, NULL);
  
        for (i = 2; i < 3 + libdirs_count + libraries_count; i++)
  	freea (argv[i]);
*** lib/csharpexec.c.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/csharpexec.c	2008-06-10 14:27:45.000000000 +0200
***************
*** 1,5 ****
  /* Execute a C# program.
!    Copyright (C) 2003-2007 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2003.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Execute a C# program.
!    Copyright (C) 2003-2008 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2003.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 109,115 ****
        argv[1] = "--version";
        argv[2] = NULL;
        exitstatus = execute ("ilrun", "ilrun", argv, false, false, true, true,
! 			    true, false);
        ilrun_present = (exitstatus == 0);
        ilrun_tested = true;
      }
--- 109,115 ----
        argv[1] = "--version";
        argv[2] = NULL;
        exitstatus = execute ("ilrun", "ilrun", argv, false, false, true, true,
! 			    true, false, NULL);
        ilrun_present = (exitstatus == 0);
        ilrun_tested = true;
      }
***************
*** 179,185 ****
        argv[1] = "--version";
        argv[2] = NULL;
        exitstatus = execute ("mono", "mono", argv, false, false, true, true,
! 			    true, false);
        mono_present = (exitstatus == 0);
        mono_tested = true;
      }
--- 179,185 ----
        argv[1] = "--version";
        argv[2] = NULL;
        exitstatus = execute ("mono", "mono", argv, false, false, true, true,
! 			    true, false, NULL);
        mono_present = (exitstatus == 0);
        mono_tested = true;
      }
***************
*** 240,246 ****
        argv[0] = "clix";
        argv[1] = NULL;
        exitstatus = execute ("clix", "clix", argv, false, false, true, true,
! 			    true, false);
        clix_present = (exitstatus == 0 || exitstatus == 1);
        clix_tested = true;
      }
--- 240,246 ----
        argv[0] = "clix";
        argv[1] = NULL;
        exitstatus = execute ("clix", "clix", argv, false, false, true, true,
! 			    true, false, NULL);
        clix_present = (exitstatus == 0 || exitstatus == 1);
        clix_tested = true;
      }
*** lib/javacomp.c.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/javacomp.c	2008-06-10 14:28:18.000000000 +0200
***************
*** 1,5 ****
  /* Compile a Java program.
!    Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Compile a Java program.
!    Copyright (C) 2001-2003, 2006-2008 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 268,274 ****
    argv[2] = command;
    argv[3] = NULL;
    exitstatus = execute (javac, "/bin/sh", argv, false, false, false,
! 			null_stderr, true, true);
    err = (exitstatus != 0);
  
    freea (command);
--- 268,274 ----
    argv[2] = command;
    argv[3] = NULL;
    exitstatus = execute (javac, "/bin/sh", argv, false, false, false,
! 			null_stderr, true, true, NULL);
    err = (exitstatus != 0);
  
    freea (command);
***************
*** 350,356 ****
      }
  
    exitstatus = execute ("gcj", "gcj", argv, false, false, false, null_stderr,
! 			true, true);
    err = (exitstatus != 0);
  
    if (ftarget_arg != NULL)
--- 350,356 ----
      }
  
    exitstatus = execute ("gcj", "gcj", argv, false, false, false, null_stderr,
! 			true, true, NULL);
    err = (exitstatus != 0);
  
    if (ftarget_arg != NULL)
***************
*** 421,427 ****
      }
  
    exitstatus = execute ("javac", "javac", argv, false, false, false,
! 			null_stderr, true, true);
    err = (exitstatus != 0);
  
    freea (argv);
--- 421,427 ----
      }
  
    exitstatus = execute ("javac", "javac", argv, false, false, false,
! 			null_stderr, true, true, NULL);
    err = (exitstatus != 0);
  
    freea (argv);
***************
*** 476,482 ****
      }
  
    exitstatus = execute ("jikes", "jikes", argv, false, false, false,
! 			null_stderr, true, true);
    err = (exitstatus != 0);
  
    freea (argv);
--- 476,482 ----
      }
  
    exitstatus = execute ("jikes", "jikes", argv, false, false, false,
! 			null_stderr, true, true, NULL);
    err = (exitstatus != 0);
  
    freea (argv);
***************
*** 605,611 ****
        fclose (fp);
  
        /* Remove zombie process from process list, and retrieve exit status.  */
!       exitstatus = wait_subprocess (child, javac, true, true, true, false);
        if (exitstatus != 0)
  	envjavac_gcj = false;
  
--- 605,612 ----
        fclose (fp);
  
        /* Remove zombie process from process list, and retrieve exit status.  */
!       exitstatus =
! 	wait_subprocess (child, javac, true, true, true, false, NULL);
        if (exitstatus != 0)
  	envjavac_gcj = false;
  
***************
*** 689,695 ****
        fclose (fp);
  
        /* Remove zombie process from process list, and retrieve exit status.  */
!       exitstatus = wait_subprocess (child, javac, true, true, true, false);
        if (exitstatus != 0)
  	envjavac_gcj43 = false;
  
--- 690,697 ----
        fclose (fp);
  
        /* Remove zombie process from process list, and retrieve exit status.  */
!       exitstatus =
! 	wait_subprocess (child, javac, true, true, true, false, NULL);
        if (exitstatus != 0)
  	envjavac_gcj43 = false;
  
***************
*** 1367,1373 ****
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "gcj", false, true, true, false);
  	  if (exitstatus != 0)
  	    gcj_present = false;
  	}
--- 1369,1375 ----
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "gcj", false, true, true, false, NULL);
  	  if (exitstatus != 0)
  	    gcj_present = false;
  	}
***************
*** 1482,1488 ****
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "gcj", false, true, true, false);
  	  if (exitstatus != 0)
  	    gcj_43 = false;
  	}
--- 1484,1490 ----
  	  /* Remove zombie process from process list, and retrieve exit
  	     status.  */
  	  exitstatus =
! 	    wait_subprocess (child, "gcj", false, true, true, false, NULL);
  	  if (exitstatus != 0)
  	    gcj_43 = false;
  	}
***************
*** 1791,1797 ****
        argv[0] = "javac";
        argv[1] = NULL;
        exitstatus = execute ("javac", "javac", argv, false, false, true, true,
! 			    true, false);
        javac_present = (exitstatus == 0 || exitstatus == 1 || exitstatus == 2);
        javac_tested = true;
      }
--- 1793,1799 ----
        argv[0] = "javac";
        argv[1] = NULL;
        exitstatus = execute ("javac", "javac", argv, false, false, true, true,
! 			    true, false, NULL);
        javac_present = (exitstatus == 0 || exitstatus == 1 || exitstatus == 2);
        javac_tested = true;
      }
***************
*** 2055,2061 ****
        argv[0] = "jikes";
        argv[1] = NULL;
        exitstatus = execute ("jikes", "jikes", argv, false, false, true, true,
! 			    true, false);
        jikes_present = (exitstatus == 0 || exitstatus == 1);
        jikes_tested = true;
      }
--- 2057,2063 ----
        argv[0] = "jikes";
        argv[1] = NULL;
        exitstatus = execute ("jikes", "jikes", argv, false, false, true, true,
! 			    true, false, NULL);
        jikes_present = (exitstatus == 0 || exitstatus == 1);
        jikes_tested = true;
      }
*** lib/javaexec.c.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/javaexec.c	2008-06-10 14:28:44.000000000 +0200
***************
*** 1,5 ****
  /* Execute a Java program.
!    Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Execute a Java program.
!    Copyright (C) 2001-2003, 2006-2008 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2001.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 209,215 ****
  	argv[1] = "--version";
  	argv[2] = NULL;
  	exitstatus = execute ("gij", "gij", argv, false, false, true, true,
! 			      true, false);
  	gij_present = (exitstatus == 0);
  	gij_tested = true;
        }
--- 209,215 ----
  	argv[1] = "--version";
  	argv[2] = NULL;
  	exitstatus = execute ("gij", "gij", argv, false, false, true, true,
! 			      true, false, NULL);
  	gij_present = (exitstatus == 0);
  	gij_tested = true;
        }
***************
*** 262,268 ****
  	argv[1] = "-version";
  	argv[2] = NULL;
  	exitstatus = execute ("java", "java", argv, false, false, true, true,
! 			      true, false);
  	java_present = (exitstatus == 0);
  	java_tested = true;
        }
--- 262,268 ----
  	argv[1] = "-version";
  	argv[2] = NULL;
  	exitstatus = execute ("java", "java", argv, false, false, true, true,
! 			      true, false, NULL);
  	java_present = (exitstatus == 0);
  	java_tested = true;
        }
***************
*** 316,322 ****
  	argv[0] = "jre";
  	argv[1] = NULL;
  	exitstatus = execute ("jre", "jre", argv, false, false, true, true,
! 			      true, false);
  	jre_present = (exitstatus == 0 || exitstatus == 1);
  	jre_tested = true;
        }
--- 316,322 ----
  	argv[0] = "jre";
  	argv[1] = NULL;
  	exitstatus = execute ("jre", "jre", argv, false, false, true, true,
! 			      true, false, NULL);
  	jre_present = (exitstatus == 0 || exitstatus == 1);
  	jre_tested = true;
        }
***************
*** 373,379 ****
  	argv[1] = "-?";
  	argv[2] = NULL;
  	exitstatus = execute ("jview", "jview", argv, false, false, true, true,
! 			      true, false);
  	jview_present = (exitstatus == 0 || exitstatus == 1);
  	jview_tested = true;
        }
--- 373,379 ----
  	argv[1] = "-?";
  	argv[2] = NULL;
  	exitstatus = execute ("jview", "jview", argv, false, false, true, true,
! 			      true, false, NULL);
  	jview_present = (exitstatus == 0 || exitstatus == 1);
  	jview_tested = true;
        }
*** lib/javaversion.c.orig	2008-06-10 17:25:46.000000000 +0200
--- lib/javaversion.c	2008-06-10 14:24:25.000000000 +0200
***************
*** 1,5 ****
  /* Determine the Java version supported by javaexec.
!    Copyright (C) 2006, 2007 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2006.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Determine the Java version supported by javaexec.
!    Copyright (C) 2006-2008 Free Software Foundation, Inc.
     Written by Bruno Haible <[email protected]>, 2006.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 90,96 ****
    fclose (fp);
  
    /* Remove zombie process from process list, and retrieve exit status.  */
!   exitstatus = wait_subprocess (child, progname, true, false, true, false);
    if (exitstatus != 0)
      {
        free (line);
--- 90,97 ----
    fclose (fp);
  
    /* Remove zombie process from process list, and retrieve exit status.  */
!   exitstatus =
!     wait_subprocess (child, progname, true, false, true, false, NULL);
    if (exitstatus != 0)
      {
        free (line);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.