Commit b0428159 authored by Guido van Rossum's avatar Guido van Rossum

Make it possible to instantiate a _FileIO() with an integer file descriptor

instead of a filename.
Add a 'closed' attribute.
parent b8551ae6
...@@ -22,9 +22,8 @@ ...@@ -22,9 +22,8 @@
* *
* Unanswered questions: * Unanswered questions:
* *
* - Add mode, name, and closed properties a la Python 2 file objects? * - Add mode and name properties a la Python 2 file objects?
* - Do we need a (*close)() in the struct like Python 2 file objects, * - Check for readable/writable before attempting to read/write?
* for not-quite-ordinary-file objects?
*/ */
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
...@@ -55,15 +54,16 @@ static PyObject * ...@@ -55,15 +54,16 @@ static PyObject *
fileio_close(PyFileIOObject *self) fileio_close(PyFileIOObject *self)
{ {
if (self->fd >= 0) { if (self->fd >= 0) {
int fd = self->fd;
self->fd = -1;
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
errno = 0; errno = 0;
close(self->fd); close(fd);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (errno < 0) { if (errno < 0) {
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_IOError);
return NULL; return NULL;
} }
self->fd = -1;
} }
Py_RETURN_NONE; Py_RETURN_NONE;
...@@ -123,7 +123,7 @@ static int ...@@ -123,7 +123,7 @@ static int
fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
{ {
PyFileIOObject *self = (PyFileIOObject *) oself; PyFileIOObject *self = (PyFileIOObject *) oself;
static char *kwlist[] = {"filename", "mode", NULL}; static char *kwlist[] = {"file", "mode", NULL};
char *name = NULL; char *name = NULL;
char *mode = "r"; char *mode = "r";
char *s; char *s;
...@@ -131,6 +131,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -131,6 +131,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
int ret = 0; int ret = 0;
int rwa = 0, plus = 0, append = 0; int rwa = 0, plus = 0, append = 0;
int flags = 0; int flags = 0;
int fd = -1;
assert(PyFileIO_Check(oself)); assert(PyFileIO_Check(oself));
if (self->fd >= 0) if (self->fd >= 0)
...@@ -142,8 +143,20 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -142,8 +143,20 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
Py_DECREF(closeresult); Py_DECREF(closeresult);
} }
if (PyArg_ParseTupleAndKeywords(args, kwds, "i|s:fileio",
kwlist, &fd, &mode)) {
if (fd < 0) {
PyErr_SetString(PyExc_ValueError,
"Negative filedescriptor");
return -1;
}
}
else {
PyErr_Clear();
#ifdef Py_WIN_WIDE_FILENAMES #ifdef Py_WIN_WIDE_FILENAMES
if (GetVersion() < 0x80000000) { /* On NT, so wide API available */ if (GetVersion() < 0x80000000) {
/* On NT, so wide API available */
PyObject *po; PyObject *po;
if (PyArg_ParseTupleAndKeywords(args, kwds, "U|s:fileio", if (PyArg_ParseTupleAndKeywords(args, kwds, "U|s:fileio",
kwlist, &po, &mode)) { kwlist, &po, &mode)) {
...@@ -167,6 +180,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -167,6 +180,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
&name, &mode)) &name, &mode))
goto error; goto error;
} }
}
self->readable = self->writable = 0; self->readable = self->writable = 0;
s = mode; s = mode;
...@@ -224,6 +238,11 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -224,6 +238,11 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
flags |= O_BINARY; flags |= O_BINARY;
#endif #endif
if (fd >= 0) {
self->fd = fd;
/* XXX Should we set self->own_fd = 0 ??? */
}
else {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
errno = 0; errno = 0;
self->fd = open(name, flags, 0666); self->fd = open(name, flags, 0666);
...@@ -232,6 +251,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -232,6 +251,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
goto error; goto error;
} }
}
goto done; goto done;
...@@ -652,6 +672,18 @@ static PyMethodDef fileio_methods[] = { ...@@ -652,6 +672,18 @@ static PyMethodDef fileio_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
/* 'closed' is an attribute for backwards compatibility reasons. */
static PyObject *
get_closed(PyFileIOObject *f, void *closure)
{
return PyBool_FromLong((long)(f->fd < 0));
}
static PyGetSetDef fileio_getsetlist[] = {
{"closed", (getter)get_closed, NULL, "True if the file is closed"},
{0},
};
PyTypeObject PyFileIO_Type = { PyTypeObject PyFileIO_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
...@@ -683,7 +715,7 @@ PyTypeObject PyFileIO_Type = { ...@@ -683,7 +715,7 @@ PyTypeObject PyFileIO_Type = {
0, /* tp_iternext */ 0, /* tp_iternext */
fileio_methods, /* tp_methods */ fileio_methods, /* tp_methods */
0, /* tp_members */ 0, /* tp_members */
0, /* tp_getset */ fileio_getsetlist, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */
0, /* tp_dict */ 0, /* tp_dict */
0, /* tp_descr_get */ 0, /* tp_descr_get */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment