~ubuntu-branches/ubuntu/saucy/python2.7/saucy-proposed

1 by Matthias Klose
Import upstream version 2.7~a2
1
/*
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
6
 * platforms might be added here as well.
7
 *
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>
11
 *
12
 * 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:
15
 *
16
 * 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.
24
 *
25
 * 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.
32
 *
33
 */
34
35
/* Licensed to PSF under a Contributor Agreement. */
36
/* See http://www.python.org/2.4/license for licensing details. */
37
38
/* TODO: handle unicode command lines? */
39
/* TODO: handle unicode environment? */
40
41
#include "Python.h"
42
43
#define WINDOWS_LEAN_AND_MEAN
44
#include "windows.h"
45
46
/* -------------------------------------------------------------------- */
47
/* handle wrapper.  note that this library uses integers when passing
48
   handles to a function, and handle wrappers when returning handles.
49
   the wrapper is used to provide Detach and Close methods */
50
51
typedef struct {
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
52
    PyObject_HEAD
53
    HANDLE handle;
1 by Matthias Klose
Import upstream version 2.7~a2
54
} sp_handle_object;
55
56
staticforward PyTypeObject sp_handle_type;
57
58
static PyObject*
59
sp_handle_new(HANDLE handle)
60
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
61
    sp_handle_object* self;
62
63
    self = PyObject_NEW(sp_handle_object, &sp_handle_type);
64
    if (self == NULL)
65
        return NULL;
66
67
    self->handle = handle;
68
69
    return (PyObject*) self;
1 by Matthias Klose
Import upstream version 2.7~a2
70
}
71
72
#if defined(MS_WIN32) && !defined(MS_WIN64)
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
73
#define HANDLE_TO_PYNUM(handle) PyInt_FromLong((long) handle)
74
#define PY_HANDLE_PARAM "l"
1 by Matthias Klose
Import upstream version 2.7~a2
75
#else
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
76
#define HANDLE_TO_PYNUM(handle) PyLong_FromLongLong((long long) handle)
77
#define PY_HANDLE_PARAM "L"
1 by Matthias Klose
Import upstream version 2.7~a2
78
#endif
79
80
static PyObject*
81
sp_handle_detach(sp_handle_object* self, PyObject* args)
82
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
83
    HANDLE handle;
84
85
    if (! PyArg_ParseTuple(args, ":Detach"))
86
        return NULL;
87
88
    handle = self->handle;
89
90
    self->handle = INVALID_HANDLE_VALUE;
91
92
    /* note: return the current handle, as an integer */
93
    return HANDLE_TO_PYNUM(handle);
1 by Matthias Klose
Import upstream version 2.7~a2
94
}
95
96
static PyObject*
97
sp_handle_close(sp_handle_object* self, PyObject* args)
98
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
99
    if (! PyArg_ParseTuple(args, ":Close"))
100
        return NULL;
1 by Matthias Klose
Import upstream version 2.7~a2
101
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
102
    if (self->handle != INVALID_HANDLE_VALUE) {
103
        CloseHandle(self->handle);
104
        self->handle = INVALID_HANDLE_VALUE;
105
    }
106
    Py_INCREF(Py_None);
107
    return Py_None;
1 by Matthias Klose
Import upstream version 2.7~a2
108
}
109
110
static void
111
sp_handle_dealloc(sp_handle_object* self)
112
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
113
    if (self->handle != INVALID_HANDLE_VALUE)
114
        CloseHandle(self->handle);
115
    PyObject_FREE(self);
1 by Matthias Klose
Import upstream version 2.7~a2
116
}
117
118
static PyMethodDef sp_handle_methods[] = {
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
119
    {"Detach", (PyCFunction) sp_handle_detach, METH_VARARGS},
120
    {"Close",  (PyCFunction) sp_handle_close,  METH_VARARGS},
121
    {NULL, NULL}
1 by Matthias Klose
Import upstream version 2.7~a2
122
};
123
124
static PyObject*
125
sp_handle_getattr(sp_handle_object* self, char* name)
126
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
127
    return Py_FindMethod(sp_handle_methods, (PyObject*) self, name);
1 by Matthias Klose
Import upstream version 2.7~a2
128
}
129
130
static PyObject*
131
sp_handle_as_int(sp_handle_object* self)
132
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
133
    return HANDLE_TO_PYNUM(self->handle);
