~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to PC/_subprocess.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

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