diff --git Doc/library/os.rst Doc/library/os.rst index 43d029a..bfc89f0 100644 --- Doc/library/os.rst +++ Doc/library/os.rst @@ -513,6 +513,9 @@ process will then be assigned 3, 4, 5, and so forth. The name "file descriptor" is slightly deceptive; on Unix platforms, sockets and pipes are also referenced by file descriptors. +For these functions, the file descriptor can either be an integer, or an object +with a fileno() method which returns the actual file descriptor. + .. function:: close(fd) @@ -629,7 +632,6 @@ by file descriptors. Return ``True`` if the file descriptor *fd* is open and connected to a tty(-like) device, else ``False``. Availability: Unix. - .. function:: lseek(fd, pos, how) Set the current position of file descriptor *fd* to position *pos*, modified @@ -638,7 +640,6 @@ by file descriptors. current position; :const:`os.SEEK_END` or ``2`` to set it relative to the end of the file. Availability: Unix, Windows. - .. function:: open(file, flags[, mode]) Open the file *file* and set various flags according to *flags* and possibly its @@ -694,7 +695,6 @@ by file descriptors. Return the process group associated with the terminal given by *fd* (an open file descriptor as returned by :func:`os.open`). Availability: Unix. - .. function:: tcsetpgrp(fd, pg) Set the process group associated with the terminal given by *fd* (an open file diff --git Lib/test/test_posix.py Lib/test/test_posix.py index afeb616..cf92815 100644 --- Lib/test/test_posix.py +++ Lib/test/test_posix.py @@ -114,6 +114,7 @@ class PosixTester(unittest.TestCase): fp = open(test_support.TESTFN) try: self.assertTrue(posix.fstatvfs(fp.fileno())) + self.assertTrue(posix.fstatvfs(fp)) finally: fp.close() @@ -127,6 +128,14 @@ class PosixTester(unittest.TestCase): posix.ftruncate(fp.fileno(), 0) finally: fp.close() + fp = open(test_support.TESTFN, 'w+') + try: + fp.write('test') + fp.flush() + posix.ftruncate(fp, 0) + finally: + fp.close() + def test_dup(self): if hasattr(posix, 'dup'): @@ -137,6 +146,14 @@ class PosixTester(unittest.TestCase): os.close(fd) finally: fp.close() + fp = open(test_support.TESTFN) + try: + fd = posix.dup(fp) + self.assert_(isinstance(fd, int)) + os.close(fd) + finally: + fp.close() + def test_confstr(self): if hasattr(posix, 'confstr'): @@ -200,6 +217,7 @@ class PosixTester(unittest.TestCase): fp = open(test_support.TESTFN) try: self.assertTrue(posix.fstat(fp.fileno())) + self.assertTrue(posix.fstat(fp)) finally: fp.close() diff --git Modules/posixmodule.c Modules/posixmodule.c index 8fb7aaa..1c5f34e 100644 --- Modules/posixmodule.c +++ Modules/posixmodule.c @@ -1743,9 +1743,13 @@ descriptor fd."); static PyObject * posix_fchmod(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd, mode, res; - if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode)) + if (!PyArg_ParseTuple(args, "Oi:fchmod", &fdobj, &mode)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ Py_BEGIN_ALLOW_THREADS res = fchmod(fd, mode); Py_END_ALLOW_THREADS @@ -1910,11 +1914,15 @@ fd to the numeric uid and gid."); static PyObject * posix_fchown(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd; long uid, gid; int res; - if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "Oll:chown", &fdobj, &uid, &gid)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); Py_END_ALLOW_THREADS @@ -6225,10 +6233,14 @@ Return the process group associated with the terminal given by a fd."); static PyObject * posix_tcgetpgrp(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd; pid_t pgid; - if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) + if (!PyArg_ParseTuple(args, "O:tcgetpgrp", &fdobj)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ pgid = tcgetpgrp(fd); if (pgid < 0) return posix_error(); @@ -6245,10 +6257,14 @@ Set the process group associated with the terminal given by a fd."); static PyObject * posix_tcsetpgrp(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd; pid_t pgid; - if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid)) + if (!PyArg_ParseTuple(args, "O" PARSE_PID ":tcsetpgrp", &fdobj, &pgid)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ if (tcsetpgrp(fd, pgid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -6309,9 +6325,12 @@ Close a file descriptor (for low level IO)."); static PyObject * posix_close(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd, res; - if (!PyArg_ParseTuple(args, "i:close", &fd)) + if (!PyArg_ParseTuple(args, "O:close", &fdobj)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + /* Rely on PyVerify to detect error cases */ if (!_PyVerify_fd(fd)) return posix_error(); Py_BEGIN_ALLOW_THREADS @@ -6350,9 +6369,12 @@ Return a duplicate of a file descriptor."); static PyObject * posix_dup(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd; - if (!PyArg_ParseTuple(args, "i:dup", &fd)) + if (!PyArg_ParseTuple(args, "O:dup", &fdobj)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + /* Rely on PyVerify to detect error cases */ if (!_PyVerify_fd(fd)) return posix_error(); Py_BEGIN_ALLOW_THREADS @@ -6371,9 +6393,12 @@ Duplicate file descriptor."); static PyObject * posix_dup2(PyObject *self, PyObject *args) { + PyObject *fdobj1, *fdobj2; int fd, fd2, res; - if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) + if (!PyArg_ParseTuple(args, "OO:dup2", &fdobj1, &fdobj2)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj1); + fd2 = PyObject_AsFileDescriptor(fdobj2); if (!_PyVerify_fd_dup2(fd, fd2)) return posix_error(); Py_BEGIN_ALLOW_THREADS @@ -6399,9 +6424,13 @@ posix_lseek(PyObject *self, PyObject *args) #else off_t pos, res; #endif + PyObject *fdobj; PyObject *posobj; - if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) + if (!PyArg_ParseTuple(args, "OOi:lseek", &fdobj, &posobj, &how)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ #ifdef SEEK_SET /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ switch (how) { @@ -6447,10 +6476,14 @@ Read a file descriptor."); static PyObject * posix_read(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd, size, n; PyObject *buffer; - if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) + if (!PyArg_ParseTuple(args, "Oi:read", &fdobj, &size)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ if (size < 0) { errno = EINVAL; return posix_error(); @@ -6480,12 +6513,15 @@ Write a string to a file descriptor."); static PyObject * posix_write(PyObject *self, PyObject *args) { + PyObject *fdobj; Py_buffer pbuf; int fd; Py_ssize_t size; - if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf)) + if (!PyArg_ParseTuple(args, "Os*:write", &fdobj, &pbuf)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + /* Rely on PyVerify to detect error cases */ if (!_PyVerify_fd(fd)) return posix_error(); Py_BEGIN_ALLOW_THREADS @@ -6505,11 +6541,15 @@ Like stat(), but for an open file descriptor."); static PyObject * posix_fstat(PyObject *self, PyObject *args) { - int fd; + PyObject *fdobj; STRUCT_STAT st; int res; - if (!PyArg_ParseTuple(args, "i:fstat", &fd)) + int fd; + if (!PyArg_ParseTuple(args, "O:fstat", &fdobj)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ #ifdef __VMS /* on OpenVMS we must ensure that all bytes are written to the file */ fsync(fd); @@ -6538,14 +6578,18 @@ Return an open file object connected to a file descriptor."); static PyObject * posix_fdopen(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd; char *orgmode = "r"; int bufsize = -1; FILE *fp; PyObject *f; char *mode; - if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize)) + if (!PyArg_ParseTuple(args, "O|si", &fdobj, &orgmode, &bufsize)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ /* Sanitize mode. See fileobject.c */ mode = PyMem_MALLOC(strlen(orgmode)+3); @@ -6596,9 +6640,12 @@ connected to the slave end of a terminal."); static PyObject * posix_isatty(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd; - if (!PyArg_ParseTuple(args, "i:isatty", &fd)) + if (!PyArg_ParseTuple(args, "O:isatty", &fdobj)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + /* Rely on PyVerify to detect error cases */ if (!_PyVerify_fd(fd)) return PyBool_FromLong(0); return PyBool_FromLong(isatty(fd)); @@ -6755,13 +6802,17 @@ Truncate a file to a specified length."); static PyObject * posix_ftruncate(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd; off_t length; int res; PyObject *lenobj; - if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj)) + if (!PyArg_ParseTuple(args, "OO:ftruncate", &fdobj, &lenobj)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ #if !defined(HAVE_LARGEFILE_SUPPORT) length = PyInt_AsLong(lenobj); @@ -7113,11 +7164,15 @@ Perform an fstatvfs system call on the given fd."); static PyObject * posix_fstatvfs(PyObject *self, PyObject *args) { + PyObject *fdobj; int fd, res; struct statvfs st; - if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) + if (!PyArg_ParseTuple(args, "O:fstatvfs", &fdobj)) return NULL; + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ Py_BEGIN_ALLOW_THREADS res = fstatvfs(fd, &st); Py_END_ALLOW_THREADS @@ -7372,10 +7427,15 @@ static PyObject * posix_fpathconf(PyObject *self, PyObject *args) { PyObject *result = NULL; + PyObject *fdobj; int name, fd; - if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, + if (PyArg_ParseTuple(args, "OO&:fpathconf", &fdobj, conv_path_confname, &name)) { + + fd = PyObject_AsFileDescriptor(fdobj); + if (fd == -1) + return NULL; /* Rely on AsFileDescriptor's error handling */ long limit; errno = 0;