1 by Matthias Klose
Import upstream version 2.7~a2
134
}
135
136
static PyNumberMethods sp_handle_as_number;
137
138
statichere PyTypeObject sp_handle_type = {
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
139
    PyObject_HEAD_INIT(NULL)
140
    0,                                  /*ob_size*/
141
    "_subprocess_handle", sizeof(sp_handle_object), 0,
142
    (destructor) sp_handle_dealloc, /*tp_dealloc*/
143
    0, /*tp_print*/
144
    (getattrfunc) sp_handle_getattr,/*tp_getattr*/
145
    0,                                  /*tp_setattr*/
146
    0,                                  /*tp_compare*/
147
    0,                                  /*tp_repr*/
148
    &sp_handle_as_number,               /*tp_as_number */
149
    0,                                  /*tp_as_sequence */
150
    0,                                  /*tp_as_mapping */
151
    0                                   /*tp_hash*/
1 by Matthias Klose
Import upstream version 2.7~a2
152
};
153
154
/* -------------------------------------------------------------------- */
155
/* windows API functions */
156
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
157
PyDoc_STRVAR(GetStdHandle_doc,
158
"GetStdHandle(handle) -> integer\n\
159
\n\
160
Return a handle to the specified standard device\n\
161
(STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE).\n\
162
The integer associated with the handle object is returned.");
163
1 by Matthias Klose
Import upstream version 2.7~a2
164
static PyObject *
165
sp_GetStdHandle(PyObject* self, PyObject* args)
166
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
167
    HANDLE handle;
168
    int std_handle;
169
170
    if (! PyArg_ParseTuple(args, "i:GetStdHandle", &std_handle))
171
        return NULL;
172
173
    Py_BEGIN_ALLOW_THREADS
174
    handle = GetStdHandle((DWORD) std_handle);
175
    Py_END_ALLOW_THREADS
176
177
    if (handle == INVALID_HANDLE_VALUE)
178
        return PyErr_SetFromWindowsErr(GetLastError());
179
180
    if (! handle) {
181
        Py_INCREF(Py_None);
182
        return Py_None;
183
    }
184
185
    /* note: returns integer, not handle object */
186
    return HANDLE_TO_PYNUM(handle);
1 by Matthias Klose
Import upstream version 2.7~a2
187
}
188
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
189
PyDoc_STRVAR(GetCurrentProcess_doc,
190
"GetCurrentProcess() -> handle\n\
191
\n\
192
Return a handle object for the current process.");
193
1 by Matthias Klose
Import upstream version 2.7~a2
194
static PyObject *
195
sp_GetCurrentProcess(PyObject* self, PyObject* args)
196
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
197
    if (! PyArg_ParseTuple(args, ":GetCurrentProcess"))
198
        return NULL;
1 by Matthias Klose
Import upstream version 2.7~a2
199
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
200
    return sp_handle_new(GetCurrentProcess());
1 by Matthias Klose
Import upstream version 2.7~a2
201
}
202
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
203
PyDoc_STRVAR(DuplicateHandle_doc,
204
"DuplicateHandle(source_proc_handle, source_handle,\n\
205
                 target_proc_handle, target_handle, access,\n\
206
                 inherit[, options]) -> handle\n\
207
\n\
208
Return a duplicate handle object.\n\
209
\n\
210
The duplicate handle refers to the same object as the original\n\
211
handle. Therefore, any changes to the object are reflected\n\
212
through both handles.");
213
1 by Matthias Klose
Import upstream version 2.7~a2
214
static PyObject *
215
sp_DuplicateHandle(PyObject* self, PyObject* args)
216
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
217
    HANDLE target_handle;
218
    BOOL result;
219
220
    HANDLE source_process_handle;
221
    HANDLE source_handle;
222
    HANDLE target_process_handle;
223
    int desired_access;
224
    int inherit_handle;
225
    int options = 0;
226
227
    if (! PyArg_ParseTuple(args,
228
                           PY_HANDLE_PARAM PY_HANDLE_PARAM PY_HANDLE_PARAM
229
                           "ii|i:DuplicateHandle",
230
                           &source_process_handle,
231
                           &source_handle,
232
                           &target_process_handle,
233
                           &desired_access,
234
                           &inherit_handle,
235
                           &options))
236
        return NULL;
237
238
    Py_BEGIN_ALLOW_THREADS
239
    result = DuplicateHandle(
240
        source_process_handle,
241
        source_handle,
242
        target_process_handle,
243
        &target_handle,
244
        desired_access,
245
        inherit_handle,
246
        options
247
    );
