diff options
author | Georg Brandl <georg@python.org> | 2008-01-19 20:22:13 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2008-01-19 20:22:13 (GMT) |
commit | 309501a61772f4cb72f1004fcbe73964b4130672 (patch) | |
tree | 8737924e043d901d7c62910a97c6aebdd8e62f8e | |
parent | 15ce880cc8c3de29e91e2e867b2db0b19a48e5f3 (diff) | |
download | cpython-309501a61772f4cb72f1004fcbe73964b4130672.zip cpython-309501a61772f4cb72f1004fcbe73964b4130672.tar.gz cpython-309501a61772f4cb72f1004fcbe73964b4130672.tar.bz2 |
#1663329: add os.closerange() to close a range of fds,
ignoring errors, and use this in subprocess to speed up
subprocess creation in close_fds mode. Patch by Mike Klaas.
-rw-r--r-- | Doc/library/os.rst | 14 | ||||
-rw-r--r-- | Lib/subprocess.py | 9 | ||||
-rw-r--r-- | Lib/test/test_os.py | 6 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/posixmodule.c | 19 |
5 files changed, 44 insertions, 7 deletions
diff --git a/Doc/library/os.rst b/Doc/library/os.rst index b39ec1b..ff37d10 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -481,6 +481,20 @@ by file descriptors. :func:`fdopen`, use its :meth:`close` method. +.. function:: closerange(fd_low, fd_high) + + Close all file descriptors from *fd_low* (inclusive) to *fd_high* (exclusive), + ignoring errors. Availability: Macintosh, Unix, Windows. Equivalent to:: + + for fd in xrange(fd_low, fd_high): + try: + os.close(fd) + except OSError: + pass + + .. versionadded:: 2.6 + + .. function:: dup(fd) Return a duplicate of file descriptor *fd*. Availability: Macintosh, Unix, diff --git a/Lib/subprocess.py b/Lib/subprocess.py index ca9489e..29c25bc 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -965,13 +965,8 @@ class Popen(object): def _close_fds(self, but): - for i in xrange(3, MAXFD): - if i == but: - continue - try: - os.close(i) - except: - pass + os.closerange(3, but) + os.closerange(but + 1, MAXFD) def _execute_child(self, args, executable, preexec_fn, close_fds, diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 52fdd8a..a6fe40e 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -23,6 +23,12 @@ class FileTests(unittest.TestCase): os.close(f) self.assert_(os.access(test_support.TESTFN, os.W_OK)) + def test_closerange(self): + f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR) + # close a fd that is open, and one that isn't + os.closerange(f, f+2) + self.assertRaises(OSError, os.write, f, "a") + class TemporaryFileTests(unittest.TestCase): def setUp(self): @@ -1019,6 +1019,9 @@ Library Extension Modules ----------------- +- Patch #1663329: added ``os.closerange()`` function to quickly close a range + of file descriptors without considering errors. + - Patch 976880: ``mmap`` objects now have an ``rfind`` method that works as expected. ``mmap.find`` also takes an optional ``end`` parameter. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 696df0d..0038703 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6156,6 +6156,24 @@ posix_close(PyObject *self, PyObject *args) } +PyDoc_STRVAR(posix_closerange__doc__, +"closerange(fd_low, fd_high)\n\n\ +Closes all file descriptors in [fd_low, fd_high), ignoring errors."); + +static PyObject * +posix_closerange(PyObject *self, PyObject *args) +{ + int fd_from, fd_to, i; + if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) + return NULL; + Py_BEGIN_ALLOW_THREADS + for (i = fd_from; i < fd_to; i++) + close(i); + Py_END_ALLOW_THREADS + Py_RETURN_NONE; +} + + PyDoc_STRVAR(posix_dup__doc__, "dup(fd) -> fd2\n\n\ Return a duplicate of a file descriptor."); @@ -8451,6 +8469,7 @@ static PyMethodDef posix_methods[] = { #endif /* HAVE_TCSETPGRP */ {"open", posix_open, METH_VARARGS, posix_open__doc__}, {"close", posix_close, METH_VARARGS, posix_close__doc__}, + {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, |