functions: revert the function init order to make pylint happy again. See #217
[pygobject.git] / gi / pygspawn.c
blob9457c6de1084a05b408367d9f4dd18357a6022cc
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * pyglib - Python bindings for GLib toolkit.
3 * Copyright (C) 1998-2003 James Henstridge
4 * 2004-2008 Johan Dahlin
6 * pygspawn.c: wrapper for the glib library.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 #include <Python.h>
23 #include <glib.h>
25 #include "pygi-python-compat.h"
26 #include "pygi-basictype.h"
27 #include "pygspawn.h"
28 #include "pygi-error.h"
30 struct _PyGChildSetupData {
31 PyObject *func;
32 PyObject *data;
35 PYGLIB_DEFINE_TYPE("gi._gi.Pid", PyGPid_Type, PYGLIB_PyLongObject)
37 static GPid
38 pyg_pid_get_pid (PyObject *self)
40 #ifdef G_OS_WIN32
41 return (GPid)PyLong_AsVoidPtr (self);
42 #else
43 return (GPid)PYGLIB_PyLong_AsLong (self);
44 #endif
47 static PyObject *
48 pyg_pid_close(PyObject *self, PyObject *args, PyObject *kwargs)
50 g_spawn_close_pid(pyg_pid_get_pid (self));
51 Py_INCREF(Py_None);
52 return Py_None;
55 static PyMethodDef pyg_pid_methods[] = {
56 { "close", (PyCFunction)pyg_pid_close, METH_NOARGS },
57 { NULL, NULL, 0 }
60 static void
61 pyg_pid_free(PyObject *gpid)
63 g_spawn_close_pid(pyg_pid_get_pid (gpid));
64 PYGLIB_PyLong_Type.tp_free((void *) gpid);
67 static int
68 pyg_pid_tp_init(PyObject *self, PyObject *args, PyObject *kwargs)
70 PyErr_SetString(PyExc_TypeError, "gi._gi.Pid cannot be manually instantiated");
71 return -1;
74 PyObject *
75 pyg_pid_new(GPid pid)
77 PyObject *long_val;
78 #ifdef G_OS_WIN32
79 long_val = PyLong_FromVoidPtr (pid);
80 #else
81 long_val = pygi_gint_to_py (pid);
82 #endif
83 return PyObject_CallMethod((PyObject*)&PyGPid_Type, "__new__", "ON",
84 &PyGPid_Type, long_val);
87 static void
88 _pyg_spawn_async_callback(gpointer user_data)
90 struct _PyGChildSetupData *data;
91 PyObject *retval;
92 PyGILState_STATE gil;
94 data = (struct _PyGChildSetupData *) user_data;
95 gil = PyGILState_Ensure();
96 if (data->data)
97 retval = PyObject_CallFunction(data->func, "O", data->data);
98 else
99 retval = PyObject_CallFunction(data->func, NULL);
100 if (retval)
101 Py_DECREF(retval);
102 else
103 PyErr_Print();
104 Py_DECREF(data->func);
105 Py_XDECREF(data->data);
106 g_slice_free(struct _PyGChildSetupData, data);
107 PyGILState_Release(gil);
110 PyObject *
111 pyglib_spawn_async(PyObject *object, PyObject *args, PyObject *kwargs)
113 static char *kwlist[] = { "argv", "envp", "working_directory", "flags",
114 "child_setup", "user_data", "standard_input",
115 "standard_output", "standard_error", NULL };
116 PyObject *pyargv, *pyenvp = NULL;
117 char **argv, **envp = NULL;
118 PyObject *func = Py_None, *user_data = NULL;
119 char *working_directory = NULL;
120 int flags = 0, _stdin = -1, _stdout = -1, _stderr = -1;
121 PyObject *pystdin = NULL, *pystdout = NULL, *pystderr = NULL;
122 gint *standard_input, *standard_output, *standard_error;
123 struct _PyGChildSetupData *callback_data = NULL;
124 GError *error = NULL;
125 GPid child_pid = 0;
126 Py_ssize_t len, i;
128 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OsiOOOOO:gi._gi.spawn_async",
129 kwlist,
130 &pyargv, &pyenvp, &working_directory, &flags,
131 &func, &user_data,
132 &pystdin, &pystdout, &pystderr))
133 return NULL;
135 if (pystdin && PyObject_IsTrue(pystdin))
136 standard_input = &_stdin;
137 else
138 standard_input = NULL;
140 if (pystdout && PyObject_IsTrue(pystdout))
141 standard_output = &_stdout;
142 else
143 standard_output = NULL;
145 if (pystderr && PyObject_IsTrue(pystderr))
146 standard_error = &_stderr;
147 else
148 standard_error = NULL;
150 /* parse argv */
151 if (!PySequence_Check(pyargv)) {
152 PyErr_SetString(PyExc_TypeError,
153 "gi._gi.spawn_async: "
154 "first argument must be a sequence of strings");
155 return NULL;
157 len = PySequence_Length(pyargv);
158 argv = g_new0(char *, len + 1);
159 for (i = 0; i < len; ++i) {
160 PyObject *tmp = PySequence_ITEM(pyargv, i);
161 if (tmp == NULL || !PYGLIB_PyUnicode_Check(tmp)) {
162 PyErr_SetString(PyExc_TypeError,
163 "gi._gi.spawn_async: "
164 "first argument must be a sequence of strings");
165 g_free(argv);
166 Py_XDECREF(tmp);
167 return NULL;
169 argv[i] = PYGLIB_PyUnicode_AsString(tmp);
170 Py_DECREF(tmp);
173 /* parse envp */
174 if (pyenvp) {
175 if (!PySequence_Check(pyenvp)) {
176 PyErr_SetString(PyExc_TypeError,
177 "gi._gi.spawn_async: "
178 "second argument must be a sequence of strings");
179 g_free(argv);
180 return NULL;
182 len = PySequence_Length(pyenvp);
183 envp = g_new0(char *, len + 1);
184 for (i = 0; i < len; ++i) {
185 PyObject *tmp = PySequence_ITEM(pyenvp, i);
186 if (tmp == NULL || !PYGLIB_PyUnicode_Check(tmp)) {
187 PyErr_SetString(PyExc_TypeError,
188 "gi._gi.spawn_async: "
189 "second argument must be a sequence of strings");
190 g_free(envp);
191 Py_XDECREF(tmp);
192 g_free(argv);
193 return NULL;
195 envp[i] = PYGLIB_PyUnicode_AsString(tmp);
196 Py_DECREF(tmp);
200 if (func != Py_None) {
201 if (!PyCallable_Check(func)) {
202 PyErr_SetString(PyExc_TypeError, "child_setup parameter must be callable or None");
203 g_free(argv);
204 if (envp)
205 g_free(envp);
206 return NULL;
208 callback_data = g_slice_new(struct _PyGChildSetupData);
209 callback_data->func = func;
210 callback_data->data = user_data;
211 Py_INCREF(callback_data->func);
212 if (callback_data->data)
213 Py_INCREF(callback_data->data);
216 if (!g_spawn_async_with_pipes(working_directory, argv, envp, flags,
217 (func != Py_None ? _pyg_spawn_async_callback : NULL),
218 callback_data, &child_pid,
219 standard_input,
220 standard_output,
221 standard_error,
222 &error))
226 g_free(argv);
227 if (envp) g_free(envp);
228 if (callback_data) {
229 Py_DECREF(callback_data->func);
230 Py_XDECREF(callback_data->data);
231 g_slice_free(struct _PyGChildSetupData, callback_data);
233 pygi_error_check(&error);
234 return NULL;
236 g_free(argv);
237 if (envp) g_free(envp);
239 if (standard_input)
240 pystdin = pygi_gint_to_py(*standard_input);
241 else {
242 Py_INCREF(Py_None);
243 pystdin = Py_None;
246 if (standard_output)
247 pystdout = pygi_gint_to_py(*standard_output);
248 else {
249 Py_INCREF(Py_None);
250 pystdout = Py_None;
253 if (standard_error)
254 pystderr = pygi_gint_to_py(*standard_error);
255 else {
256 Py_INCREF(Py_None);
257 pystderr = Py_None;
260 return Py_BuildValue("NNNN", pyg_pid_new(child_pid), pystdin, pystdout, pystderr);
264 * Returns 0 on success, or -1 and sets an exception.
267 pygi_spawn_register_types(PyObject *d)
269 PyGPid_Type.tp_base = &PYGLIB_PyLong_Type;
270 PyGPid_Type.tp_flags = Py_TPFLAGS_DEFAULT;
271 PyGPid_Type.tp_methods = pyg_pid_methods;
272 PyGPid_Type.tp_init = pyg_pid_tp_init;
273 PyGPid_Type.tp_free = (freefunc)pyg_pid_free;
274 PyGPid_Type.tp_new = PYGLIB_PyLong_Type.tp_new;
275 PYGLIB_REGISTER_TYPE(d, PyGPid_Type, "Pid");
277 return 0;