248
    Py_END_ALLOW_THREADS
249
250
    if (! result)
251
        return PyErr_SetFromWindowsErr(GetLastError());
252
253
    return sp_handle_new(target_handle);
1 by Matthias Klose
Import upstream version 2.7~a2
254
}
255
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
256
PyDoc_STRVAR(CreatePipe_doc,
257
"CreatePipe(pipe_attrs, size) -> (read_handle, write_handle)\n\
258
\n\
259
Create an anonymous pipe, and return handles to the read and\n\
260
write ends of the pipe.\n\
261
\n\
262
pipe_attrs is ignored internally and can be None.");
263
1 by Matthias Klose
Import upstream version 2.7~a2
264
static PyObject *
265
sp_CreatePipe(PyObject* self, PyObject* args)
266
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
267
    HANDLE read_pipe;
268
    HANDLE write_pipe;
269
    BOOL result;
270
271
    PyObject* pipe_attributes; /* ignored */
272
    int size;
273
274
    if (! PyArg_ParseTuple(args, "Oi:CreatePipe", &pipe_attributes, &size))
275
        return NULL;
276
277
    Py_BEGIN_ALLOW_THREADS
278
    result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
279
    Py_END_ALLOW_THREADS
280
281
    if (! result)
282
        return PyErr_SetFromWindowsErr(GetLastError());
283
284
    return Py_BuildValue(
285
        "NN", sp_handle_new(read_pipe), sp_handle_new(write_pipe));
1 by Matthias Klose
Import upstream version 2.7~a2
286
}
287
288
/* helpers for createprocess */
289
290
static int
291
getint(PyObject* obj, char* name)
292
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
293
    PyObject* value;
294
    int ret;
1 by Matthias Klose
Import upstream version 2.7~a2
295
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
296
    value = PyObject_GetAttrString(obj, name);
297
    if (! value) {
298
        PyErr_Clear(); /* FIXME: propagate error? */
299
        return 0;
300
    }
301
    ret = (int) PyInt_AsLong(value);
302
    Py_DECREF(value);
303
    return ret;
1 by Matthias Klose
Import upstream version 2.7~a2
304
}
305
306
static HANDLE
307
gethandle(PyObject* obj, char* name)
308
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
309
    sp_handle_object* value;
310
    HANDLE ret;
1 by Matthias Klose
Import upstream version 2.7~a2
311
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
312
    value = (sp_handle_object*) PyObject_GetAttrString(obj, name);
313
    if (! value) {
314
        PyErr_Clear(); /* FIXME: propagate error? */
315
        return NULL;
316
    }
317
    if (value->ob_type != &sp_handle_type)
318
        ret = NULL;
319
    else
320
        ret = value->handle;
321
    Py_DECREF(value);
322
    return ret;
1 by Matthias Klose
Import upstream version 2.7~a2
323
}
324
325
static PyObject*
326
getenvironment(PyObject* environment)
327
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
328
    int i, envsize;
329
    PyObject* out = NULL;
330
    PyObject* keys;
331
    PyObject* values;
332
    char* p;
333
334
    /* convert environment dictionary to windows enviroment string */
335
    if (! PyMapping_Check(environment)) {
336
        PyErr_SetString(
337
            PyExc_TypeError, "environment must be dictionary or None");
338
        return NULL;
339
    }
340
341
    envsize = PyMapping_Length(environment);
342
343
    keys = PyMapping_Keys(environment);
344
    values = PyMapping_Values(environment);
345
    if (!keys || !values)
346
        goto error;
347
348
    out = PyString_FromStringAndSize(NULL, 2048);
349
    if (! out)
350
        goto error;
351
352
    p = PyString_AS_STRING(out);
353
354
    for (i = 0; i < envsize; i++) {
355
        int ksize, vsize, totalsize;
356
        PyObject* key = PyList_GET_ITEM(keys, i);
357
        PyObject* value = PyList_GET_ITEM(values, i);
358
359
        if (! PyString_Check(key) || ! PyString_Check(value)) {
360
            PyErr_SetString(PyExc_TypeError,
361
                "environment can only contain strings");
362
            goto error;
363
        }
364
        ksize = PyString_GET_SIZE(key);
365
        vsize = PyString_GET_SIZE(value);
366
        totalsize = (p - PyString_AS_STRING(out)) + ksize + 1 +
367
                                                     vsize + 1 + 1;
368
        if (totalsize > PyString_GET_SIZE(out)) {
369
            int offset = p - PyString_AS_STRING(out);
370
            _PyString_Resize(&out, totalsize + 1024);
371
            p = PyString_AS_STRING(out) + offset;
372
        }
373
        memcpy(p, PyString_AS_STRING(key), ksize);
374
        p += ksize;
375
        *p++ = '=';
376
        memcpy(p, PyString_AS_STRING(value), vsize);
377
        p += vsize;
378
        *p++ = '\0';
379
    }
