(root)/
bison-3.8.2/
lib/
windows-spawn.h
       1  /* Auxiliary functions for the creation of subprocesses.  Native Windows API.
       2     Copyright (C) 2001, 2003-2021 Free Software Foundation, Inc.
       3     Written by Bruno Haible <bruno@clisp.org>, 2003.
       4  
       5     This file is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     This file is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #ifndef _WINDOWS_SPAWN_H
      19  #define _WINDOWS_SPAWN_H
      20  
      21  #include <stdbool.h>
      22  #include <stdint.h>
      23  #include <stdlib.h>
      24  
      25  /* Get declarations of the native Windows API functions.  */
      26  #define WIN32_LEAN_AND_MEAN
      27  #include <windows.h>
      28  
      29  
      30  /* Prepares an argument vector before calling spawn().
      31  
      32     Note that spawn() does not by itself call the command interpreter
      33       (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
      34        ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
      35           GetVersionEx(&v);
      36           v.dwPlatformId == VER_PLATFORM_WIN32_NT;
      37        }) ? "cmd.exe" : "command.com").
      38     Instead it simply concatenates the arguments, separated by ' ', and calls
      39     CreateProcess().  We must quote the arguments since Windows CreateProcess()
      40     interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
      41     special way:
      42     - Space and tab are interpreted as delimiters. They are not treated as
      43       delimiters if they are surrounded by double quotes: "...".
      44     - Unescaped double quotes are removed from the input. Their only effect is
      45       that within double quotes, space and tab are treated like normal
      46       characters.
      47     - Backslashes not followed by double quotes are not special.
      48     - But 2*n+1 backslashes followed by a double quote become
      49       n backslashes followed by a double quote (n >= 0):
      50         \" -> "
      51         \\\" -> \"
      52         \\\\\" -> \\"
      53     - '*', '?' characters may get expanded through wildcard expansion in the
      54       callee: By default, in the callee, the initialization code before main()
      55       takes the result of GetCommandLine(), wildcard-expands it, and passes it
      56       to main(). The exceptions to this rule are:
      57         - programs that inspect GetCommandLine() and ignore argv,
      58         - mingw programs that have a global variable 'int _CRT_glob = 0;',
      59         - Cygwin programs, when invoked from a Cygwin program.
      60  
      61     prepare_spawn creates and returns a new argument vector, where the arguments
      62     are appropriately quoted and an additional argument "sh.exe" has been added
      63     at the beginning.  The new argument vector is freshly allocated.  The memory
      64     for all its elements is allocated within *MEM_TO_FREE, which is freshly
      65     allocated as well.  In case of memory allocation failure, NULL is returned,
      66     with errno set.
      67   */
      68  extern const char ** prepare_spawn (const char * const *argv,
      69                                      char **mem_to_free);
      70  
      71  /* Composes the command to be passed to CreateProcess().
      72     ARGV must contain appropriately quoted arguments, as returned by
      73     prepare_spawn.
      74     Returns a freshly allocated string.  In case of memory allocation failure,
      75     NULL is returned, with errno set.  */
      76  extern char * compose_command (const char * const *argv)
      77    _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
      78  
      79  /* Composes the block of memory that contains the environment variables.
      80     ENVP must contain an environment (a NULL-terminated array of string of the
      81     form VARIABLE=VALUE).
      82     Returns a freshly allocated block of memory.  In case of memory allocation
      83     failure, NULL is returned, with errno set.  */
      84  extern char * compose_envblock (const char * const *envp)
      85    _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
      86  
      87  
      88  /* This struct keeps track of which handles to pass to a subprocess, and with
      89     which flags.  All of the handles here are inheritable.
      90     Regarding handle inheritance, see
      91     <https://docs.microsoft.com/en-us/windows/win32/sysinfo/handle-inheritance>  */
      92  struct inheritable_handles
      93  {
      94    /* The number of occupied entries in the two arrays below.
      95       3 <= count <= allocated.  */
      96    size_t count;
      97    /* The number of allocated entries in the two arrays below.  */
      98    size_t allocated;
      99    /* handles[0..count-1] are the occupied entries.
     100       handles[fd] is either INVALID_HANDLE_VALUE or an inheritable handle.  */
     101    HANDLE *handles;
     102    /* flags[0..count-1] are the occupied entries.
     103       flags[fd] is only relevant if handles[fd] != INVALID_HANDLE_VALUE.
     104       It is a bit mask consisting of:
     105         - 32 for O_APPEND.
     106     */
     107    unsigned char *flags;
     108  };
     109  
     110  /* Initializes a set of inheritable handles, filling in all inheritable handles
     111     assigned to file descriptors.
     112     If DUPLICATE is true, the handles stored in the set are duplicates.
     113     Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
     114   */
     115  extern int init_inheritable_handles (struct inheritable_handles *inh_handles,
     116                                       bool duplicate);
     117  
     118  /* Fills a set of inheritable handles into a STARTUPINFO for CreateProcess().
     119     Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
     120   */
     121  extern int compose_handles_block (const struct inheritable_handles *inh_handles,
     122                                    STARTUPINFOA *sinfo);
     123  
     124  /* Frees the memory held by a set of inheritable handles.  */
     125  extern void free_inheritable_handles (struct inheritable_handles *inh_handles);
     126  
     127  
     128  /* Converts a CreateProcess() error code (retrieved through GetLastError()) to
     129     an errno value.  */
     130  extern int convert_CreateProcess_error (DWORD error);
     131  
     132  
     133  /* Creates a subprocess.
     134     MODE is either P_WAIT or P_NOWAIT.
     135     PROGNAME is the program to invoke.
     136     ARGV is the NULL-terminated array of arguments, ARGV[0] being PROGNAME by
     137     convention.
     138     ENVP is the NULL-terminated set of environment variable assignments, or NULL
     139     to inherit the initial environ variable assignments from the caller and
     140     ignore all calls to putenv(), setenv(), unsetenv() done in the caller.
     141     CURRDIR is the directory in which to start the program, or NULL to inherit
     142     the working directory from the caller.
     143     STDIN_HANDLE, STDOUT_HANDLE, STDERR_HANDLE are the handles to use for the
     144     first three file descriptors in the callee process.
     145     Returns
     146       - 0 for success (if MODE is P_WAIT), or
     147       - a handle that be passed to _cwait (on Windows) or waitpid (on OS/2), or
     148       - -1 upon error, with errno set.
     149   */
     150  extern intptr_t spawnpvech (int mode,
     151                              const char *progname, const char * const *argv,
     152                              const char * const *envp,
     153                              const char *currdir,
     154                              HANDLE stdin_handle, HANDLE stdout_handle,
     155                              HANDLE stderr_handle);
     156  
     157  #endif /* _WINDOWS_SPAWN_H */