This patch refactors common code of 'execute' and 'spawn-pipe', so that packages that include both modules contain the same code only once.
2020-11-28 Bruno Haible <br...@clisp.org> windows-spawn: New module. * lib/windows-spawn.h: Renamed from lib/w32spawn.h. Remove implementations. * lib/windows-spawn.c: Renamed from lib/w32spawn.h. * modules/windows-spawn: New file. * lib/execute.c: Include "windows-spawn.h" instead of "w32spawn.h". * lib/spawn-pipe.c: Likewise. * modules/execute (Files): Remove lib/w32spawn.h. (Depends-on): Add windows-spawn. Remove cloexec, msvc-nothrow, strpbrk, xalloc. (Makefile.am): Remove w32spawn.h from lib_SOURCES. * modules/spawn-pipe (Files): Remove lib/w32spawn.h. (Depends-on): Add windows-spawn. Remove cloexec, msvc-nothrow, strpbrk, xalloc. (Makefile.am): Remove w32spawn.h from lib_SOURCES. diff --git a/lib/execute.c b/lib/execute.c index 15d9ba9..41e1e92 100644 --- a/lib/execute.c +++ b/lib/execute.c @@ -39,7 +39,7 @@ /* Native Windows API. */ # include <process.h> -# include "w32spawn.h" +# include "windows-spawn.h" #else diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c index 947825a..1a7a1e1 100644 --- a/lib/spawn-pipe.c +++ b/lib/spawn-pipe.c @@ -44,7 +44,7 @@ /* Native Windows API. */ # include <process.h> -# include "w32spawn.h" +# include "windows-spawn.h" #else diff --git a/lib/w32spawn.h b/lib/windows-spawn.c similarity index 73% rename from lib/w32spawn.h rename to lib/windows-spawn.c index a4b3b1e..eedb7e4 100644 --- a/lib/w32spawn.h +++ b/lib/windows-spawn.c @@ -15,6 +15,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include <config.h> + +/* Specification. */ +#include "windows-spawn.h" + #ifndef __KLIBC__ /* Get declarations of the native Windows API functions. */ # define WIN32_LEAN_AND_MEAN @@ -25,19 +30,25 @@ #include <io.h> #include <stdbool.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> /* Get _get_osfhandle(). */ -# if GNULIB_MSVC_NOTHROW -# include "msvc-nothrow.h" -# else -# include <io.h> -# endif +#if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +#else +# include <io.h> +#endif #include "cloexec.h" +#include "error.h" #include "xalloc.h" +#include "gettext.h" + +#define _(str) gettext (str) + /* Duplicates a file handle, making the copy uninheritable. Returns -1 for a file handle that is equivalent to closed. */ @@ -71,17 +82,13 @@ fd_safer_noinherit (int fd) return fd; } -/* Duplicates a file handle, making the copy uninheritable and ensuring the - result is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. - Returns -1 for a file handle that is equivalent to closed. */ -static int +int dup_safer_noinherit (int fd) { return fd_safer_noinherit (dup_noinherit (fd)); } -/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD); */ -static void +void undup_safer_noinherit (int tempfd, int origfd) { if (tempfd >= 0) @@ -99,36 +106,6 @@ undup_safer_noinherit (int tempfd, int origfd) } } -/* Prepares an argument vector before calling spawn(). - Note that spawn() does not by itself call the command interpreter - (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : - ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&v); - v.dwPlatformId == VER_PLATFORM_WIN32_NT; - }) ? "cmd.exe" : "command.com"). - Instead it simply concatenates the arguments, separated by ' ', and calls - CreateProcess(). We must quote the arguments since Windows CreateProcess() - interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a - special way: - - Space and tab are interpreted as delimiters. They are not treated as - delimiters if they are surrounded by double quotes: "...". - - Unescaped double quotes are removed from the input. Their only effect is - that within double quotes, space and tab are treated like normal - characters. - - Backslashes not followed by double quotes are not special. - - But 2*n+1 backslashes followed by a double quote become - n backslashes followed by a double quote (n >= 0): - \" -> " - \\\" -> \" - \\\\\" -> \\" - - '*', '?' characters may get expanded through wildcard expansion in the - callee: By default, in the callee, the initialization code before main() - takes the result of GetCommandLine(), wildcard-expands it, and passes it - to main(). The exceptions to this rule are: - - programs that inspect GetCommandLine() and ignore argv, - - mingw programs that have a global variable 'int _CRT_glob = 0;', - - Cygwin programs, when invoked from a Cygwin program. - */ #ifndef __KLIBC__ # define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?" # define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" @@ -136,7 +113,7 @@ undup_safer_noinherit (int tempfd, int origfd) # define SHELL_SPECIAL_CHARS "" # define SHELL_SPACE_CHARS "" #endif -static char ** +char ** prepare_spawn (char **argv) { size_t argc; diff --git a/lib/windows-spawn.h b/lib/windows-spawn.h new file mode 100644 index 0000000..200f321 --- /dev/null +++ b/lib/windows-spawn.h @@ -0,0 +1,61 @@ +/* Auxiliary functions for the creation of subprocesses. Native Windows API. + Copyright (C) 2001, 2003-2020 Free Software Foundation, Inc. + Written by Bruno Haible <br...@clisp.org>, 2003. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +#ifndef _WINDOWS_SPAWN_H +#define _WINDOWS_SPAWN_H + +/* Duplicates a file handle, making the copy uninheritable and ensuring the + result is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. + Returns -1 for a file handle that is equivalent to closed. */ +extern int dup_safer_noinherit (int fd); + +/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD); */ +extern void undup_safer_noinherit (int tempfd, int origfd); + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Windows CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + - '*', '?' characters may get expanded through wildcard expansion in the + callee: By default, in the callee, the initialization code before main() + takes the result of GetCommandLine(), wildcard-expands it, and passes it + to main(). The exceptions to this rule are: + - programs that inspect GetCommandLine() and ignore argv, + - mingw programs that have a global variable 'int _CRT_glob = 0;', + - Cygwin programs, when invoked from a Cygwin program. + */ +extern char ** prepare_spawn (char **argv); + +#endif /* _WINDOWS_SPAWN_H */ diff --git a/modules/execute b/modules/execute index a438fbf..4a7f845 100644 --- a/modules/execute +++ b/modules/execute @@ -4,17 +4,14 @@ Creation of autonomous subprocesses. Files: lib/execute.h lib/execute.c -lib/w32spawn.h m4/execute.m4 Depends-on: -cloexec dup2 error fatal-signal wait-process gettext-h -msvc-nothrow spawn posix_spawnp posix_spawn_file_actions_init @@ -26,16 +23,15 @@ posix_spawnattr_setflags posix_spawnattr_destroy stdbool stdlib -strpbrk unistd environ -xalloc +windows-spawn configure.ac: gl_EXECUTE Makefile.am: -lib_SOURCES += execute.h execute.c w32spawn.h +lib_SOURCES += execute.h execute.c Include: "execute.h" diff --git a/modules/spawn-pipe b/modules/spawn-pipe index dd07fef..2c62586 100644 --- a/modules/spawn-pipe +++ b/modules/spawn-pipe @@ -4,17 +4,14 @@ Creation of subprocesses, communicating via pipes. Files: lib/spawn-pipe.h lib/spawn-pipe.c -lib/w32spawn.h m4/spawn-pipe.m4 Depends-on: -cloexec dup2 environ error fatal-signal gettext-h -msvc-nothrow open pipe2 pipe2-safer @@ -31,17 +28,16 @@ posix_spawnattr_setflags posix_spawnattr_destroy stdbool stdlib -strpbrk unistd unistd-safer wait-process -xalloc +windows-spawn configure.ac: gl_SPAWN_PIPE Makefile.am: -lib_SOURCES += spawn-pipe.h spawn-pipe.c w32spawn.h +lib_SOURCES += spawn-pipe.h spawn-pipe.c Include: "spawn-pipe.h" diff --git a/modules/windows-spawn b/modules/windows-spawn new file mode 100644 index 0000000..747f8bb --- /dev/null +++ b/modules/windows-spawn @@ -0,0 +1,37 @@ +Description: +Auxiliary functions for the creation of subprocesses on native Windows. + +Files: +lib/windows-spawn.h +lib/windows-spawn.c + +Depends-on: +cloexec +dup2 +error +gettext-h +msvc-nothrow +stdbool +stdlib +strpbrk +unistd +xalloc + +configure.ac: +AC_REQUIRE([AC_CANONICAL_HOST]) +case "$host_os" in + mingw*) + AC_LIBOBJ([windows-spawn]) + ;; +esac + +Makefile.am: + +Include: +"windows-spawn.h" + +License: +GPL + +Maintainer: +all