380
381
    /* add trailing null byte */
382
    *p++ = '\0';
383
    _PyString_Resize(&out, p - PyString_AS_STRING(out));
384
385
    /* PyObject_Print(out, stdout, 0); */
386
387
    Py_XDECREF(keys);
388
    Py_XDECREF(values);
389
390
    return out;
1 by Matthias Klose
Import upstream version 2.7~a2
391
392
 error:
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
393
    Py_XDECREF(out);
394
    Py_XDECREF(keys);
395
    Py_XDECREF(values);
396
    return NULL;
1 by Matthias Klose
Import upstream version 2.7~a2
397
}
398
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
399
PyDoc_STRVAR(CreateProcess_doc,
400
"CreateProcess(app_name, cmd_line, proc_attrs, thread_attrs,\n\
401
               inherit, flags, env_mapping, curdir,\n\
402
               startup_info) -> (proc_handle, thread_handle,\n\
403
                                 pid, tid)\n\
404
\n\
405
Create a new process and its primary thread. The return\n\
406
value is a tuple of the process handle, thread handle,\n\
407
process ID, and thread ID.\n\
408
\n\
409
proc_attrs and thread_attrs are ignored internally and can be None.");
410
1 by Matthias Klose
Import upstream version 2.7~a2
411
static PyObject *
412
sp_CreateProcess(PyObject* self, PyObject* args)
413
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
414
    BOOL result;
415
    PROCESS_INFORMATION pi;
416
    STARTUPINFO si;
417
    PyObject* environment;
418
419
    char* application_name;
420
    char* command_line;
421
    PyObject* process_attributes; /* ignored */
422
    PyObject* thread_attributes; /* ignored */
423
    int inherit_handles;
424
    int creation_flags;
425
    PyObject* env_mapping;
426
    char* current_directory;
427
    PyObject* startup_info;
428
429
    if (! PyArg_ParseTuple(args, "zzOOiiOzO:CreateProcess",
430
                           &application_name,
431
                           &command_line,
432
                           &process_attributes,
433
                           &thread_attributes,
434
                           &inherit_handles,
435
                           &creation_flags,
436
                           &env_mapping,
437
                           &current_directory,
438
                           &startup_info))
439
        return NULL;
440
441
    ZeroMemory(&si, sizeof(si));
442
    si.cb = sizeof(si);
443
444
    /* note: we only support a small subset of all SI attributes */
445
    si.dwFlags = getint(startup_info, "dwFlags");
446
    si.wShowWindow = getint(startup_info, "wShowWindow");
447
    si.hStdInput = gethandle(startup_info, "hStdInput");
448
    si.hStdOutput = gethandle(startup_info, "hStdOutput");
449
    si.hStdError = gethandle(startup_info, "hStdError");
450
451
    if (PyErr_Occurred())
452
        return NULL;
453
454
    if (env_mapping == Py_None)
455
        environment = NULL;
456
    else {
457
        environment = getenvironment(env_mapping);
458
        if (! environment)
459
            return NULL;
460
    }
461
462
    Py_BEGIN_ALLOW_THREADS
463
    result = CreateProcess(application_name,
464
                           command_line,
465
                           NULL,
466
                           NULL,
467
                           inherit_handles,
468
                           creation_flags,
469
                           environment ? PyString_AS_STRING(environment) : NULL,
470
                           current_directory,
471
                           &si,
472
                           &pi);
473
    Py_END_ALLOW_THREADS
474
475
    Py_XDECREF(environment);
476
477
    if (! result)
478
        return PyErr_SetFromWindowsErr(GetLastError());
479
480
    return Py_BuildValue("NNii",
481
                         sp_handle_new(pi.hProcess),
482
                         sp_handle_new(pi.hThread),
483
                         pi.dwProcessId,
484
                         pi.dwThreadId);
