changeset 30235:d2d89737e596

Enable use of shell scripts as executables in mingw.
author Bruno Haible <bruno@clisp.org>
date Mon, 29 Sep 2008 15:13:25 +0200
parents 7741d88d82fe
children a7110dbf49ed
files ChangeLog lib/execute.c lib/pipe.c lib/w32spawn.h
diffstat 4 files changed, 43 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Sep 29 06:27:29 2008 -0600
+++ b/ChangeLog	Mon Sep 29 15:13:25 2008 +0200
@@ -1,3 +1,12 @@
+2008-09-29  Bruno Haible  <bruno@clisp.org>
+
+	Enable use of shell scripts as executables in mingw.
+	* lib/execute.c (execute): When spawnv fails with error ENOEXEC,
+	run the program as a shell script.
+	* lib/pipe.c (create_pipe): Likewise.
+	* lib/w32spawn.h (prepare_spawn): Add a hidden element in front of the
+	resulting array.
+
 2008-09-29  Eric Blake  <ebb9@byu.net>
 
 	* m4/arpa_inet_h.m4 (gl_REPLACE_ARPA_INET_H): Fix typo.
--- a/lib/execute.c	Mon Sep 29 06:27:29 2008 -0600
+++ b/lib/execute.c	Mon Sep 29 15:13:25 2008 +0200
@@ -130,6 +130,7 @@
   int nullinfd;
   int nulloutfd;
 
+  /* FIXME: Need to free memory allocated by prepare_spawn.  */
   prog_argv = prepare_spawn (prog_argv);
 
   /* Save standard file handles of parent process.  */
@@ -160,7 +161,17 @@
 	      && ((null_stdout && nulloutfd == STDOUT_FILENO)
 		  || (null_stderr && nulloutfd == STDERR_FILENO)
 		  || close (nulloutfd) >= 0))))
-    exitcode = spawnvp (P_WAIT, prog_path, prog_argv);
+    {
+      exitcode = spawnvp (P_WAIT, prog_path, prog_argv);
+      if (exitcode < 0 && errno == ENOEXEC)
+	{
+	  /* prog is not an native executable.  Try to execute it as a
+	     shell script.  Note that prepare_spawn() has already prepended
+	     a hidden element "sh.exe" to prog_argv.  */
+	  --prog_argv;
+	  exitcode = spawnvp (P_WAIT, prog_argv[0], prog_argv);
+	}
+    }
   if (nulloutfd >= 0)
     close (nulloutfd);
   if (nullinfd >= 0)
--- a/lib/pipe.c	Mon Sep 29 06:27:29 2008 -0600
+++ b/lib/pipe.c	Mon Sep 29 15:13:25 2008 +0200
@@ -145,6 +145,7 @@
   int stdinfd;
   int stdoutfd;
 
+  /* FIXME: Need to free memory allocated by prepare_spawn.  */
   prog_argv = prepare_spawn (prog_argv);
 
   if (pipe_stdout)
@@ -201,7 +202,17 @@
        we want in the case of STD*_FILENO) and also orig_stdin,
        orig_stdout, orig_stderr (which is not explicitly wanted but
        harmless).  */
-    child = spawnvp (P_NOWAIT, prog_path, prog_argv);
+    {
+      child = spawnvp (P_NOWAIT, prog_path, prog_argv);
+      if (child < 0 && errno == ENOEXEC)
+	{
+	  /* prog is not an native executable.  Try to execute it as a
+	     shell script.  Note that prepare_spawn() has already prepended
+	     a hidden element "sh.exe" to prog_argv.  */
+	  --prog_argv;
+	  child = spawnvp (P_NOWAIT, prog_argv[0], prog_argv);
+	}
+    }
   if (stdinfd >= 0)
     close (stdinfd);
   if (stdoutfd >= 0)
--- a/lib/w32spawn.h	Mon Sep 29 06:27:29 2008 -0600
+++ b/lib/w32spawn.h	Mon Sep 29 15:13:25 2008 +0200
@@ -1,5 +1,5 @@
 /* Auxiliary functions for the creation of subprocesses.  Native Woe32 API.
-   Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006-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
@@ -91,7 +91,15 @@
     ;
 
   /* Allocate new argument vector.  */
-  new_argv = XNMALLOC (argc + 1, char *);
+  new_argv = XNMALLOC (1 + argc + 1, char *);
+
+  /* Add an element upfront that can be used when argv[0] turns out to be a
+     script, not a program.
+     On Unix, this would be "/bin/sh". On native Windows, "sh" is actually
+     "sh.exe".  We have to omit the directory part and rely on the search in
+     PATH, because the mingw "mount points" are not visible inside Win32
+     CreateProcess().  */
+  *new_argv++ = "sh.exe";
 
   /* Put quoted arguments into the new argument vector.  */
   for (i = 0; i < argc; i++)