gettext: Sync with gettext 0.23.
[gnulib.git] / lib / windows-spawn.h
blob3a33016a5c5f653bd7281e099cb7a1b5e8aae54a
1 /* Auxiliary functions for the creation of subprocesses. Native Windows API.
2 Copyright (C) 2001, 2003-2024 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
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.
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.
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/>. */
18 #ifndef _WINDOWS_SPAWN_H
19 #define _WINDOWS_SPAWN_H
21 /* This file uses _GL_ATTRIBUTE_MALLOC. */
22 #if !_GL_CONFIG_H_INCLUDED
23 #error "Please include config.h first."
24 #endif
26 #include <stdint.h>
27 #include <stdlib.h>
29 /* Get declarations of the native Windows API functions. */
30 #define WIN32_LEAN_AND_MEAN
31 #include <windows.h>
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
39 /* Prepares an argument vector before calling spawn().
41 Note that spawn() does not by itself call the command interpreter
42 (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
43 ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
44 GetVersionEx(&v);
45 v.dwPlatformId == VER_PLATFORM_WIN32_NT;
46 }) ? "cmd.exe" : "command.com").
47 Instead it simply concatenates the arguments, separated by ' ', and calls
48 CreateProcess(). We must quote the arguments since Windows CreateProcess()
49 interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
50 special way:
51 - Space and tab are interpreted as delimiters. They are not treated as
52 delimiters if they are surrounded by double quotes: "...".
53 - Unescaped double quotes are removed from the input. Their only effect is
54 that within double quotes, space and tab are treated like normal
55 characters.
56 - Backslashes not followed by double quotes are not special.
57 - But 2*n+1 backslashes followed by a double quote become
58 n backslashes followed by a double quote (n >= 0):
59 \" -> "
60 \\\" -> \"
61 \\\\\" -> \\"
62 - '*', '?' characters may get expanded through wildcard expansion in the
63 callee: By default, in the callee, the initialization code before main()
64 takes the result of GetCommandLine(), wildcard-expands it, and passes it
65 to main(). The exceptions to this rule are:
66 - programs that inspect GetCommandLine() and ignore argv,
67 - mingw programs that have a global variable 'int _CRT_glob = 0;',
68 - Cygwin programs, when invoked from a Cygwin program.
70 prepare_spawn creates and returns a new argument vector, where the arguments
71 are appropriately quoted and an additional argument "sh.exe" has been added
72 at the beginning. The new argument vector is freshly allocated. The memory
73 for all its elements is allocated within *MEM_TO_FREE, which is freshly
74 allocated as well. In case of memory allocation failure, NULL is returned,
75 with errno set.
77 extern const char ** prepare_spawn (const char * const *argv,
78 char **mem_to_free);
80 /* Composes the command to be passed to CreateProcess().
81 ARGV must contain appropriately quoted arguments, as returned by
82 prepare_spawn.
83 Returns a freshly allocated string. In case of memory allocation failure,
84 NULL is returned, with errno set. */
85 extern char * compose_command (const char * const *argv)
86 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
88 /* Composes the block of memory that contains the environment variables.
89 ENVP must contain an environment (a NULL-terminated array of string of the
90 form VARIABLE=VALUE).
91 NEW_PATH must be a string of the form PATH=VALUE, or NULL if the PATH
92 environment variable from this process is suitable for the child process.
93 Returns a freshly allocated block of memory. In case of memory allocation
94 failure, NULL is returned, with errno set. */
95 extern char * compose_envblock (const char * const *envp, const char *new_PATH)
96 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
99 /* An inheritable handle with some additional information. */
100 struct IHANDLE
102 /* Either INVALID_HANDLE_VALUE or an inheritable handle. */
103 HANDLE handle;
104 /* Only relevant if handle != INVALID_HANDLE_VALUE.
105 It is a bit mask consisting of:
106 - 32 for O_APPEND.
107 - KEEP_OPEN_IN_CHILD if the handle is scheduled to be preserved in the
108 child process.
109 - KEEP_OPEN_IN_PARENT if the handle is shared with (and needs to be kept
110 open in) the parent process.
111 - DELAYED_DUP2_OLDFD if there is a delayed dup2 (oldfd, newfd) and
112 this IHANDLE is at position oldfd.
113 - DELAYED_DUP2_NEWFD if there is a delayed dup2 (oldfd, newfd) and
114 this IHANDLE is at position newfd.
115 Note that DELAYED_DUP2_OLDFD and DELAYED_DUP2_NEWFD cannot be set in the
116 same IHANDLE. */
117 unsigned short flags;
118 #define KEEP_OPEN_IN_CHILD 0x100
119 #define KEEP_OPEN_IN_PARENT 0x200
120 #define DELAYED_DUP2_OLDFD 0x400
121 #define DELAYED_DUP2_NEWFD 0x800
122 /* Only relevant if handle != INVALID_HANDLE_VALUE and flags contains
123 either DELAYED_DUP2_OLDFD or DELAYED_DUP2_NEWFD.
124 It is the other fd of the delayed dup2 (oldfd, newfd), i.e.
125 - for DELAYED_DUP2_OLDFD, the newfd,
126 - for DELAYED_DUP2_NEWFD, the oldfd. */
127 int linked_fd;
130 /* This struct keeps track of which handles to potentially pass to a subprocess,
131 and with which flags. All of the handles here are inheritable.
132 Regarding handle inheritance, see
133 <https://docs.microsoft.com/en-us/windows/win32/sysinfo/handle-inheritance>.
134 Whether a handle is actually scheduled for being preserved in the child
135 process is determined by the KEEP_OPEN_IN_CHILD bit in the flags. */
136 struct inheritable_handles
138 /* The number of occupied entries in the two arrays below.
139 3 <= count <= allocated. */
140 size_t count;
141 /* The number of allocated entries in the two arrays below. */
142 size_t allocated;
143 /* ih[0..count-1] are the occupied entries. */
144 struct IHANDLE *ih;
147 /* Initializes a set of inheritable handles, filling in all or part of the
148 file descriptors of the current process.
149 If DUPLICATE is true, the handles stored are those of all file descriptors,
150 and we use DuplicateHandle to make sure that they are all inheritable.
151 If DUPLICATE is false, the handles stored are only the inheritables ones;
152 this is a shortcut for spawnpvech().
153 Returns 0 upon success. In case of failure, -1 is returned, with errno set.
155 extern int init_inheritable_handles (struct inheritable_handles *inh_handles,
156 bool duplicate);
158 /* Fills a set of inheritable handles into a STARTUPINFO for CreateProcess().
159 Returns 0 upon success. In case of failure, -1 is returned, with errno set.
161 extern int compose_handles_block (const struct inheritable_handles *inh_handles,
162 STARTUPINFOA *sinfo);
164 /* Frees the memory held by a set of inheritable handles. */
165 extern void free_inheritable_handles (struct inheritable_handles *inh_handles);
168 /* Converts a CreateProcess() error code (retrieved through GetLastError()) to
169 an errno value. */
170 extern int convert_CreateProcess_error (DWORD error);
173 /* Creates a subprocess.
174 MODE is either P_WAIT or P_NOWAIT.
175 PROGNAME is the program to invoke.
176 ARGV is the NULL-terminated array of arguments, ARGV[0] being PROGNAME by
177 convention.
178 ENVP is the NULL-terminated set of environment variable assignments, or NULL
179 to inherit the initial environ variable assignments from the caller and
180 ignore all calls to putenv(), setenv(), unsetenv() done in the caller.
181 DLL_DIRS is, on Windows platforms, a NULL-terminated list of directories
182 that contain DLLs needed to execute the program, or NULL if none is needed.
183 On other platforms, always pass NULL.
184 CURRDIR is the directory in which to start the program, or NULL to inherit
185 the working directory from the caller.
186 STDIN_HANDLE, STDOUT_HANDLE, STDERR_HANDLE are the handles to use for the
187 first three file descriptors in the callee process.
188 Returns
189 - 0 for success (if MODE is P_WAIT), or
190 - a handle that be passed to _cwait (on Windows) or waitpid (on OS/2), or
191 - -1 upon error, with errno set.
193 extern intptr_t spawnpvech (int mode,
194 const char *progname, const char * const *argv,
195 const char * const *envp,
196 const char * const *dll_dirs,
197 const char *currdir,
198 HANDLE stdin_handle, HANDLE stdout_handle,
199 HANDLE stderr_handle);
202 #ifdef __cplusplus
204 #endif
206 #endif /* _WINDOWS_SPAWN_H */