Remove a duplicate entry in gio.defs
[pygobject.git] / glib / pygspawn.c
blobcded501886be6edae299eb842a91b4d92de28ada
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, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 * USA
24 #include <Python.h>
25 #include <glib.h>
27 #include "pyglib.h"
28 #include "pyglib-private.h"
30 struct _PyGChildSetupData {
31 PyObject *func;
32 PyObject *data;
35 PYGLIB_DEFINE_TYPE("glib.Pid", PyGPid_Type, _PyLongObject)
37 static PyObject *
38 pyg_pid_close(PyObject *self, PyObject *args, PyObject *kwargs)
40 g_spawn_close_pid(_PyLong_AsLong(self));
41 Py_INCREF(Py_None);
42 return Py_None;
45 static PyMethodDef pyg_pid_methods[] = {
46 { "close", (PyCFunction)pyg_pid_close, METH_NOARGS },
47 { NULL, NULL, 0 }
50 static void
51 pyg_pid_free(PyObject *gpid)
53 g_spawn_close_pid((GPid) _PyLong_AsLong(gpid));
54 _PyLong_Type.tp_free((void *) gpid);
57 static int
58 pyg_pid_tp_init(PyObject *self, PyObject *args, PyObject *kwargs)
60 PyErr_SetString(PyExc_TypeError, "glib.Pid cannot be manually instantiated");
61 return -1;
64 PyObject *
65 pyg_pid_new(GPid pid)
67 _PyLongObject *pygpid;
68 pygpid = PyObject_NEW(_PyLongObject, &PyGPid_Type);
70 #if PY_VERSION_HEX >= 0x03000000
71 # warning "FIXME: figure out how to subclass long"
72 #else
73 pygpid->ob_ival = pid;
74 #endif
75 return (PyObject *) pygpid;
78 static void
79 _pyg_spawn_async_callback(gpointer user_data)
81 struct _PyGChildSetupData *data;
82 PyObject *retval;
83 PyGILState_STATE gil;
85 data = (struct _PyGChildSetupData *) user_data;
86 gil = pyglib_gil_state_ensure();
87 if (data->data)
88 retval = PyObject_CallFunction(data->func, "O", data->data);
89 else
90 retval = PyObject_CallFunction(data->func, NULL);
91 if (retval)
92 Py_DECREF(retval);
93 else
94 PyErr_Print();
95 Py_DECREF(data->func);
96 Py_XDECREF(data->data);
97 g_slice_free(struct _PyGChildSetupData, data);
98 pyglib_gil_state_release(gil);
101 PyObject *
102 pyglib_spawn_async(PyObject *object, PyObject *args, PyObject *kwargs)
104 static char *kwlist[] = { "argv", "envp", "working_directory", "flags",
105 "child_setup", "user_data", "standard_input",
106 "standard_output", "standard_error", NULL };
107 PyObject *pyargv, *pyenvp = NULL;
108 char **argv, **envp = NULL;
109 PyObject *func = Py_None, *user_data = NULL;
110 char *working_directory = NULL;
111 int flags = 0, _stdin = -1, _stdout = -1, _stderr = -1;
112 PyObject *pystdin = NULL, *pystdout = NULL, *pystderr = NULL;
113 gint *standard_input, *standard_output, *standard_error;
114 struct _PyGChildSetupData *callback_data = NULL;
115 GError *error = NULL;
116 GPid child_pid = -1;
117 Py_ssize_t len, i;
119 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OsiOOOOO:glib.spawn_async",
120 kwlist,
121 &pyargv, &pyenvp, &working_directory, &flags,
122 &func, &user_data,
123 &pystdin, &pystdout, &pystderr))
124 return NULL;
126 if (pystdin && PyObject_IsTrue(pystdin))
127 standard_input = &_stdin;
128 else
129 standard_input = NULL;
131 if (pystdout && PyObject_IsTrue(pystdout))
132 standard_output = &_stdout;
133 else
134 standard_output = NULL;
136 if (pystderr && PyObject_IsTrue(pystderr))
137 standard_error = &_stderr;
138 else
139 standard_error = NULL;
141 /* parse argv */
142 if (!PySequence_Check(pyargv)) {
143 PyErr_SetString(PyExc_TypeError,
144 "glib.spawn_async: "
145 "first argument must be a sequence of strings");
146 return NULL;
148 len = PySequence_Length(pyargv);
149 argv = g_new0(char *, len + 1);
150 for (i = 0; i < len; ++i) {
151 PyObject *tmp = PySequence_ITEM(pyargv, i);
152 if (!_PyUnicode_Check(tmp)) {
153 PyErr_SetString(PyExc_TypeError,
154 "glib.spawn_async: "
155 "first argument must be a sequence of strings");
156 g_free(argv);
157 Py_XDECREF(tmp);
158 return NULL;
160 argv[i] = _PyUnicode_AsString(tmp);
161 Py_DECREF(tmp);
164 /* parse envp */
165 if (pyenvp) {
166 if (!PySequence_Check(pyenvp)) {
167 PyErr_SetString(PyExc_TypeError,
168 "glib.spawn_async: "
169 "second argument must be a sequence of strings");
170 g_free(argv);
171 return NULL;
173 len = PySequence_Length(pyenvp);
174 envp = g_new0(char *, len + 1);
175 for (i = 0; i < len; ++i) {
176 PyObject *tmp = PySequence_ITEM(pyenvp, i);
177 if (!_PyUnicode_Check(tmp)) {
178 PyErr_SetString(PyExc_TypeError,
179 "glib.spawn_async: "
180 "second argument must be a sequence of strings");
181 g_free(envp);
182 Py_XDECREF(tmp);
183 g_free(argv);
184 return NULL;
186 envp[i] = _PyUnicode_AsString(tmp);
187 Py_DECREF(tmp);
191 if (func != Py_None) {
192 if (!PyCallable_Check(func)) {
193 PyErr_SetString(PyExc_TypeError, "child_setup parameter must be callable or None");
194 g_free(argv);
195 if (envp)
196 g_free(envp);
197 return NULL;
199 callback_data = g_slice_new(struct _PyGChildSetupData);
200 callback_data->func = func;
201 callback_data->data = user_data;
202 Py_INCREF(callback_data->func);
203 if (callback_data->data)
204 Py_INCREF(callback_data->data);
207 if (!g_spawn_async_with_pipes(working_directory, argv, envp, flags,
208 (func != Py_None ? _pyg_spawn_async_callback : NULL),
209 callback_data, &child_pid,
210 standard_input,
211 standard_output,
212 standard_error,
213 &error))
217 g_free(argv);
218 if (envp) g_free(envp);
219 if (callback_data) {
220 Py_DECREF(callback_data->func);
221 Py_XDECREF(callback_data->data);
222 g_slice_free(struct _PyGChildSetupData, callback_data);
224 pyglib_error_check(&error);
225 return NULL;
227 g_free(argv);
228 if (envp) g_free(envp);
230 if (standard_input)
231 pystdin = _PyLong_FromLong(*standard_input);
232 else {
233 Py_INCREF(Py_None);
234 pystdin = Py_None;
237 if (standard_output)
238 pystdout = _PyLong_FromLong(*standard_output);
239 else {
240 Py_INCREF(Py_None);
241 pystdout = Py_None;
244 if (standard_error)
245 pystderr = _PyLong_FromLong(*standard_error);
246 else {
247 Py_INCREF(Py_None);
248 pystderr = Py_None;
251 return Py_BuildValue("NNNN", pyg_pid_new(child_pid), pystdin, pystdout, pystderr);
254 void
255 pyglib_spawn_register_types(PyObject *d)
257 PyGPid_Type.tp_base = &_PyLong_Type;
258 PyGPid_Type.tp_flags = Py_TPFLAGS_DEFAULT;
259 PyGPid_Type.tp_methods = pyg_pid_methods;
260 PyGPid_Type.tp_init = pyg_pid_tp_init;
261 PyGPid_Type.tp_free = (freefunc)pyg_pid_free;
262 PYGLIB_REGISTER_TYPE(d, PyGPid_Type, "Pid");