Guitar
winpty.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2016 Ryan Prichard
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  */
22 
23 #ifndef WINPTY_H
24 #define WINPTY_H
25 
26 #include <windows.h>
27 
28 #include "winpty_constants.h"
29 
30 /* On 32-bit Windows, winpty functions have the default __cdecl (not __stdcall)
31  * calling convention. (64-bit Windows has only a single calling convention.)
32  * When compiled with __declspec(dllexport), with either MinGW or MSVC, the
33  * winpty functions are unadorned--no underscore prefix or '@nn' suffix--so
34  * GetProcAddress can be used easily. */
35 #ifdef COMPILING_WINPTY_DLL
36 #define WINPTY_API __declspec(dllexport)
37 #else
38 #define WINPTY_API __declspec(dllimport)
39 #endif
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /* The winpty API uses wide characters, instead of UTF-8, to avoid conversion
46  * complications related to surrogates. Windows generally tolerates unpaired
47  * surrogates in text, which makes conversion to and from UTF-8 ambiguous and
48  * complicated. (There are different UTF-8 variants that deal with UTF-16
49  * surrogates differently.) */
50 
51 
52 
53 /*****************************************************************************
54  * Error handling. */
55 
56 /* All the APIs have an optional winpty_error_t output parameter. If a
57  * non-NULL argument is specified, then either the API writes NULL to the
58  * value (on success) or writes a newly allocated winpty_error_t object. The
59  * object must be freed using winpty_error_free. */
60 
61 /* An error object. */
62 typedef struct winpty_error_s winpty_error_t;
64 
65 /* An error code -- one of WINPTY_ERROR_xxx. */
66 typedef DWORD winpty_result_t;
67 
68 /* Gets the error code from the error object. */
70 
71 /* Returns a textual representation of the error. The string is freed when
72  * the error is freed. */
74 
75 /* Free the error object. Every error returned from the winpty API must be
76  * freed. */
78 
79 
80 
81 /*****************************************************************************
82  * Configuration of a new agent. */
83 
84 /* The winpty_config_t object is not thread-safe. */
85 typedef struct winpty_config_s winpty_config_t;
86 
87 /* Allocate a winpty_config_t value. Returns NULL on error. There are no
88  * required settings -- the object may immediately be used. agentFlags is a
89  * set of zero or more WINPTY_FLAG_xxx values. An unrecognized flag results
90  * in an assertion failure. */
92 winpty_config_new(UINT64 agentFlags, winpty_error_ptr_t *err /*OPTIONAL*/);
93 
94 /* Free the cfg object after passing it to winpty_open. */
96 
97 WINPTY_API void
99 
100 /* Set the mouse mode to one of the WINPTY_MOUSE_MODE_xxx constants. */
101 WINPTY_API void
103 
104 /* Amount of time to wait for the agent to startup and to wait for any given
105  * agent RPC request. Must be greater than 0. Can be INFINITE. */
106 WINPTY_API void
108 
109 
110 
111 /*****************************************************************************
112  * Start the agent. */
113 
114 /* The winpty_t object is thread-safe. */
115 typedef struct winpty_s winpty_t;
116 
117 /* Starts the agent. Returns NULL on error. This process will connect to the
118  * agent over a control pipe, and the agent will open data pipes (e.g. CONIN
119  * and CONOUT). */
122  winpty_error_ptr_t *err /*OPTIONAL*/);
123 
124 /* A handle to the agent process. This value is valid for the lifetime of the
125  * winpty_t object. Do not close it. */
127 
128 
129 
130 /*****************************************************************************
131  * I/O pipes. */
132 
133 /* Returns the names of named pipes used for terminal I/O. Each input or
134  * output direction uses a different half-duplex pipe. The agent creates
135  * these pipes, and the client can connect to them using ordinary I/O methods.
136  * The strings are freed when the winpty_t object is freed.
137  *
138  * winpty_conerr_name returns NULL unless WINPTY_FLAG_CONERR is specified.
139  *
140  * N.B.: CreateFile does not block when connecting to a local server pipe. If
141  * the server pipe does not exist or is already connected, then it fails
142  * instantly. */
146 
147 
148 
149 /*****************************************************************************
150  * winpty agent RPC call: process creation. */
151 
152 /* The winpty_spawn_config_t object is not thread-safe. */
153 typedef struct winpty_spawn_config_s winpty_spawn_config_t;
154 
155 /* winpty_spawn_config strings do not need to live as long as the config
156  * object. They are copied. Returns NULL on error. spawnFlags is a set of
157  * zero or more WINPTY_SPAWN_FLAG_xxx values. An unrecognized flag results in
158  * an assertion failure.
159  *
160  * env is a a pointer to an environment block like that passed to
161  * CreateProcess--a contiguous array of NUL-terminated "VAR=VAL" strings
162  * followed by a final NUL terminator.
163  *
164  * N.B.: If you want to gather all of the child's output, you may want the
165  * WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN flag.
166  */
168 winpty_spawn_config_new(UINT64 spawnFlags,
169  LPCWSTR appname /*OPTIONAL*/,
170  LPCWSTR cmdline /*OPTIONAL*/,
171  LPCWSTR cwd /*OPTIONAL*/,
172  LPCWSTR env /*OPTIONAL*/,
173  winpty_error_ptr_t *err /*OPTIONAL*/);
174 
175 /* Free the cfg object after passing it to winpty_spawn. */
177 
178 /*
179  * Spawns the new process.
180  *
181  * The function initializes all output parameters to zero or NULL.
182  *
183  * On success, the function returns TRUE. For each of process_handle and
184  * thread_handle that is non-NULL, the HANDLE returned from CreateProcess is
185  * duplicated from the agent and returned to the winpty client. The client is
186  * responsible for closing these HANDLES.
187  *
188  * On failure, the function returns FALSE, and if err is non-NULL, then *err
189  * is set to an error object.
190  *
191  * If the agent's CreateProcess call failed, then *create_process_error is set
192  * to GetLastError(), and the WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED error
193  * is returned.
194  *
195  * winpty_spawn can only be called once per winpty_t object. If it is called
196  * before the output data pipe(s) is/are connected, then collected output is
197  * buffered until the pipes are connected, rather than being discarded.
198  *
199  * N.B.: GetProcessId works even if the process has exited. The PID is not
200  * recycled until the NT process object is freed.
201  * (https://blogs.msdn.microsoft.com/oldnewthing/20110107-00/?p=11803)
202  */
203 WINPTY_API BOOL
205  const winpty_spawn_config_t *cfg,
206  HANDLE *process_handle /*OPTIONAL*/,
207  HANDLE *thread_handle /*OPTIONAL*/,
208  DWORD *create_process_error /*OPTIONAL*/,
209  winpty_error_ptr_t *err /*OPTIONAL*/);
210 
211 
212 
213 /*****************************************************************************
214  * winpty agent RPC calls: everything else */
215 
216 /* Change the size of the Windows console window. */
217 WINPTY_API BOOL
218 winpty_set_size(winpty_t *wp, int cols, int rows,
219  winpty_error_ptr_t *err /*OPTIONAL*/);
220 
221 /* Frees the winpty_t object and the OS resources contained in it. This
222  * call breaks the connection with the agent, which should then close its
223  * console, terminating the processes attached to it.
224  *
225  * This function must not be called if any other threads are using the
226  * winpty_t object. Undefined behavior results. */
228 
229 
230 
231 /****************************************************************************/
232 
233 #ifdef __cplusplus
234 }
235 #endif
236 
237 #endif /* WINPTY_H */
winpty_error_t * winpty_error_ptr_t
Definition: winpty.h:63
WINPTY_API void winpty_config_set_mouse_mode(winpty_config_t *cfg, int mouseMode)
struct winpty_config_s winpty_config_t
Definition: winpty.h:85
WINPTY_API BOOL winpty_spawn(winpty_t *wp, const winpty_spawn_config_t *cfg, HANDLE *process_handle, HANDLE *thread_handle, DWORD *create_process_error, winpty_error_ptr_t *err)
WINPTY_API LPCWSTR winpty_conerr_name(winpty_t *wp)
WINPTY_API void winpty_spawn_config_free(winpty_spawn_config_t *cfg)
WINPTY_API winpty_t * winpty_open(const winpty_config_t *cfg, winpty_error_ptr_t *err)
WINPTY_API LPCWSTR winpty_conout_name(winpty_t *wp)
struct winpty_error_s winpty_error_t
Definition: winpty.h:62
struct winpty_spawn_config_s winpty_spawn_config_t
Definition: winpty.h:153
WINPTY_API BOOL winpty_set_size(winpty_t *wp, int cols, int rows, winpty_error_ptr_t *err)
DWORD winpty_result_t
Definition: winpty.h:66
#define WINPTY_API
Definition: winpty.h:38
struct winpty_s winpty_t
Definition: winpty.h:115
WINPTY_API HANDLE winpty_agent_process(winpty_t *wp)
WINPTY_API void winpty_config_free(winpty_config_t *cfg)
WINPTY_API winpty_spawn_config_t * winpty_spawn_config_new(UINT64 spawnFlags, LPCWSTR appname, LPCWSTR cmdline, LPCWSTR cwd, LPCWSTR env, winpty_error_ptr_t *err)
WINPTY_API void winpty_free(winpty_t *wp)
WINPTY_API void winpty_config_set_initial_size(winpty_config_t *cfg, int cols, int rows)
WINPTY_API LPCWSTR winpty_conin_name(winpty_t *wp)
WINPTY_API void winpty_config_set_agent_timeout(winpty_config_t *cfg, DWORD timeoutMs)
WINPTY_API LPCWSTR winpty_error_msg(winpty_error_ptr_t err)
WINPTY_API winpty_config_t * winpty_config_new(UINT64 agentFlags, winpty_error_ptr_t *err)
WINPTY_API winpty_result_t winpty_error_code(winpty_error_ptr_t err)
WINPTY_API void winpty_error_free(winpty_error_ptr_t err)