diff -r 5f90ef1df157 Modules/ossaudiodev.c --- a/Modules/ossaudiodev.c Wed Mar 18 16:05:32 2015 +0100 +++ b/Modules/ossaudiodev.c Thu Mar 19 14:29:23 2015 +0100 @@ -48,12 +48,12 @@ typedef unsigned long uint32_t; typedef struct { PyObject_HEAD - char *devicename; /* name of the device file */ - int fd; /* file descriptor */ - int mode; /* file mode (O_RDONLY, etc.) */ - int icount; /* input count */ - int ocount; /* output count */ - uint32_t afmts; /* audio formats supported by hardware */ + char *devicename; /* name of the device file */ + int fd; /* file descriptor */ + int mode; /* file mode (O_RDONLY, etc.) */ + Py_ssize_t icount; /* input count */ + Py_ssize_t ocount; /* output count */ + uint32_t afmts; /* audio formats supported by hardware */ } oss_audio_t; typedef struct { @@ -399,29 +399,24 @@ oss_post(oss_audio_t *self, PyObject *ar static PyObject * oss_read(oss_audio_t *self, PyObject *args) { - int size, count; - char *cp; + Py_ssize_t size, count; PyObject *rv; if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "i:read", &size)) + if (!PyArg_ParseTuple(args, "n:read", &size)) return NULL; rv = PyBytes_FromStringAndSize(NULL, size); if (rv == NULL) return NULL; - cp = PyBytes_AS_STRING(rv); - Py_BEGIN_ALLOW_THREADS - count = read(self->fd, cp, size); - Py_END_ALLOW_THREADS - - if (count < 0) { - PyErr_SetFromErrno(PyExc_IOError); + count = _Py_read(self->fd, PyBytes_AS_STRING(rv), size); + if (count == -1) { Py_DECREF(rv); return NULL; } + self->icount += count; _PyBytes_Resize(&rv, count); return rv; @@ -430,35 +425,33 @@ oss_read(oss_audio_t *self, PyObject *ar static PyObject * oss_write(oss_audio_t *self, PyObject *args) { - char *cp; - int rv, size; + Py_buffer buf; + Py_ssize_t rv; if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) { + if (!PyArg_ParseTuple(args, "y*:write", &buf)) return NULL; - } - Py_BEGIN_ALLOW_THREADS - rv = write(self->fd, cp, size); - Py_END_ALLOW_THREADS + rv = _Py_write(self->fd, buf.buf, buf.len); + PyBuffer_Release(&buf); + if (rv == -1) + return NULL; - if (rv == -1) { - return PyErr_SetFromErrno(PyExc_IOError); - } else { - self->ocount += rv; - } + self->ocount += rv; return PyLong_FromLong(rv); } static PyObject * oss_writeall(oss_audio_t *self, PyObject *args) { + Py_buffer buf; char *cp; - int rv, size; + Py_ssize_t size, rv; fd_set write_set_fds; int select_rv; + PyObject *res = NULL; /* NB. writeall() is only useful in non-blocking mode: according to Guenter Geiger on the linux-audio-dev list @@ -470,13 +463,15 @@ oss_writeall(oss_audio_t *self, PyObject if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) + if (!PyArg_ParseTuple(args, "y*:write", &buf)) return NULL; + cp = buf.buf; + size = buf.len; if (!_PyIsSelectable_fd(self->fd)) { PyErr_SetString(PyExc_ValueError, "file descriptor out of range for select"); - return NULL; + goto finally; } /* use select to wait for audio device to be available */ FD_ZERO(&write_set_fds); @@ -487,26 +482,35 @@ oss_writeall(oss_audio_t *self, PyObject 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) - return PyErr_SetFromErrno(PyExc_IOError); + if (select_rv == -1) { + PyErr_SetFromErrno(PyExc_IOError); + goto finally; + } - Py_BEGIN_ALLOW_THREADS - rv = write(self->fd, cp, size); - Py_END_ALLOW_THREADS + rv = _Py_write(self->fd, cp, size); if (rv == -1) { - if (errno == EAGAIN) { /* buffer is full, try again */ - errno = 0; + /* buffer is full, try again */ + if (errno == EAGAIN) { + PyErr_Clear(); continue; - } else /* it's a real error */ - return PyErr_SetFromErrno(PyExc_IOError); - } else { /* wrote rv bytes */ - self->ocount += rv; - size -= rv; - cp += rv; + } + /* it's a real error */ + goto finally; } + + /* wrote rv bytes */ + self->ocount += rv; + size -= rv; + cp += rv; } + PyBuffer_Release(&buf); + Py_INCREF(Py_None); - return Py_None; + res = Py_None; + +finally: + PyBuffer_Release(&buf); + return res; } static PyObject *