summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--lib/execute.c13
-rw-r--r--lib/pipe.c13
-rw-r--r--lib/w32spawn.h12
4 files changed, 43 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 3efa157b28..75ed5a830d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/lib/execute.c b/lib/execute.c
index 751dcb384b..47f4085204 100644
--- a/lib/execute.c
+++ b/lib/execute.c
@@ -130,6 +130,7 @@ execute (const char *progname,
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 @@ execute (const char *progname,
&& ((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)
diff --git a/lib/pipe.c b/lib/pipe.c
index a632e9dd22..ebedb0a2d5 100644
--- a/lib/pipe.c
+++ b/lib/pipe.c
@@ -145,6 +145,7 @@ create_pipe (const char *progname,
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 @@ create_pipe (const char *progname,
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)
diff --git a/lib/w32spawn.h b/lib/w32spawn.h
index 7ebbb4c58e..9ebf5bc49c 100644
--- a/lib/w32spawn.h
+++ b/lib/w32spawn.h
@@ -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 @@ prepare_spawn (char **argv)
;
/* 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++)