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