static int SignalChecker_tp_init(SignalChecker *self, PyObject *args, PyObject *kwargs) { int err; long fd; Loop *loop; UNUSED_ARG(kwargs); RAISE_IF_HANDLE_INITIALIZED(self, -1); if (!PyArg_ParseTuple(args, "O!l:__init__", &LoopType, &loop, &fd)) { return -1; } err = uv_poll_init_socket(loop->uv_loop, &self->poll_h, (uv_os_sock_t)fd); if (err < 0) { RAISE_UV_EXCEPTION(err, PyExc_UVError); return -1; } self->fd = fd; initialize_handle(HANDLE(self), loop); return 0; }
static int Pipe_tp_init(Pipe *self, PyObject *args, PyObject *kwargs) { int err; Loop *loop; PyObject *ipc = Py_False; UNUSED_ARG(kwargs); RAISE_IF_HANDLE_INITIALIZED(self, -1); if (!PyArg_ParseTuple(args, "O!|O!:__init__", &LoopType, &loop, &PyBool_Type, &ipc)) { return -1; } err = uv_pipe_init(loop->uv_loop, &self->pipe_h, (ipc == Py_True) ? 1 : 0); if (err < 0) { RAISE_UV_EXCEPTION(err, PyExc_PipeError); return -1; } initialize_handle(HANDLE(self), loop); return 0; }
static int Async_tp_init(Async *self, PyObject *args, PyObject *kwargs) { int r; Loop *loop; PyObject *callback, *tmp; UNUSED_ARG(kwargs); RAISE_IF_HANDLE_INITIALIZED(self, -1); if (!PyArg_ParseTuple(args, "O!O:__init__", &LoopType, &loop, &callback)) { return -1; } if (!PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "a callable is required"); return -1; } r = uv_async_init(loop->uv_loop, (uv_async_t *)UV_HANDLE(self), on_async_callback); if (r != 0) { RAISE_UV_EXCEPTION(loop->uv_loop, PyExc_AsyncError); return -1; } tmp = self->callback; Py_INCREF(callback); self->callback = callback; Py_XDECREF(tmp); initialize_handle(HANDLE(self), loop); return 0; }
static int Process_tp_init(Process *self, PyObject *args, PyObject *kwargs) { Loop *loop; UNUSED_ARG(kwargs); RAISE_IF_HANDLE_INITIALIZED(self, -1); if (!PyArg_ParseTuple(args, "O!:__init__", &LoopType, &loop)) { return -1; } initialize_handle(HANDLE(self), loop); /* uv_process_t handles are not initialized explicitly, so workaround it. See tp_dealloc for the rest */ HANDLE(self)->initialized = False; return 0; }
static int UDP_tp_init(UDP *self, PyObject *args, PyObject *kwargs) { int r; Loop *loop; UNUSED_ARG(kwargs); RAISE_IF_HANDLE_INITIALIZED(self, -1); if (!PyArg_ParseTuple(args, "O!:__init__", &LoopType, &loop)) { return -1; } r = uv_udp_init(loop->uv_loop, (uv_udp_t *)UV_HANDLE(self)); if (r != 0) { RAISE_UV_EXCEPTION(loop->uv_loop, PyExc_UDPError); return -1; } initialize_handle(HANDLE(self), loop); return 0; }
static int Timer_tp_init(Timer *self, PyObject *args, PyObject *kwargs) { int err; Loop *loop; UNUSED_ARG(kwargs); RAISE_IF_HANDLE_INITIALIZED(self, -1); if (!PyArg_ParseTuple(args, "O!:__init__", &LoopType, &loop)) { return -1; } err = uv_timer_init(loop->uv_loop, &self->timer_h); if (err < 0) { RAISE_UV_EXCEPTION(err, PyExc_TimerError); return -1; } initialize_handle(HANDLE(self), loop); return 0; }
static PyObject * Pipe_func_write2(Pipe *self, PyObject *args) { uv_buf_t buf; Py_buffer *view; PyObject *callback, *send_handle; callback = Py_None; RAISE_IF_HANDLE_NOT_INITIALIZED(self, NULL); RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL); view = PyMem_Malloc(sizeof *view); if (!view) { PyErr_NoMemory(); return NULL; } #ifdef PYUV_PYTHON3 if (!PyArg_ParseTuple(args, "y*O|O:write", view, &send_handle, &callback)) { #else if (!PyArg_ParseTuple(args, "s*O|O:write", view, &send_handle, &callback)) { #endif return NULL; } if (PyObject_IsSubclass((PyObject *)send_handle->ob_type, (PyObject *)&StreamType)) { if (UV_HANDLE(send_handle)->type != UV_TCP && UV_HANDLE(send_handle)->type != UV_NAMED_PIPE) { PyErr_SetString(PyExc_TypeError, "Only TCP and Pipe objects are supported for write2"); goto error; } } else if (PyObject_IsSubclass((PyObject *)send_handle->ob_type, (PyObject *)&UDPType)) { /* empty */ } else { PyErr_SetString(PyExc_TypeError, "Only Stream and UDP objects are supported"); goto error; } if (callback != Py_None && !PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "a callable or None is required"); goto error; } buf = uv_buf_init(view->buf, view->len); return pyuv_stream_write((Stream *)self, view, &buf, 1, callback, send_handle); error: PyBuffer_Release(view); PyMem_Free(view); return NULL; } static int Pipe_tp_init(Pipe *self, PyObject *args, PyObject *kwargs) { int r; Loop *loop; PyObject *ipc = Py_False; UNUSED_ARG(kwargs); RAISE_IF_HANDLE_INITIALIZED(self, -1); if (!PyArg_ParseTuple(args, "O!|O!:__init__", &LoopType, &loop, &PyBool_Type, &ipc)) { return -1; } r = uv_pipe_init(loop->uv_loop, (uv_pipe_t *)UV_HANDLE(self), (ipc == Py_True) ? 1 : 0); if (r != 0) { RAISE_UV_EXCEPTION(loop->uv_loop, PyExc_PipeError); return -1; } initialize_handle(HANDLE(self), loop); return 0; }
static PyObject * Process_func_spawn(PyObject *cls, PyObject *args, PyObject *kwargs) { int err, flags, stdio_count; unsigned int uid, gid; Py_ssize_t i, n, pos, size; PyObject *key, *value, *item, *tmp, *callback, *arguments, *env, *stdio, *ret, *executable, *cwd; Process *self; Loop *loop; uv_process_options_t options; uv_stdio_container_t *stdio_container; static char *kwlist[] = {"loop", "args", "executable", "env", "cwd", "uid", "gid", "flags", "stdio", "exit_callback", NULL}; cwd = executable = Py_None; tmp = arguments = env = stdio = NULL; stdio_container = NULL; flags = uid = gid = stdio_count = 0; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O|OO!OIIiOO:__init__", kwlist, &LoopType, &loop, &arguments, &executable, &PyDict_Type, &env, &cwd, &uid, &gid, &flags, &stdio, &callback)) { return NULL; } if (callback != Py_None && !PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "a callable is required"); return NULL; } if (!PyBytes_Check(arguments) && !PyUnicode_Check(arguments) && !PySequence_Check(arguments)) { PyErr_SetString(PyExc_TypeError, "only string or iterable objects are supported for 'args'"); return NULL; } if (stdio && !PySequence_Check(stdio)) { PyErr_SetString(PyExc_TypeError, "only iterable objects are supported for 'stdio'"); return NULL; } self = (Process *)Process_tp_new((PyTypeObject *) cls, args, kwargs); if (!self) { return NULL; } initialize_handle(HANDLE(self), loop); /* Don't consider the handle initialized until uv_spawn is called. Unline other handles, * there is no uv_process_init, it's called at the begining of uv_spawn, so don't * consider the handle initialized until then, or we'd call uv_close when the Python * object is deallocated, which is not A Good Thing (TM). */ HANDLE(self)->initialized = False; memset(&options, 0, sizeof(uv_process_options_t)); options.uid = uid; options.gid = gid; options.flags = flags; options.exit_cb = pyuv__process_exit_cb; /* process args */ if (PyBytes_Check(arguments) || PyUnicode_Check(arguments)) { options.args = PyMem_Malloc(sizeof *(options.args) * 2); if (!options.args) { PyErr_NoMemory(); goto error; } options.args[0] = pyuv_dup_strobj(arguments); if (!options.args[0]) { goto error; } options.args[1] = NULL; } else { /* it's a sequence object */ n = PySequence_Length(arguments); if (n < 1) { PyErr_SetString(PyExc_ValueError, "'args' must contain at least one element"); goto error; } options.args = PyMem_Malloc(sizeof *(options.args) * (n + 1)); if (!options.args) { PyErr_NoMemory(); goto error; } for (i = 0; i < n; i++) { item = PySequence_GetItem(arguments, i); if (!item) { options.args[i] = NULL; goto error; } options.args[i] = pyuv_dup_strobj(item); if (!options.args[i]) { Py_DECREF(item); goto error; } Py_DECREF(item); } options.args[n] = NULL; } /* process file */ if (executable != Py_None) { options.file = pyuv_dup_strobj(executable); if (!options.file) { goto error; } } else { size = strlen(options.args[0]) + 1; options.file = PyMem_Malloc(size); if (!options.file) { PyErr_NoMemory(); goto error; } memcpy((void*)options.file, options.args[0], size); } /* process cwd */ if (cwd != Py_None) { options.cwd = pyuv_dup_strobj(cwd); if (!options.cwd) { goto error; } } /* process env */ if (env) { char *key_str, *value_str; PyObject *key_bytes, *value_bytes; n = PyDict_Size(env); if (n > 0) { options.env = PyMem_Malloc(sizeof *(options.env) * (n + 1)); if (!options.env) { PyErr_NoMemory(); goto error; } i = 0; pos = 0; while (PyDict_Next(env, &pos, &key, &value)) { key_bytes = value_bytes = NULL; if (!pyuv_PyUnicode_FSConverter(key, &key_bytes)) { options.env[i] = NULL; goto error; } if (!pyuv_PyUnicode_FSConverter(value, &value_bytes)) { Py_DECREF(key_bytes); options.env[i] = NULL; goto error; } key_str = PyBytes_AS_STRING(key_bytes); value_str = PyBytes_AS_STRING(value_bytes); size = PyBytes_GET_SIZE(key_bytes) + PyBytes_GET_SIZE(value_bytes) + 2; options.env[i] = PyMem_Malloc(size); if (!options.env[i]) { options.env[i] = NULL; PyErr_NoMemory(); Py_DECREF(key_bytes); Py_DECREF(value_bytes); goto error; } PyOS_snprintf(options.env[i], size, "%s=%s", key_str, value_str); Py_DECREF(key_bytes); Py_DECREF(value_bytes); i++; } options.env[i] = NULL; } } /* process stdio container */ if (stdio) { n = PySequence_Length(stdio); stdio_container = PyMem_Malloc(sizeof *stdio_container * n); if (!stdio_container) { PyErr_NoMemory(); goto error; } item = NULL; for (i = 0;i < n; i++) { item = PySequence_GetItem(stdio, i); if (!item || !PyObject_TypeCheck(item, &StdIOType)) { Py_XDECREF(item); PyErr_SetString(PyExc_TypeError, "a StdIO instance is required"); goto error; } stdio_count++; stdio_container[i].flags = ((StdIO *)item)->flags; if (((StdIO *)item)->flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM)) { stdio_container[i].data.stream = (uv_stream_t *)(UV_HANDLE(((StdIO *)item)->stream)); } else if (((StdIO *)item)->flags & UV_INHERIT_FD) { stdio_container[i].data.fd = ((StdIO *)item)->fd; } Py_DECREF(item); } } options.stdio = stdio_container; options.stdio_count = stdio_count; HANDLE(self)->initialized = True; err = uv_spawn(UV_HANDLE_LOOP(self), &self->process_h, &options); if (err < 0) { RAISE_UV_EXCEPTION(err, PyExc_ProcessError); goto error; } ret = (PyObject *) self; tmp = (PyObject *)self->on_exit_cb; Py_INCREF(callback); self->on_exit_cb = callback; Py_XDECREF(tmp); tmp = self->stdio; Py_XINCREF(stdio); self->stdio = stdio; Py_XDECREF(tmp); /* Increase refcount so that object is not removed before the exit callback is called */ Py_INCREF(self); goto cleanup; error: ret = NULL; Py_DECREF(self); cleanup: if (options.args) { for (i = 0; options.args[i] != NULL; ++i) { PyMem_Free(options.args[i]); } PyMem_Free(options.args); } if (options.env) { for (i = 0; options.env[i] != NULL; ++i) { PyMem_Free(options.env[i]); } PyMem_Free(options.env); } PyMem_Free((void*)options.cwd); PyMem_Free((void*)options.file); PyMem_Free(options.stdio); return ret; }