diff options
author | axc <axc@yandex-team.ru> | 2022-02-10 16:47:35 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:35 +0300 |
commit | 1f5217043ad70f25dc35e75b3bd261a1e23d045e (patch) | |
tree | 11bf68c1fa5272d3d3446cbd5a0ff96ed9d75788 /contrib/tools/bison/gnulib/src/w32spawn.h | |
parent | 69505a07cbb096113e85aa02e7d136cac4aa826c (diff) | |
download | ydb-1f5217043ad70f25dc35e75b3bd261a1e23d045e.tar.gz |
Restoring authorship annotation for <axc@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/bison/gnulib/src/w32spawn.h')
-rw-r--r-- | contrib/tools/bison/gnulib/src/w32spawn.h | 444 |
1 files changed, 222 insertions, 222 deletions
diff --git a/contrib/tools/bison/gnulib/src/w32spawn.h b/contrib/tools/bison/gnulib/src/w32spawn.h index 3b5c08afcd..531333e668 100644 --- a/contrib/tools/bison/gnulib/src/w32spawn.h +++ b/contrib/tools/bison/gnulib/src/w32spawn.h @@ -1,222 +1,222 @@ -/* Auxiliary functions for the creation of subprocesses. Native Windows API. - Copyright (C) 2001, 2003-2013 Free Software Foundation, Inc. - Written by Bruno Haible <bruno@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 <http://www.gnu.org/licenses/>. */ - -/* Get declarations of the native Windows API functions. */ -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -/* Get _open_osfhandle(). */ -#include <io.h> - -#include <stdbool.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -/* Get _get_osfhandle(). */ -#include "msvc-nothrow.h" - -#include "cloexec.h" -#include "xalloc.h" - -/* Duplicates a file handle, making the copy uninheritable. - Returns -1 for a file handle that is equivalent to closed. */ -static int -dup_noinherit (int fd) -{ - fd = dup_cloexec (fd); - if (fd < 0 && errno == EMFILE) - error (EXIT_FAILURE, errno, _("_open_osfhandle failed")); - - return fd; -} - -/* Returns a file descriptor equivalent to FD, except that the resulting file - descriptor is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. - FD must be open and non-inheritable. The result will be non-inheritable as - well. - If FD < 0, FD itself is returned. */ -static int -fd_safer_noinherit (int fd) -{ - if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) - { - /* The recursion depth is at most 3. */ - int nfd = fd_safer_noinherit (dup_noinherit (fd)); - int saved_errno = errno; - close (fd); - errno = saved_errno; - return nfd; - } - 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 -dup_safer_noinherit (int fd) -{ - return fd_safer_noinherit (dup_noinherit (fd)); -} - -/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD); */ -static void -undup_safer_noinherit (int tempfd, int origfd) -{ - if (tempfd >= 0) - { - if (dup2 (tempfd, origfd) < 0) - error (EXIT_FAILURE, errno, _("cannot restore fd %d: dup2 failed"), - origfd); - close (tempfd); - } - else - { - /* origfd was closed or open to no handle at all. Set it to a closed - state. This is (nearly) equivalent to the original state. */ - close (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. - */ -#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" -static char ** -prepare_spawn (char **argv) -{ - size_t argc; - char **new_argv; - size_t i; - - /* Count number of arguments. */ - for (argc = 0; argv[argc] != NULL; argc++) - ; - - /* Allocate new argument vector. */ - 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 Windows - CreateProcess(). */ - *new_argv++ = "sh.exe"; - - /* Put quoted arguments into the new argument vector. */ - for (i = 0; i < argc; i++) - { - const char *string = argv[i]; - - if (string[0] == '\0') - new_argv[i] = xstrdup ("\"\""); - else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) - { - bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); - size_t length; - unsigned int backslashes; - const char *s; - char *quoted_string; - char *p; - - length = 0; - backslashes = 0; - if (quote_around) - length++; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - length += backslashes + 1; - length++; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - length += backslashes + 1; - - quoted_string = (char *) xmalloc (length + 1); - - p = quoted_string; - backslashes = 0; - if (quote_around) - *p++ = '"'; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - { - unsigned int j; - for (j = backslashes + 1; j > 0; j--) - *p++ = '\\'; - } - *p++ = c; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - { - unsigned int j; - for (j = backslashes; j > 0; j--) - *p++ = '\\'; - *p++ = '"'; - } - *p = '\0'; - - new_argv[i] = quoted_string; - } - else - new_argv[i] = (char *) string; - } - new_argv[argc] = NULL; - - return new_argv; -} +/* Auxiliary functions for the creation of subprocesses. Native Windows API. + Copyright (C) 2001, 2003-2013 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@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 <http://www.gnu.org/licenses/>. */ + +/* Get declarations of the native Windows API functions. */ +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +/* Get _open_osfhandle(). */ +#include <io.h> + +#include <stdbool.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +/* Get _get_osfhandle(). */ +#include "msvc-nothrow.h" + +#include "cloexec.h" +#include "xalloc.h" + +/* Duplicates a file handle, making the copy uninheritable. + Returns -1 for a file handle that is equivalent to closed. */ +static int +dup_noinherit (int fd) +{ + fd = dup_cloexec (fd); + if (fd < 0 && errno == EMFILE) + error (EXIT_FAILURE, errno, _("_open_osfhandle failed")); + + return fd; +} + +/* Returns a file descriptor equivalent to FD, except that the resulting file + descriptor is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. + FD must be open and non-inheritable. The result will be non-inheritable as + well. + If FD < 0, FD itself is returned. */ +static int +fd_safer_noinherit (int fd) +{ + if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) + { + /* The recursion depth is at most 3. */ + int nfd = fd_safer_noinherit (dup_noinherit (fd)); + int saved_errno = errno; + close (fd); + errno = saved_errno; + return nfd; + } + 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 +dup_safer_noinherit (int fd) +{ + return fd_safer_noinherit (dup_noinherit (fd)); +} + +/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD); */ +static void +undup_safer_noinherit (int tempfd, int origfd) +{ + if (tempfd >= 0) + { + if (dup2 (tempfd, origfd) < 0) + error (EXIT_FAILURE, errno, _("cannot restore fd %d: dup2 failed"), + origfd); + close (tempfd); + } + else + { + /* origfd was closed or open to no handle at all. Set it to a closed + state. This is (nearly) equivalent to the original state. */ + close (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. + */ +#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" +static char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + 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 Windows + CreateProcess(). */ + *new_argv++ = "sh.exe"; + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = (char *) xmalloc (length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} |