diff options
author | Bruno Haible <bruno@clisp.org> | 2008-09-29 15:13:25 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2008-09-29 15:13:25 +0200 |
commit | a7dd7898b03b95173995e1b69733fd0e91aa04cf (patch) | |
tree | 4d896af6297ddf6726ed4f7ba7ce4a5c9929374d /lib | |
parent | 7f182b971ef6257abb99f17e9b951c5daaf84999 (diff) | |
download | gnulib-a7dd7898b03b95173995e1b69733fd0e91aa04cf.tar.gz |
Enable use of shell scripts as executables in mingw.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/execute.c | 13 | ||||
-rw-r--r-- | lib/pipe.c | 13 | ||||
-rw-r--r-- | lib/w32spawn.h | 12 |
3 files changed, 34 insertions, 4 deletions
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++) |