blob: 77a8a85e47e94c6d76893bc71fd5d563c3f75b2c [file] [log] [blame]
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001/*
2 * support routines for subprocess module
3 *
4 * Currently, this extension module is only required when using the
5 * subprocess module on Windows, but in the future, stubs for other
Tim Petersf3250b02004-10-12 21:38:22 +00006 * platforms might be added here as well.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00007 *
8 * Copyright (c) 2004 by Fredrik Lundh <fredrik@pythonware.com>
9 * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com
10 * Copyright (c) 2004 by Peter Astrand <astrand@lysator.liu.se>
Tim Petersf3250b02004-10-12 21:38:22 +000011 *
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000012 * By obtaining, using, and/or copying this software and/or its
13 * associated documentation, you agree that you have read, understood,
14 * and will comply with the following terms and conditions:
Tim Petersf3250b02004-10-12 21:38:22 +000015 *
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000016 * Permission to use, copy, modify, and distribute this software and
17 * its associated documentation for any purpose and without fee is
18 * hereby granted, provided that the above copyright notice appears in
19 * all copies, and that both that copyright notice and this permission
20 * notice appear in supporting documentation, and that the name of the
21 * authors not be used in advertising or publicity pertaining to
22 * distribution of the software without specific, written prior
23 * permission.
Tim Petersf3250b02004-10-12 21:38:22 +000024 *
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000025 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
27 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
28 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
29 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
30 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
31 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Tim Petersf3250b02004-10-12 21:38:22 +000032 *
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000033 */
34
Fredrik Lundh63168a52005-12-14 22:29:34 +000035/* Licensed to PSF under a Contributor Agreement. */
36/* See http://www.python.org/2.4/license for licensing details. */
37
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000038#include "Python.h"
39
40#define WINDOWS_LEAN_AND_MEAN
41#include "windows.h"
42
43/* -------------------------------------------------------------------- */
44/* handle wrapper. note that this library uses integers when passing
45 handles to a function, and handle wrappers when returning handles.
46 the wrapper is used to provide Detach and Close methods */
47
48typedef struct {
Tim Petersf3250b02004-10-12 21:38:22 +000049 PyObject_HEAD
50 HANDLE handle;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000051} sp_handle_object;
52
Neal Norwitz227b5332006-03-22 09:28:35 +000053static PyTypeObject sp_handle_type;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000054
55static PyObject*
56sp_handle_new(HANDLE handle)
57{
Tim Petersf3250b02004-10-12 21:38:22 +000058 sp_handle_object* self;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000059
Tim Petersf3250b02004-10-12 21:38:22 +000060 self = PyObject_NEW(sp_handle_object, &sp_handle_type);
61 if (self == NULL)
62 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000063
Tim Petersf3250b02004-10-12 21:38:22 +000064 self->handle = handle;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000065
Tim Petersf3250b02004-10-12 21:38:22 +000066 return (PyObject*) self;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000067}
68
69static PyObject*
70sp_handle_detach(sp_handle_object* self, PyObject* args)
71{
Tim Petersf3250b02004-10-12 21:38:22 +000072 HANDLE handle;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000073
Tim Petersf3250b02004-10-12 21:38:22 +000074 if (! PyArg_ParseTuple(args, ":Detach"))
75 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000076
Tim Petersf3250b02004-10-12 21:38:22 +000077 handle = self->handle;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000078
Tim Petersf3250b02004-10-12 21:38:22 +000079 self->handle = NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000080
Tim Petersf3250b02004-10-12 21:38:22 +000081 /* note: return the current handle, as an integer */
Christian Heimes217cfd12007-12-02 14:31:20 +000082 return PyLong_FromLong((long) handle);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000083}
84
85static PyObject*
86sp_handle_close(sp_handle_object* self, PyObject* args)
87{
Tim Petersf3250b02004-10-12 21:38:22 +000088 if (! PyArg_ParseTuple(args, ":Close"))
89 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000090
Tim Petersf3250b02004-10-12 21:38:22 +000091 if (self->handle != INVALID_HANDLE_VALUE) {
92 CloseHandle(self->handle);
93 self->handle = INVALID_HANDLE_VALUE;
94 }
95 Py_INCREF(Py_None);
96 return Py_None;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000097}
98
99static void
100sp_handle_dealloc(sp_handle_object* self)
101{
Tim Petersf3250b02004-10-12 21:38:22 +0000102 if (self->handle != INVALID_HANDLE_VALUE)
103 CloseHandle(self->handle);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000104 PyObject_FREE(self);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000105}
106
107static PyMethodDef sp_handle_methods[] = {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000108 {"Detach", (PyCFunction) sp_handle_detach, METH_VARARGS},
109 {"Close", (PyCFunction) sp_handle_close, METH_VARARGS},
Tim Petersf3250b02004-10-12 21:38:22 +0000110 {NULL, NULL}
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000111};
112
Tim Petersf3250b02004-10-12 21:38:22 +0000113static PyObject*
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000114sp_handle_as_int(sp_handle_object* self)
115{
Christian Heimes217cfd12007-12-02 14:31:20 +0000116 return PyLong_FromLong((long) self->handle);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000117}
118
119static PyNumberMethods sp_handle_as_number;
120
Neal Norwitz227b5332006-03-22 09:28:35 +0000121static PyTypeObject sp_handle_type = {
Martin v. Löwis95c95ce2007-07-22 14:41:55 +0000122 PyVarObject_HEAD_INIT(NULL, 0)
Tim Petersf3250b02004-10-12 21:38:22 +0000123 "_subprocess_handle", sizeof(sp_handle_object), 0,
124 (destructor) sp_handle_dealloc, /*tp_dealloc*/
125 0, /*tp_print*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000126 0, /*tp_getattr*/
Tim Petersf3250b02004-10-12 21:38:22 +0000127 0, /*tp_setattr*/
128 0, /*tp_compare*/
129 0, /*tp_repr*/
130 &sp_handle_as_number, /*tp_as_number */
131 0, /*tp_as_sequence */
132 0, /*tp_as_mapping */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000133 0, /*tp_hash*/
134 0, /*tp_call*/
135 0, /*tp_str*/
136 0, /*tp_getattro*/
137 0, /*tp_setattro*/
138 0, /*tp_as_buffer*/
139 Py_TPFLAGS_DEFAULT, /*tp_flags*/
140 0, /*tp_doc*/
141 0, /*tp_traverse*/
142 0, /*tp_clear*/
143 0, /*tp_richcompare*/
144 0, /*tp_weaklistoffset*/
145 0, /*tp_iter*/
146 0, /*tp_iternext*/
147 sp_handle_methods, /*tp_methods*/
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000148};
149
150/* -------------------------------------------------------------------- */
151/* windows API functions */
152
153static PyObject *
154sp_GetStdHandle(PyObject* self, PyObject* args)
155{
Tim Petersf3250b02004-10-12 21:38:22 +0000156 HANDLE handle;
157 int std_handle;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000158
Tim Petersf3250b02004-10-12 21:38:22 +0000159 if (! PyArg_ParseTuple(args, "i:GetStdHandle", &std_handle))
160 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000161
Tim Petersf3250b02004-10-12 21:38:22 +0000162 Py_BEGIN_ALLOW_THREADS
163 handle = GetStdHandle((DWORD) std_handle);
164 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000165
Tim Petersf3250b02004-10-12 21:38:22 +0000166 if (handle == INVALID_HANDLE_VALUE)
167 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000168
Tim Petersf3250b02004-10-12 21:38:22 +0000169 if (! handle) {
170 Py_INCREF(Py_None);
171 return Py_None;
172 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000173
Tim Petersf3250b02004-10-12 21:38:22 +0000174 /* note: returns integer, not handle object */
Christian Heimes217cfd12007-12-02 14:31:20 +0000175 return PyLong_FromLong((long) handle);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000176}
177
178static PyObject *
179sp_GetCurrentProcess(PyObject* self, PyObject* args)
180{
Tim Petersf3250b02004-10-12 21:38:22 +0000181 if (! PyArg_ParseTuple(args, ":GetCurrentProcess"))
182 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000183
Tim Petersf3250b02004-10-12 21:38:22 +0000184 return sp_handle_new(GetCurrentProcess());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000185}
186
187static PyObject *
188sp_DuplicateHandle(PyObject* self, PyObject* args)
189{
Tim Petersf3250b02004-10-12 21:38:22 +0000190 HANDLE target_handle;
191 BOOL result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000192
Tim Petersf3250b02004-10-12 21:38:22 +0000193 long source_process_handle;
194 long source_handle;
195 long target_process_handle;
196 int desired_access;
197 int inherit_handle;
198 int options = 0;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000199
Tim Petersf3250b02004-10-12 21:38:22 +0000200 if (! PyArg_ParseTuple(args, "lllii|i:DuplicateHandle",
201 &source_process_handle,
202 &source_handle,
203 &target_process_handle,
204 &desired_access,
205 &inherit_handle,
206 &options))
207 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000208
Tim Petersf3250b02004-10-12 21:38:22 +0000209 Py_BEGIN_ALLOW_THREADS
210 result = DuplicateHandle(
211 (HANDLE) source_process_handle,
212 (HANDLE) source_handle,
213 (HANDLE) target_process_handle,
214 &target_handle,
215 desired_access,
216 inherit_handle,
217 options
218 );
219 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000220
Tim Petersf3250b02004-10-12 21:38:22 +0000221 if (! result)
222 return PyErr_SetFromWindowsErr(GetLastError());
223
224 return sp_handle_new(target_handle);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000225}
226
227static PyObject *
228sp_CreatePipe(PyObject* self, PyObject* args)
229{
Tim Petersf3250b02004-10-12 21:38:22 +0000230 HANDLE read_pipe;
231 HANDLE write_pipe;
232 BOOL result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000233
Tim Petersf3250b02004-10-12 21:38:22 +0000234 PyObject* pipe_attributes; /* ignored */
235 int size;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000236
Tim Petersf3250b02004-10-12 21:38:22 +0000237 if (! PyArg_ParseTuple(args, "Oi:CreatePipe", &pipe_attributes, &size))
238 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000239
Tim Petersf3250b02004-10-12 21:38:22 +0000240 Py_BEGIN_ALLOW_THREADS
241 result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
242 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000243
Tim Petersf3250b02004-10-12 21:38:22 +0000244 if (! result)
245 return PyErr_SetFromWindowsErr(GetLastError());
246
247 return Py_BuildValue(
248 "NN", sp_handle_new(read_pipe), sp_handle_new(write_pipe));
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000249}
250
251/* helpers for createprocess */
252
253static int
254getint(PyObject* obj, char* name)
255{
Tim Petersf3250b02004-10-12 21:38:22 +0000256 PyObject* value;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000257 int ret;
Tim Petersf3250b02004-10-12 21:38:22 +0000258
259 value = PyObject_GetAttrString(obj, name);
260 if (! value) {
261 PyErr_Clear(); /* FIXME: propagate error? */
262 return 0;
263 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000264 ret = (int) PyLong_AsLong(value);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000265 Py_DECREF(value);
266 return ret;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000267}
Tim Petersf3250b02004-10-12 21:38:22 +0000268
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000269static HANDLE
270gethandle(PyObject* obj, char* name)
271{
Tim Petersf3250b02004-10-12 21:38:22 +0000272 sp_handle_object* value;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000273 HANDLE ret;
Tim Petersf3250b02004-10-12 21:38:22 +0000274
275 value = (sp_handle_object*) PyObject_GetAttrString(obj, name);
276 if (! value) {
277 PyErr_Clear(); /* FIXME: propagate error? */
278 return NULL;
279 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000280 if (Py_TYPE(value) != &sp_handle_type)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000281 ret = NULL;
282 else
283 ret = value->handle;
284 Py_DECREF(value);
285 return ret;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000286}
287
288static PyObject*
289getenvironment(PyObject* environment)
290{
Tim Petersf3250b02004-10-12 21:38:22 +0000291 int i, envsize;
292 PyObject* out = NULL;
293 PyObject* keys;
294 PyObject* values;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000295 Py_UNICODE* p;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000296
Tim Petersf3250b02004-10-12 21:38:22 +0000297 /* convert environment dictionary to windows enviroment string */
298 if (! PyMapping_Check(environment)) {
299 PyErr_SetString(
300 PyExc_TypeError, "environment must be dictionary or None");
301 return NULL;
302 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000303
Tim Petersf3250b02004-10-12 21:38:22 +0000304 envsize = PyMapping_Length(environment);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000305
Tim Petersf3250b02004-10-12 21:38:22 +0000306 keys = PyMapping_Keys(environment);
307 values = PyMapping_Values(environment);
308 if (!keys || !values)
309 goto error;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000310
Guido van Rossumfb67be22007-08-29 18:38:11 +0000311 out = PyUnicode_FromUnicode(NULL, 2048);
Tim Petersf3250b02004-10-12 21:38:22 +0000312 if (! out)
313 goto error;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000314
Guido van Rossumfb67be22007-08-29 18:38:11 +0000315 p = PyUnicode_AS_UNICODE(out);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000316
Tim Petersf3250b02004-10-12 21:38:22 +0000317 for (i = 0; i < envsize; i++) {
318 int ksize, vsize, totalsize;
319 PyObject* key = PyList_GET_ITEM(keys, i);
320 PyObject* value = PyList_GET_ITEM(values, i);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000321
Guido van Rossumfb67be22007-08-29 18:38:11 +0000322 if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) {
Tim Petersf3250b02004-10-12 21:38:22 +0000323 PyErr_SetString(PyExc_TypeError,
324 "environment can only contain strings");
325 goto error;
326 }
Guido van Rossumfb67be22007-08-29 18:38:11 +0000327 ksize = PyUnicode_GET_SIZE(key);
328 vsize = PyUnicode_GET_SIZE(value);
329 totalsize = (p - PyUnicode_AS_UNICODE(out)) + ksize + 1 +
Tim Petersf3250b02004-10-12 21:38:22 +0000330 vsize + 1 + 1;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000331 if (totalsize > PyUnicode_GET_SIZE(out)) {
332 int offset = p - PyUnicode_AS_UNICODE(out);
333 PyUnicode_Resize(&out, totalsize + 1024);
334 p = PyUnicode_AS_UNICODE(out) + offset;
Tim Petersf3250b02004-10-12 21:38:22 +0000335 }
Guido van Rossumfb67be22007-08-29 18:38:11 +0000336 Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(key), ksize);
Tim Petersf3250b02004-10-12 21:38:22 +0000337 p += ksize;
338 *p++ = '=';
Guido van Rossumfb67be22007-08-29 18:38:11 +0000339 Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(value), vsize);
Tim Petersf3250b02004-10-12 21:38:22 +0000340 p += vsize;
341 *p++ = '\0';
342 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000343
Tim Petersf3250b02004-10-12 21:38:22 +0000344 /* add trailing null byte */
345 *p++ = '\0';
Guido van Rossumfb67be22007-08-29 18:38:11 +0000346 PyUnicode_Resize(&out, p - PyUnicode_AS_UNICODE(out));
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000347
Tim Petersf3250b02004-10-12 21:38:22 +0000348 /* PyObject_Print(out, stdout, 0); */
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000349
Fredrik Lundhbb4692b2005-11-12 10:15:03 +0000350 Py_XDECREF(keys);
351 Py_XDECREF(values);
352
Tim Petersf3250b02004-10-12 21:38:22 +0000353 return out;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000354
Tim Petersf3250b02004-10-12 21:38:22 +0000355 error:
356 Py_XDECREF(out);
357 Py_XDECREF(keys);
358 Py_XDECREF(values);
359 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000360}
361
362static PyObject *
363sp_CreateProcess(PyObject* self, PyObject* args)
364{
Tim Petersf3250b02004-10-12 21:38:22 +0000365 BOOL result;
366 PROCESS_INFORMATION pi;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000367 STARTUPINFOW si;
Tim Petersf3250b02004-10-12 21:38:22 +0000368 PyObject* environment;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000369
Guido van Rossumfb67be22007-08-29 18:38:11 +0000370 Py_UNICODE* application_name;
371 Py_UNICODE* command_line;
Tim Petersf3250b02004-10-12 21:38:22 +0000372 PyObject* process_attributes; /* ignored */
373 PyObject* thread_attributes; /* ignored */
374 int inherit_handles;
375 int creation_flags;
376 PyObject* env_mapping;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000377 Py_UNICODE* current_directory;
Tim Petersf3250b02004-10-12 21:38:22 +0000378 PyObject* startup_info;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000379
Guido van Rossumfb67be22007-08-29 18:38:11 +0000380 if (! PyArg_ParseTuple(args, "ZZOOiiOZO:CreateProcess",
Tim Petersf3250b02004-10-12 21:38:22 +0000381 &application_name,
382 &command_line,
383 &process_attributes,
384 &thread_attributes,
385 &inherit_handles,
386 &creation_flags,
387 &env_mapping,
388 &current_directory,
389 &startup_info))
390 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000391
Tim Petersf3250b02004-10-12 21:38:22 +0000392 ZeroMemory(&si, sizeof(si));
393 si.cb = sizeof(si);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000394
Tim Petersf3250b02004-10-12 21:38:22 +0000395 /* note: we only support a small subset of all SI attributes */
396 si.dwFlags = getint(startup_info, "dwFlags");
Peter Astrandc1d65362004-11-07 14:30:34 +0000397 si.wShowWindow = getint(startup_info, "wShowWindow");
Tim Petersf3250b02004-10-12 21:38:22 +0000398 si.hStdInput = gethandle(startup_info, "hStdInput");
399 si.hStdOutput = gethandle(startup_info, "hStdOutput");
400 si.hStdError = gethandle(startup_info, "hStdError");
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000401
Fredrik Lundh3a49e922005-11-12 10:15:14 +0000402 if (PyErr_Occurred())
403 return NULL;
404
Tim Petersf3250b02004-10-12 21:38:22 +0000405 if (env_mapping == Py_None)
406 environment = NULL;
407 else {
408 environment = getenvironment(env_mapping);
409 if (! environment)
410 return NULL;
411 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000412
Tim Petersf3250b02004-10-12 21:38:22 +0000413 Py_BEGIN_ALLOW_THREADS
Guido van Rossumfb67be22007-08-29 18:38:11 +0000414 result = CreateProcessW(application_name,
Tim Petersf3250b02004-10-12 21:38:22 +0000415 command_line,
416 NULL,
417 NULL,
418 inherit_handles,
Guido van Rossumfb67be22007-08-29 18:38:11 +0000419 creation_flags | CREATE_UNICODE_ENVIRONMENT,
420 environment ? PyUnicode_AS_UNICODE(environment) : NULL,
Tim Petersf3250b02004-10-12 21:38:22 +0000421 current_directory,
422 &si,
423 &pi);
424 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000425
Tim Petersf3250b02004-10-12 21:38:22 +0000426 Py_XDECREF(environment);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000427
Tim Petersf3250b02004-10-12 21:38:22 +0000428 if (! result)
429 return PyErr_SetFromWindowsErr(GetLastError());
430
431 return Py_BuildValue("NNii",
432 sp_handle_new(pi.hProcess),
433 sp_handle_new(pi.hThread),
434 pi.dwProcessId,
435 pi.dwThreadId);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000436}
437
438static PyObject *
Fredrik Lundhe5152932005-12-18 21:06:46 +0000439sp_TerminateProcess(PyObject* self, PyObject* args)
440{
441 BOOL result;
442
443 long process;
444 int exit_code;
445 if (! PyArg_ParseTuple(args, "li:TerminateProcess", &process,
446 &exit_code))
447 return NULL;
448
449 result = TerminateProcess((HANDLE) process, exit_code);
450
451 if (! result)
452 return PyErr_SetFromWindowsErr(GetLastError());
453
454 Py_INCREF(Py_None);
455 return Py_None;
456}
457
458static PyObject *
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000459sp_GetExitCodeProcess(PyObject* self, PyObject* args)
460{
Tim Petersf3250b02004-10-12 21:38:22 +0000461 DWORD exit_code;
462 BOOL result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000463
Tim Petersf3250b02004-10-12 21:38:22 +0000464 long process;
465 if (! PyArg_ParseTuple(args, "l:GetExitCodeProcess", &process))
466 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000467
Tim Petersf3250b02004-10-12 21:38:22 +0000468 result = GetExitCodeProcess((HANDLE) process, &exit_code);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000469
Tim Petersf3250b02004-10-12 21:38:22 +0000470 if (! result)
471 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000472
Christian Heimes217cfd12007-12-02 14:31:20 +0000473 return PyLong_FromLong(exit_code);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000474}
475
476static PyObject *
477sp_WaitForSingleObject(PyObject* self, PyObject* args)
478{
Tim Petersf3250b02004-10-12 21:38:22 +0000479 DWORD result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000480
Tim Petersf3250b02004-10-12 21:38:22 +0000481 long handle;
482 int milliseconds;
483 if (! PyArg_ParseTuple(args, "li:WaitForSingleObject",
484 &handle,
485 &milliseconds))
486 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000487
Tim Petersf3250b02004-10-12 21:38:22 +0000488 Py_BEGIN_ALLOW_THREADS
489 result = WaitForSingleObject((HANDLE) handle, (DWORD) milliseconds);
490 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000491
Tim Petersf3250b02004-10-12 21:38:22 +0000492 if (result == WAIT_FAILED)
493 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000494
Christian Heimes217cfd12007-12-02 14:31:20 +0000495 return PyLong_FromLong((int) result);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000496}
497
498static PyObject *
499sp_GetVersion(PyObject* self, PyObject* args)
500{
Tim Petersf3250b02004-10-12 21:38:22 +0000501 if (! PyArg_ParseTuple(args, ":GetVersion"))
502 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000503
Christian Heimes217cfd12007-12-02 14:31:20 +0000504 return PyLong_FromLong((int) GetVersion());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000505}
506
507static PyObject *
508sp_GetModuleFileName(PyObject* self, PyObject* args)
509{
Tim Petersf3250b02004-10-12 21:38:22 +0000510 BOOL result;
511 long module;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000512 WCHAR filename[MAX_PATH];
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000513
Tim Petersf3250b02004-10-12 21:38:22 +0000514 if (! PyArg_ParseTuple(args, "l:GetModuleFileName", &module))
515 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000516
Guido van Rossumfb67be22007-08-29 18:38:11 +0000517 result = GetModuleFileNameW((HMODULE)module, filename, MAX_PATH);
Tim Petersf3250b02004-10-12 21:38:22 +0000518 filename[MAX_PATH-1] = '\0';
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000519
Tim Petersf3250b02004-10-12 21:38:22 +0000520 if (! result)
521 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000522
Guido van Rossumfb67be22007-08-29 18:38:11 +0000523 return PyUnicode_FromUnicode(filename, Py_UNICODE_strlen(filename));
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000524}
525
526static PyMethodDef sp_functions[] = {
Tim Petersf3250b02004-10-12 21:38:22 +0000527 {"GetStdHandle", sp_GetStdHandle, METH_VARARGS},
528 {"GetCurrentProcess", sp_GetCurrentProcess, METH_VARARGS},
529 {"DuplicateHandle", sp_DuplicateHandle, METH_VARARGS},
530 {"CreatePipe", sp_CreatePipe, METH_VARARGS},
531 {"CreateProcess", sp_CreateProcess, METH_VARARGS},
Fredrik Lundhe5152932005-12-18 21:06:46 +0000532 {"TerminateProcess", sp_TerminateProcess, METH_VARARGS},
Tim Petersf3250b02004-10-12 21:38:22 +0000533 {"GetExitCodeProcess", sp_GetExitCodeProcess, METH_VARARGS},
534 {"WaitForSingleObject", sp_WaitForSingleObject, METH_VARARGS},
535 {"GetVersion", sp_GetVersion, METH_VARARGS},
536 {"GetModuleFileName", sp_GetModuleFileName, METH_VARARGS},
537 {NULL, NULL}
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000538};
539
540/* -------------------------------------------------------------------- */
541
542static void
543defint(PyObject* d, const char* name, int value)
544{
Christian Heimes217cfd12007-12-02 14:31:20 +0000545 PyObject* v = PyLong_FromLong((long) value);
Tim Petersf3250b02004-10-12 21:38:22 +0000546 if (v) {
547 PyDict_SetItemString(d, (char*) name, v);
548 Py_DECREF(v);
549 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000550}
551
Martin v. Löwis1a214512008-06-11 05:26:20 +0000552static struct PyModuleDef _subprocessmodule = {
553 PyModuleDef_HEAD_INIT,
554 "_subprocess",
555 NULL,
556 -1,
557 sp_functions,
558 NULL,
559 NULL,
560 NULL,
561 NULL
562};
563
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000564PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000565PyInit__subprocess()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000566{
Tim Petersf3250b02004-10-12 21:38:22 +0000567 PyObject *d;
568 PyObject *m;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000569
Tim Petersf3250b02004-10-12 21:38:22 +0000570 /* patch up object descriptors */
Tim Petersf3250b02004-10-12 21:38:22 +0000571 sp_handle_as_number.nb_int = (unaryfunc) sp_handle_as_int;
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000572 if (PyType_Ready(&sp_handle_type) < 0)
573 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000574
Martin v. Löwis1a214512008-06-11 05:26:20 +0000575 m = PyModule_Create(&_subprocessmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000576 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000577 return NULL;
Tim Petersf3250b02004-10-12 21:38:22 +0000578 d = PyModule_GetDict(m);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000579
Tim Petersf3250b02004-10-12 21:38:22 +0000580 /* constants */
581 defint(d, "STD_INPUT_HANDLE", STD_INPUT_HANDLE);
582 defint(d, "STD_OUTPUT_HANDLE", STD_OUTPUT_HANDLE);
583 defint(d, "STD_ERROR_HANDLE", STD_ERROR_HANDLE);
584 defint(d, "DUPLICATE_SAME_ACCESS", DUPLICATE_SAME_ACCESS);
585 defint(d, "STARTF_USESTDHANDLES", STARTF_USESTDHANDLES);
Peter Astrandc1d65362004-11-07 14:30:34 +0000586 defint(d, "STARTF_USESHOWWINDOW", STARTF_USESHOWWINDOW);
587 defint(d, "SW_HIDE", SW_HIDE);
Tim Petersf3250b02004-10-12 21:38:22 +0000588 defint(d, "INFINITE", INFINITE);
589 defint(d, "WAIT_OBJECT_0", WAIT_OBJECT_0);
590 defint(d, "CREATE_NEW_CONSOLE", CREATE_NEW_CONSOLE);
Martin v. Löwis1a214512008-06-11 05:26:20 +0000591 return m;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000592}