1 by Matthias Klose
Import upstream version 2.7~a2
485
}
486
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
487
PyDoc_STRVAR(TerminateProcess_doc,
488
"TerminateProcess(handle, exit_code) -> None\n\
489
\n\
490
Terminate the specified process and all of its threads.");
491
1 by Matthias Klose
Import upstream version 2.7~a2
492
static PyObject *
493
sp_TerminateProcess(PyObject* self, PyObject* args)
494
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
495
    BOOL result;
496
497
    HANDLE process;
498
    int exit_code;
499
    if (! PyArg_ParseTuple(args, PY_HANDLE_PARAM "i:TerminateProcess",
500
                           &process, &exit_code))
501
        return NULL;
502
503
    result = TerminateProcess(process, exit_code);
504
505
    if (! result)
506
        return PyErr_SetFromWindowsErr(GetLastError());
507
508
    Py_INCREF(Py_None);
509
    return Py_None;
1 by Matthias Klose
Import upstream version 2.7~a2
510
}
511
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
512
PyDoc_STRVAR(GetExitCodeProcess_doc,
513
"GetExitCodeProcess(handle) -> Exit code\n\
514
\n\
515
Return the termination status of the specified process.");
516
1 by Matthias Klose
Import upstream version 2.7~a2
517
static PyObject *
518
sp_GetExitCodeProcess(PyObject* self, PyObject* args)
519
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
520
    DWORD exit_code;
521
    BOOL result;
522
523
    HANDLE process;
524
    if (! PyArg_ParseTuple(args, PY_HANDLE_PARAM ":GetExitCodeProcess", &process))
525
        return NULL;
526
527
    result = GetExitCodeProcess(process, &exit_code);
528
529
    if (! result)
530
        return PyErr_SetFromWindowsErr(GetLastError());
531
532
    return PyInt_FromLong(exit_code);
1 by Matthias Klose
Import upstream version 2.7~a2
533
}
534
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
535
PyDoc_STRVAR(WaitForSingleObject_doc,
536
"WaitForSingleObject(handle, timeout) -> result\n\
537
\n\
538
Wait until the specified object is in the signaled state or\n\
539
the time-out interval elapses. The timeout value is specified\n\
540
in milliseconds.");
541
1 by Matthias Klose
Import upstream version 2.7~a2
542
static PyObject *
543
sp_WaitForSingleObject(PyObject* self, PyObject* args)
544
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
545
    DWORD result;
546
547
    HANDLE handle;
548
    int milliseconds;
549
    if (! PyArg_ParseTuple(args, PY_HANDLE_PARAM "i:WaitForSingleObject",
550
                                 &handle,
551
                                 &milliseconds))
552
        return NULL;
553
554
    Py_BEGIN_ALLOW_THREADS
555
    result = WaitForSingleObject(handle, (DWORD) milliseconds);
556
    Py_END_ALLOW_THREADS
557
558
    if (result == WAIT_FAILED)
559
        return PyErr_SetFromWindowsErr(GetLastError());
560
561
    return PyInt_FromLong((int) result);
1 by Matthias Klose
Import upstream version 2.7~a2
562
}
563
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
564
PyDoc_STRVAR(GetVersion_doc,
565
"GetVersion() -> version\n\
566
\n\
567
Return the version number of the current operating system.");
568
1 by Matthias Klose
Import upstream version 2.7~a2
569
static PyObject *
570
sp_GetVersion(PyObject* self, PyObject* args)
571
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
572
    if (! PyArg_ParseTuple(args, ":GetVersion"))
573
        return NULL;
1 by Matthias Klose
Import upstream version 2.7~a2
574
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
575
    return PyInt_FromLong((int) GetVersion());
1 by Matthias Klose
Import upstream version 2.7~a2
576
}
577
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
578
PyDoc_STRVAR(GetModuleFileName_doc,
579
"GetModuleFileName(module) -> path\n\
580
\n\
581
Return the fully-qualified path for the file that contains\n\
582
the specified module. The module must have been loaded by the\n\
583
current process.\n\
584
\n\
585
The module parameter should be a handle to the loaded module\n\
586
whose path is being requested. If this parameter is 0, \n\
587
GetModuleFileName retrieves the path of the executable file\n\
588
of the current process.");
589
1 by Matthias Klose
Import upstream version 2.7~a2
590
static PyObject *
591
sp_GetModuleFileName(PyObject* self, PyObject* args)
592
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
593
    BOOL result;
594
    HMODULE module;
595
    TCHAR filename[MAX_PATH];
596
597
    if (! PyArg_ParseTuple(args, PY_HANDLE_PARAM ":GetModuleFileName",
598
                           &module))
599
        return NULL;
600
601
    result = GetModuleFileName(module, filename, MAX_PATH);
602
    filename[MAX_PATH-1] = '\0';
603
604
    if (! result)
605
        return PyErr_SetFromWindowsErr(GetLastError());
606
607
    return PyString_FromString(filename);
1 by Matthias Klose
Import upstream version 2.7~a2
608
}
609
610
static PyMethodDef sp_functions[] = {
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
611
    {"GetStdHandle", sp_GetStdHandle, METH_VARARGS, GetStdHandle_doc},
612
    {"GetCurrentProcess", sp_GetCurrentProcess,         METH_VARARGS,
613
                                              GetCurrentProcess_doc},
614
    {"DuplicateHandle",         sp_DuplicateHandle,     METH_VARARGS,
615
                                            DuplicateHandle_doc},
616
    {"CreatePipe", sp_CreatePipe, METH_VARARGS, CreatePipe_doc},
617
    {"CreateProcess", sp_CreateProcess, METH_VARARGS, CreateProcess_doc},
618
    {"TerminateProcess", sp_TerminateProcess, METH_VARARGS,
619
                                             TerminateProcess_doc},
620
    {"GetExitCodeProcess", sp_GetExitCodeProcess, METH_VARARGS,
621
                                               GetExitCodeProcess_doc},
622
    {"WaitForSingleObject", sp_WaitForSingleObject, METH_VARARGS,
623
                                                    WaitForSingleObject_doc},
624
    {"GetVersion", sp_GetVersion, METH_VARARGS, GetVersion_doc},
625
    {"GetModuleFileName", sp_GetModuleFileName, METH_VARARGS,
626
                                              GetModuleFileName_doc},
627
    {NULL, NULL}
1 by Matthias Klose
Import upstream version 2.7~a2
628
};
629
630
/* -------------------------------------------------------------------- */
631
632
static void
633
defint(PyObject* d, const char* name, int value)
634
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
635
    PyObject* v = PyInt_FromLong((long) value);
