static PyObject * stdprinter_write(PyStdPrinter_Object *self, PyObject *args) { PyObject *unicode; PyObject *bytes = NULL; const char *str; Py_ssize_t n; int err; if (self->fd < 0) { /* fd might be invalid on Windows * I can't raise an exception here. It may lead to an * unlimited recursion in the case stderr is invalid. */ Py_RETURN_NONE; } if (!PyArg_ParseTuple(args, "U", &unicode)) return NULL; /* encode Unicode to UTF-8 */ str = PyUnicode_AsUTF8AndSize(unicode, &n); if (str == NULL) { PyErr_Clear(); bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace"); if (bytes == NULL) return NULL; str = PyBytes_AS_STRING(bytes); n = PyBytes_GET_SIZE(bytes); } n = _Py_write(self->fd, str, n); /* save errno, it can be modified indirectly by Py_XDECREF() */ err = errno; Py_XDECREF(bytes); if (n == -1) { if (err == EAGAIN) { PyErr_Clear(); Py_RETURN_NONE; } return NULL; } return PyLong_FromSsize_t(n); }
static PyObject * oss_write(oss_audio_t *self, PyObject *args) { Py_buffer data; Py_ssize_t rv; if (!_is_fd_valid(self->fd)) return NULL; if (!PyArg_ParseTuple(args, "y*:write", &data)) { return NULL; } rv = _Py_write(self->fd, data.buf, data.len); PyBuffer_Release(&data); if (rv == -1) return NULL; self->ocount += rv; return PyLong_FromLong(rv); }
static PyObject * oss_writeall(oss_audio_t *self, PyObject *args) { Py_buffer data; const char *cp; Py_ssize_t size; Py_ssize_t rv; fd_set write_set_fds; int select_rv; /* NB. writeall() is only useful in non-blocking mode: according to Guenter Geiger <*****@*****.**> on the linux-audio-dev list (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that write() in blocking mode consumes the whole buffer. In blocking mode, the behaviour of write() and writeall() from Python is indistinguishable. */ if (!_is_fd_valid(self->fd)) return NULL; if (!PyArg_ParseTuple(args, "y*:writeall", &data)) return NULL; if (!_PyIsSelectable_fd(self->fd)) { PyErr_SetString(PyExc_ValueError, "file descriptor out of range for select"); PyBuffer_Release(&data); return NULL; } /* use select to wait for audio device to be available */ FD_ZERO(&write_set_fds); FD_SET(self->fd, &write_set_fds); cp = (const char *)data.buf; size = data.len; while (size > 0) { Py_BEGIN_ALLOW_THREADS select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL); Py_END_ALLOW_THREADS assert(select_rv != 0); /* no timeout, can't expire */ if (select_rv == -1) { PyBuffer_Release(&data); return PyErr_SetFromErrno(PyExc_OSError); } rv = _Py_write(self->fd, cp, Py_MIN(size, INT_MAX)); if (rv == -1) { /* buffer is full, try again */ if (errno == EAGAIN) { PyErr_Clear(); continue; } /* it's a real error */ PyBuffer_Release(&data); return NULL; } /* wrote rv bytes */ self->ocount += rv; size -= rv; cp += rv; } PyBuffer_Release(&data); Py_RETURN_NONE; }