diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_fileio.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/Modules/_fileio.c b/Modules/_fileio.c index bc707e8..8469bb2 100644 --- a/Modules/_fileio.c +++ b/Modules/_fileio.c @@ -33,6 +33,7 @@ typedef struct { unsigned readable : 1; unsigned writable : 1; int seekable : 2; /* -1 means unknown */ + int closefd : 1; PyObject *weakreflist; } PyFileIOObject; @@ -59,6 +60,13 @@ internal_close(PyFileIOObject *self) static PyObject * fileio_close(PyFileIOObject *self) { + if (!self->closefd) { + if (PyErr_WarnEx(PyExc_RuntimeWarning, + "Trying to close unclosable fd!", 3) < 0) { + return NULL; + } + Py_RETURN_NONE; + } errno = internal_close(self); if (errno < 0) { PyErr_SetFromErrno(PyExc_IOError); @@ -119,7 +127,7 @@ static int fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) { PyFileIOObject *self = (PyFileIOObject *) oself; - static char *kwlist[] = {"file", "mode", NULL}; + static char *kwlist[] = {"file", "mode", "closefd", NULL}; char *name = NULL; char *mode = "r"; char *s; @@ -130,6 +138,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) int rwa = 0, plus = 0, append = 0; int flags = 0; int fd = -1; + int closefd = 1; assert(PyFileIO_Check(oself)); if (self->fd >= 0) { @@ -138,8 +147,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) return -1; } - if (PyArg_ParseTupleAndKeywords(args, kwds, "i|s:fileio", - kwlist, &fd, &mode)) { + if (PyArg_ParseTupleAndKeywords(args, kwds, "i|si:fileio", + kwlist, &fd, &mode, &closefd)) { if (fd < 0) { PyErr_SetString(PyExc_ValueError, "Negative filedescriptor"); @@ -153,8 +162,9 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) if (GetVersion() < 0x80000000) { /* On NT, so wide API available */ PyObject *po; - if (PyArg_ParseTupleAndKeywords(args, kwds, "U|s:fileio", - kwlist, &po, &mode)) { + if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:fileio", + kwlist, &po, &mode, &closefd) + ) { widename = PyUnicode_AS_UNICODE(po); } else { /* Drop the argument parsing error as narrow @@ -162,13 +172,13 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) PyErr_Clear(); } } - if (widename == NULL) + if (widename == NULL) #endif { - if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:fileio", + if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:fileio", kwlist, Py_FileSystemDefaultEncoding, - &name, &mode)) + &name, &mode, &closefd)) goto error; } } @@ -237,8 +247,16 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) if (fd >= 0) { self->fd = fd; + self->closefd = closefd; } else { + self->closefd = 1; + if (!closefd) { + PyErr_SetString(PyExc_ValueError, + "Cannot use closefd=True with file name"); + goto error; + } + Py_BEGIN_ALLOW_THREADS errno = 0; #ifdef MS_WINDOWS @@ -270,7 +288,7 @@ fileio_dealloc(PyFileIOObject *self) if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); - if (self->fd >= 0) { + if (self->fd >= 0 && self->closefd) { errno = internal_close(self); if (errno < 0) { #ifdef HAVE_STRERROR |