636
    if (v) {
637
        PyDict_SetItemString(d, (char*) name, v);
638
        Py_DECREF(v);
639
    }
1 by Matthias Klose
Import upstream version 2.7~a2
640
}
641
642
#if PY_VERSION_HEX >= 0x02030000
643
PyMODINIT_FUNC
644
#else
645
DL_EXPORT(void)
646
#endif
647
init_subprocess()
648
{
1.1.4 by Matthias Klose
Import upstream version 2.7~rc2
649
    PyObject *d;
650
    PyObject *m;
651
652
    /* patch up object descriptors */
653
    sp_handle_type.ob_type = &PyType_Type;
654
    sp_handle_as_number.nb_int = (unaryfunc) sp_handle_as_int;
655
656
    m = Py_InitModule("_subprocess", sp_functions);
657
    if (m == NULL)
658
        return;
659
    d = PyModule_GetDict(m);
660
661
    /* constants */
662
    defint(d, "STD_INPUT_HANDLE", STD_INPUT_HANDLE);
663
    defint(d, "STD_OUTPUT_HANDLE", STD_OUTPUT_HANDLE);
664
    defint(d, "STD_ERROR_HANDLE", STD_ERROR_HANDLE);
665
    defint(d, "DUPLICATE_SAME_ACCESS", DUPLICATE_SAME_ACCESS);
666
    defint(d, "STARTF_USESTDHANDLES", STARTF_USESTDHANDLES);
667
    defint(d, "STARTF_USESHOWWINDOW", STARTF_USESHOWWINDOW);
668
    defint(d, "SW_HIDE", SW_HIDE);
669
    defint(d, "INFINITE", INFINITE);
670
    defint(d, "WAIT_OBJECT_0", WAIT_OBJECT_0);
671
    defint(d, "CREATE_NEW_CONSOLE", CREATE_NEW_CONSOLE);
672
    defint(d, "CREATE_NEW_PROCESS_GROUP", CREATE_NEW_PROCESS_GROUP);
1.1.13 by Matthias Klose
Import upstream version 2.7.4~rc1
673
    defint(d, "STILL_ACTIVE", STILL_ACTIVE);
1 by Matthias Klose
Import upstream version 2.7~a2
674
}