blob: c256ca35d89d712f9cb374f4802e698bb69a0167 [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_getattr(sp_handle_object* self, char* name)
115{
Tim Petersf3250b02004-10-12 21:38:22 +0000116 return Py_FindMethod(sp_handle_methods, (PyObject*) self, name);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000117}
118
119static PyObject*
120sp_handle_as_int(sp_handle_object* self)
121{
Christian Heimes217cfd12007-12-02 14:31:20 +0000122 return PyLong_FromLong((long) self->handle);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000123}
124
125static PyNumberMethods sp_handle_as_number;
126
Neal Norwitz227b5332006-03-22 09:28:35 +0000127static PyTypeObject sp_handle_type = {
Martin v. Löwis95c95ce2007-07-22 14:41:55 +0000128 PyVarObject_HEAD_INIT(NULL, 0)
Tim Petersf3250b02004-10-12 21:38:22 +0000129 "_subprocess_handle", sizeof(sp_handle_object), 0,
130 (destructor) sp_handle_dealloc, /*tp_dealloc*/
131 0, /*tp_print*/
132 (getattrfunc) sp_handle_getattr,/*tp_getattr*/
133 0, /*tp_setattr*/
134 0, /*tp_compare*/
135 0, /*tp_repr*/
136 &sp_handle_as_number, /*tp_as_number */
137 0, /*tp_as_sequence */
138 0, /*tp_as_mapping */
139 0 /*tp_hash*/
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000140};
141
142/* -------------------------------------------------------------------- */
143/* windows API functions */
144
145static PyObject *
146sp_GetStdHandle(PyObject* self, PyObject* args)
147{
Tim Petersf3250b02004-10-12 21:38:22 +0000148 HANDLE handle;
149 int std_handle;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000150
Tim Petersf3250b02004-10-12 21:38:22 +0000151 if (! PyArg_ParseTuple(args, "i:GetStdHandle", &std_handle))
152 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000153
Tim Petersf3250b02004-10-12 21:38:22 +0000154 Py_BEGIN_ALLOW_THREADS
155 handle = GetStdHandle((DWORD) std_handle);
156 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000157
Tim Petersf3250b02004-10-12 21:38:22 +0000158 if (handle == INVALID_HANDLE_VALUE)
159 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000160
Tim Petersf3250b02004-10-12 21:38:22 +0000161 if (! handle) {
162 Py_INCREF(Py_None);
163 return Py_None;
164 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000165
Tim Petersf3250b02004-10-12 21:38:22 +0000166 /* note: returns integer, not handle object */
Christian Heimes217cfd12007-12-02 14:31:20 +0000167 return PyLong_FromLong((long) handle);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000168}
169
170static PyObject *
171sp_GetCurrentProcess(PyObject* self, PyObject* args)
172{
Tim Petersf3250b02004-10-12 21:38:22 +0000173 if (! PyArg_ParseTuple(args, ":GetCurrentProcess"))
174 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000175
Tim Petersf3250b02004-10-12 21:38:22 +0000176 return sp_handle_new(GetCurrentProcess());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000177}
178
179static PyObject *
180sp_DuplicateHandle(PyObject* self, PyObject* args)
181{
Tim Petersf3250b02004-10-12 21:38:22 +0000182 HANDLE target_handle;
183 BOOL result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000184
Tim Petersf3250b02004-10-12 21:38:22 +0000185 long source_process_handle;
186 long source_handle;
187 long target_process_handle;
188 int desired_access;
189 int inherit_handle;
190 int options = 0;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000191
Tim Petersf3250b02004-10-12 21:38:22 +0000192 if (! PyArg_ParseTuple(args, "lllii|i:DuplicateHandle",
193 &source_process_handle,
194 &source_handle,
195 &target_process_handle,
196 &desired_access,
197 &inherit_handle,
198 &options))
199 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000200
Tim Petersf3250b02004-10-12 21:38:22 +0000201 Py_BEGIN_ALLOW_THREADS
202 result = DuplicateHandle(
203 (HANDLE) source_process_handle,
204 (HANDLE) source_handle,
205 (HANDLE) target_process_handle,
206 &target_handle,
207 desired_access,
208 inherit_handle,
209 options
210 );
211 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000212
Tim Petersf3250b02004-10-12 21:38:22 +0000213 if (! result)
214 return PyErr_SetFromWindowsErr(GetLastError());
215
216 return sp_handle_new(target_handle);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000217}
218
219static PyObject *
220sp_CreatePipe(PyObject* self, PyObject* args)
221{
Tim Petersf3250b02004-10-12 21:38:22 +0000222 HANDLE read_pipe;
223 HANDLE write_pipe;
224 BOOL result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000225
Tim Petersf3250b02004-10-12 21:38:22 +0000226 PyObject* pipe_attributes; /* ignored */
227 int size;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000228
Tim Petersf3250b02004-10-12 21:38:22 +0000229 if (! PyArg_ParseTuple(args, "Oi:CreatePipe", &pipe_attributes, &size))
230 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000231
Tim Petersf3250b02004-10-12 21:38:22 +0000232 Py_BEGIN_ALLOW_THREADS
233 result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
234 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000235
Tim Petersf3250b02004-10-12 21:38:22 +0000236 if (! result)
237 return PyErr_SetFromWindowsErr(GetLastError());
238
239 return Py_BuildValue(
240 "NN", sp_handle_new(read_pipe), sp_handle_new(write_pipe));
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000241}
242
243/* helpers for createprocess */
244
245static int
246getint(PyObject* obj, char* name)
247{
Tim Petersf3250b02004-10-12 21:38:22 +0000248 PyObject* value;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000249 int ret;
Tim Petersf3250b02004-10-12 21:38:22 +0000250
251 value = PyObject_GetAttrString(obj, name);
252 if (! value) {
253 PyErr_Clear(); /* FIXME: propagate error? */
254 return 0;
255 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000256 ret = (int) PyLong_AsLong(value);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000257 Py_DECREF(value);
258 return ret;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000259}
Tim Petersf3250b02004-10-12 21:38:22 +0000260
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000261static HANDLE
262gethandle(PyObject* obj, char* name)
263{
Tim Petersf3250b02004-10-12 21:38:22 +0000264 sp_handle_object* value;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000265 HANDLE ret;
Tim Petersf3250b02004-10-12 21:38:22 +0000266
267 value = (sp_handle_object*) PyObject_GetAttrString(obj, name);
268 if (! value) {
269 PyErr_Clear(); /* FIXME: propagate error? */
270 return NULL;
271 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000272 if (Py_TYPE(value) != &sp_handle_type)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000273 ret = NULL;
274 else
275 ret = value->handle;
276 Py_DECREF(value);
277 return ret;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000278}
279
280static PyObject*
281getenvironment(PyObject* environment)
282{
Tim Petersf3250b02004-10-12 21:38:22 +0000283 int i, envsize;
284 PyObject* out = NULL;
285 PyObject* keys;
286 PyObject* values;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000287 Py_UNICODE* p;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000288
Tim Petersf3250b02004-10-12 21:38:22 +0000289 /* convert environment dictionary to windows enviroment string */
290 if (! PyMapping_Check(environment)) {
291 PyErr_SetString(
292 PyExc_TypeError, "environment must be dictionary or None");
293 return NULL;
294 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000295
Tim Petersf3250b02004-10-12 21:38:22 +0000296 envsize = PyMapping_Length(environment);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000297
Tim Petersf3250b02004-10-12 21:38:22 +0000298 keys = PyMapping_Keys(environment);
299 values = PyMapping_Values(environment);
300 if (!keys || !values)
301 goto error;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000302
Guido van Rossumfb67be22007-08-29 18:38:11 +0000303 out = PyUnicode_FromUnicode(NULL, 2048);
Tim Petersf3250b02004-10-12 21:38:22 +0000304 if (! out)
305 goto error;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000306
Guido van Rossumfb67be22007-08-29 18:38:11 +0000307 p = PyUnicode_AS_UNICODE(out);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000308
Tim Petersf3250b02004-10-12 21:38:22 +0000309 for (i = 0; i < envsize; i++) {
310 int ksize, vsize, totalsize;
311 PyObject* key = PyList_GET_ITEM(keys, i);
312 PyObject* value = PyList_GET_ITEM(values, i);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000313
Guido van Rossumfb67be22007-08-29 18:38:11 +0000314 if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) {
Tim Petersf3250b02004-10-12 21:38:22 +0000315 PyErr_SetString(PyExc_TypeError,
316 "environment can only contain strings");
317 goto error;
318 }
Guido van Rossumfb67be22007-08-29 18:38:11 +0000319 ksize = PyUnicode_GET_SIZE(key);
320 vsize = PyUnicode_GET_SIZE(value);
321 totalsize = (p - PyUnicode_AS_UNICODE(out)) + ksize + 1 +
Tim Petersf3250b02004-10-12 21:38:22 +0000322 vsize + 1 + 1;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000323 if (totalsize > PyUnicode_GET_SIZE(out)) {
324 int offset = p - PyUnicode_AS_UNICODE(out);
325 PyUnicode_Resize(&out, totalsize + 1024);
326 p = PyUnicode_AS_UNICODE(out) + offset;
Tim Petersf3250b02004-10-12 21:38:22 +0000327 }
Guido van Rossumfb67be22007-08-29 18:38:11 +0000328 Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(key), ksize);
Tim Petersf3250b02004-10-12 21:38:22 +0000329 p += ksize;
330 *p++ = '=';
Guido van Rossumfb67be22007-08-29 18:38:11 +0000331 Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(value), vsize);
Tim Petersf3250b02004-10-12 21:38:22 +0000332 p += vsize;
333 *p++ = '\0';
334 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000335
Tim Petersf3250b02004-10-12 21:38:22 +0000336 /* add trailing null byte */
337 *p++ = '\0';
Guido van Rossumfb67be22007-08-29 18:38:11 +0000338 PyUnicode_Resize(&out, p - PyUnicode_AS_UNICODE(out));
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000339
Tim Petersf3250b02004-10-12 21:38:22 +0000340 /* PyObject_Print(out, stdout, 0); */
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000341
Fredrik Lundhbb4692b2005-11-12 10:15:03 +0000342 Py_XDECREF(keys);
343 Py_XDECREF(values);
344
Tim Petersf3250b02004-10-12 21:38:22 +0000345 return out;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000346
Tim Petersf3250b02004-10-12 21:38:22 +0000347 error:
348 Py_XDECREF(out);
349 Py_XDECREF(keys);
350 Py_XDECREF(values);
351 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000352}
353
354static PyObject *
355sp_CreateProcess(PyObject* self, PyObject* args)
356{
Tim Petersf3250b02004-10-12 21:38:22 +0000357 BOOL result;
358 PROCESS_INFORMATION pi;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000359 STARTUPINFOW si;
Tim Petersf3250b02004-10-12 21:38:22 +0000360 PyObject* environment;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000361
Guido van Rossumfb67be22007-08-29 18:38:11 +0000362 Py_UNICODE* application_name;
363 Py_UNICODE* command_line;
Tim Petersf3250b02004-10-12 21:38:22 +0000364 PyObject* process_attributes; /* ignored */
365 PyObject* thread_attributes; /* ignored */
366 int inherit_handles;
367 int creation_flags;
368 PyObject* env_mapping;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000369 Py_UNICODE* current_directory;
Tim Petersf3250b02004-10-12 21:38:22 +0000370 PyObject* startup_info;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000371
Guido van Rossumfb67be22007-08-29 18:38:11 +0000372 if (! PyArg_ParseTuple(args, "ZZOOiiOZO:CreateProcess",
Tim Petersf3250b02004-10-12 21:38:22 +0000373 &application_name,
374 &command_line,
375 &process_attributes,
376 &thread_attributes,
377 &inherit_handles,
378 &creation_flags,
379 &env_mapping,
380 &current_directory,
381 &startup_info))
382 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000383
Tim Petersf3250b02004-10-12 21:38:22 +0000384 ZeroMemory(&si, sizeof(si));
385 si.cb = sizeof(si);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000386
Tim Petersf3250b02004-10-12 21:38:22 +0000387 /* note: we only support a small subset of all SI attributes */
388 si.dwFlags = getint(startup_info, "dwFlags");
Peter Astrandc1d65362004-11-07 14:30:34 +0000389 si.wShowWindow = getint(startup_info, "wShowWindow");
Tim Petersf3250b02004-10-12 21:38:22 +0000390 si.hStdInput = gethandle(startup_info, "hStdInput");
391 si.hStdOutput = gethandle(startup_info, "hStdOutput");
392 si.hStdError = gethandle(startup_info, "hStdError");
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000393
Fredrik Lundh3a49e922005-11-12 10:15:14 +0000394 if (PyErr_Occurred())
395 return NULL;
396
Tim Petersf3250b02004-10-12 21:38:22 +0000397 if (env_mapping == Py_None)
398 environment = NULL;
399 else {
400 environment = getenvironment(env_mapping);
401 if (! environment)
402 return NULL;
403 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000404
Tim Petersf3250b02004-10-12 21:38:22 +0000405 Py_BEGIN_ALLOW_THREADS
Guido van Rossumfb67be22007-08-29 18:38:11 +0000406 result = CreateProcessW(application_name,
Tim Petersf3250b02004-10-12 21:38:22 +0000407 command_line,
408 NULL,
409 NULL,
410 inherit_handles,
Guido van Rossumfb67be22007-08-29 18:38:11 +0000411 creation_flags | CREATE_UNICODE_ENVIRONMENT,
412 environment ? PyUnicode_AS_UNICODE(environment) : NULL,
Tim Petersf3250b02004-10-12 21:38:22 +0000413 current_directory,
414 &si,
415 &pi);
416 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000417
Tim Petersf3250b02004-10-12 21:38:22 +0000418 Py_XDECREF(environment);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000419
Tim Petersf3250b02004-10-12 21:38:22 +0000420 if (! result)
421 return PyErr_SetFromWindowsErr(GetLastError());
422
423 return Py_BuildValue("NNii",
424 sp_handle_new(pi.hProcess),
425 sp_handle_new(pi.hThread),
426 pi.dwProcessId,
427 pi.dwThreadId);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000428}
429
430static PyObject *
Fredrik Lundhe5152932005-12-18 21:06:46 +0000431sp_TerminateProcess(PyObject* self, PyObject* args)
432{
433 BOOL result;
434
435 long process;
436 int exit_code;
437 if (! PyArg_ParseTuple(args, "li:TerminateProcess", &process,
438 &exit_code))
439 return NULL;
440
441 result = TerminateProcess((HANDLE) process, exit_code);
442
443 if (! result)
444 return PyErr_SetFromWindowsErr(GetLastError());
445
446 Py_INCREF(Py_None);
447 return Py_None;
448}
449
450static PyObject *
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000451sp_GetExitCodeProcess(PyObject* self, PyObject* args)
452{
Tim Petersf3250b02004-10-12 21:38:22 +0000453 DWORD exit_code;
454 BOOL result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000455
Tim Petersf3250b02004-10-12 21:38:22 +0000456 long process;
457 if (! PyArg_ParseTuple(args, "l:GetExitCodeProcess", &process))
458 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000459
Tim Petersf3250b02004-10-12 21:38:22 +0000460 result = GetExitCodeProcess((HANDLE) process, &exit_code);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000461
Tim Petersf3250b02004-10-12 21:38:22 +0000462 if (! result)
463 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000464
Christian Heimes217cfd12007-12-02 14:31:20 +0000465 return PyLong_FromLong(exit_code);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000466}
467
468static PyObject *
469sp_WaitForSingleObject(PyObject* self, PyObject* args)
470{
Tim Petersf3250b02004-10-12 21:38:22 +0000471 DWORD result;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000472
Tim Petersf3250b02004-10-12 21:38:22 +0000473 long handle;
474 int milliseconds;
475 if (! PyArg_ParseTuple(args, "li:WaitForSingleObject",
476 &handle,
477 &milliseconds))
478 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000479
Tim Petersf3250b02004-10-12 21:38:22 +0000480 Py_BEGIN_ALLOW_THREADS
481 result = WaitForSingleObject((HANDLE) handle, (DWORD) milliseconds);
482 Py_END_ALLOW_THREADS
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000483
Tim Petersf3250b02004-10-12 21:38:22 +0000484 if (result == WAIT_FAILED)
485 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000486
Christian Heimes217cfd12007-12-02 14:31:20 +0000487 return PyLong_FromLong((int) result);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000488}
489
490static PyObject *
491sp_GetVersion(PyObject* self, PyObject* args)
492{
Tim Petersf3250b02004-10-12 21:38:22 +0000493 if (! PyArg_ParseTuple(args, ":GetVersion"))
494 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000495
Christian Heimes217cfd12007-12-02 14:31:20 +0000496 return PyLong_FromLong((int) GetVersion());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000497}
498
499static PyObject *
500sp_GetModuleFileName(PyObject* self, PyObject* args)
501{
Tim Petersf3250b02004-10-12 21:38:22 +0000502 BOOL result;
503 long module;
Guido van Rossumfb67be22007-08-29 18:38:11 +0000504 WCHAR filename[MAX_PATH];
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000505
Tim Petersf3250b02004-10-12 21:38:22 +0000506 if (! PyArg_ParseTuple(args, "l:GetModuleFileName", &module))
507 return NULL;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000508
Guido van Rossumfb67be22007-08-29 18:38:11 +0000509 result = GetModuleFileNameW((HMODULE)module, filename, MAX_PATH);
Tim Petersf3250b02004-10-12 21:38:22 +0000510 filename[MAX_PATH-1] = '\0';
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000511
Tim Petersf3250b02004-10-12 21:38:22 +0000512 if (! result)
513 return PyErr_SetFromWindowsErr(GetLastError());
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000514
Guido van Rossumfb67be22007-08-29 18:38:11 +0000515 return PyUnicode_FromUnicode(filename, Py_UNICODE_strlen(filename));
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000516}
517
518static PyMethodDef sp_functions[] = {
Tim Petersf3250b02004-10-12 21:38:22 +0000519 {"GetStdHandle", sp_GetStdHandle, METH_VARARGS},
520 {"GetCurrentProcess", sp_GetCurrentProcess, METH_VARARGS},
521 {"DuplicateHandle", sp_DuplicateHandle, METH_VARARGS},
522 {"CreatePipe", sp_CreatePipe, METH_VARARGS},
523 {"CreateProcess", sp_CreateProcess, METH_VARARGS},
Fredrik Lundhe5152932005-12-18 21:06:46 +0000524 {"TerminateProcess", sp_TerminateProcess, METH_VARARGS},
Tim Petersf3250b02004-10-12 21:38:22 +0000525 {"GetExitCodeProcess", sp_GetExitCodeProcess, METH_VARARGS},
526 {"WaitForSingleObject", sp_WaitForSingleObject, METH_VARARGS},
527 {"GetVersion", sp_GetVersion, METH_VARARGS},
528 {"GetModuleFileName", sp_GetModuleFileName, METH_VARARGS},
529 {NULL, NULL}
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000530};
531
532/* -------------------------------------------------------------------- */
533
534static void
535defint(PyObject* d, const char* name, int value)
536{
Christian Heimes217cfd12007-12-02 14:31:20 +0000537 PyObject* v = PyLong_FromLong((long) value);
Tim Petersf3250b02004-10-12 21:38:22 +0000538 if (v) {
539 PyDict_SetItemString(d, (char*) name, v);
540 Py_DECREF(v);
541 }
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000542}
543
Martin v. Löwis1a214512008-06-11 05:26:20 +0000544static struct PyModuleDef _subprocessmodule = {
545 PyModuleDef_HEAD_INIT,
546 "_subprocess",
547 NULL,
548 -1,
549 sp_functions,
550 NULL,
551 NULL,
552 NULL,
553 NULL
554};
555
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000556PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000557PyInit__subprocess()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000558{
Tim Petersf3250b02004-10-12 21:38:22 +0000559 PyObject *d;
560 PyObject *m;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000561
Tim Petersf3250b02004-10-12 21:38:22 +0000562 /* patch up object descriptors */
Christian Heimes90aa7642007-12-19 02:45:37 +0000563 Py_TYPE(&sp_handle_type) = &PyType_Type;
Tim Petersf3250b02004-10-12 21:38:22 +0000564 sp_handle_as_number.nb_int = (unaryfunc) sp_handle_as_int;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000565
Martin v. Löwis1a214512008-06-11 05:26:20 +0000566 m = PyModule_Create(&_subprocessmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000567 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000568 return NULL;
Tim Petersf3250b02004-10-12 21:38:22 +0000569 d = PyModule_GetDict(m);
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000570
Tim Petersf3250b02004-10-12 21:38:22 +0000571 /* constants */
572 defint(d, "STD_INPUT_HANDLE", STD_INPUT_HANDLE);
573 defint(d, "STD_OUTPUT_HANDLE", STD_OUTPUT_HANDLE);
574 defint(d, "STD_ERROR_HANDLE", STD_ERROR_HANDLE);
575 defint(d, "DUPLICATE_SAME_ACCESS", DUPLICATE_SAME_ACCESS);
576 defint(d, "STARTF_USESTDHANDLES", STARTF_USESTDHANDLES);
Peter Astrandc1d65362004-11-07 14:30:34 +0000577 defint(d, "STARTF_USESHOWWINDOW", STARTF_USESHOWWINDOW);
578 defint(d, "SW_HIDE", SW_HIDE);
Tim Petersf3250b02004-10-12 21:38:22 +0000579 defint(d, "INFINITE", INFINITE);
580 defint(d, "WAIT_OBJECT_0", WAIT_OBJECT_0);
581 defint(d, "CREATE_NEW_CONSOLE", CREATE_NEW_CONSOLE);
Martin v. Löwis1a214512008-06-11 05:26:20 +0000582 return m;
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000583}