Issue #10755: Add the posix.fdlistdir() function. Patch by Ross Lagerwall.

This commit is contained in:
Antoine Pitrou 2011-02-25 23:41:16 +00:00
parent f65132de3d
commit 8250e23abd
7 changed files with 108 additions and 5 deletions

View File

@ -733,6 +733,16 @@ as internal buffering of data.
This function is not available on MacOS. This function is not available on MacOS.
.. function:: fdlistdir(fd)
Like :func:`listdir`, but uses a file descriptor instead and always returns
strings. After execution of this function, *fd* will be closed.
Availability: Unix.
.. versionadded:: 3.3
.. function:: fpathconf(fd, name) .. function:: fpathconf(fd, name)
Return system configuration information relevant to an open file. *name* Return system configuration information relevant to an open file. *name*

View File

@ -285,6 +285,18 @@ class PosixTester(unittest.TestCase):
if hasattr(posix, 'listdir'): if hasattr(posix, 'listdir'):
self.assertTrue(support.TESTFN in posix.listdir()) self.assertTrue(support.TESTFN in posix.listdir())
@unittest.skipUnless(hasattr(posix, 'fdlistdir'), "test needs posix.fdlistdir()")
def test_fdlistdir(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
self.assertEqual(
sorted(posix.listdir('.')),
sorted(posix.fdlistdir(f))
)
# Check the fd was closed by fdlistdir
with self.assertRaises(OSError) as ctx:
posix.close(f)
self.assertEqual(ctx.exception.errno, errno.EBADF)
def test_access(self): def test_access(self):
if hasattr(posix, 'access'): if hasattr(posix, 'access'):
self.assertTrue(posix.access(support.TESTFN, os.R_OK)) self.assertTrue(posix.access(support.TESTFN, os.R_OK))

View File

@ -35,6 +35,8 @@ Core and Builtins
Library Library
------- -------
- Issue #10755: Add the posix.fdlistdir() function. Patch by Ross Lagerwall.
- Issue #4761: Add the *at() family of functions (openat(), etc.) to the posix - Issue #4761: Add the *at() family of functions (openat(), etc.) to the posix
module. Patch by Ross Lagerwall. module. Patch by Ross Lagerwall.

View File

@ -2678,6 +2678,76 @@ posix_listdir(PyObject *self, PyObject *args)
#endif /* which OS */ #endif /* which OS */
} /* end of posix_listdir */ } /* end of posix_listdir */
#ifdef HAVE_FDOPENDIR
PyDoc_STRVAR(posix_fdlistdir__doc__,
"fdlistdir(fd) -> list_of_strings\n\n\
Like listdir(), but uses a file descriptor instead.\n\
After succesful execution of this function, fd will be closed.");
static PyObject *
posix_fdlistdir(PyObject *self, PyObject *args)
{
PyObject *d, *v;
DIR *dirp;
struct dirent *ep;
int fd;
errno = 0;
if (!PyArg_ParseTuple(args, "i:fdlistdir", &fd))
return NULL;
Py_BEGIN_ALLOW_THREADS
dirp = fdopendir(fd);
Py_END_ALLOW_THREADS
if (dirp == NULL) {
close(fd);
return posix_error();
}
if ((d = PyList_New(0)) == NULL) {
Py_BEGIN_ALLOW_THREADS
closedir(dirp);
Py_END_ALLOW_THREADS
return NULL;
}
for (;;) {
errno = 0;
Py_BEGIN_ALLOW_THREADS
ep = readdir(dirp);
Py_END_ALLOW_THREADS
if (ep == NULL) {
if (errno == 0) {
break;
} else {
Py_BEGIN_ALLOW_THREADS
closedir(dirp);
Py_END_ALLOW_THREADS
Py_DECREF(d);
return posix_error();
}
}
if (ep->d_name[0] == '.' &&
(NAMLEN(ep) == 1 ||
(ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
continue;
v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
if (v == NULL) {
Py_CLEAR(d);
break;
}
if (PyList_Append(d, v) != 0) {
Py_DECREF(v);
Py_CLEAR(d);
break;
}
Py_DECREF(v);
}
Py_BEGIN_ALLOW_THREADS
closedir(dirp);
Py_END_ALLOW_THREADS
return d;
}
#endif
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
/* A helper function for abspath on win32 */ /* A helper function for abspath on win32 */
static PyObject * static PyObject *
@ -8599,6 +8669,9 @@ static PyMethodDef posix_methods[] = {
{"link", posix_link, METH_VARARGS, posix_link__doc__}, {"link", posix_link, METH_VARARGS, posix_link__doc__},
#endif /* HAVE_LINK */ #endif /* HAVE_LINK */
{"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__}, {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
#ifdef HAVE_FDOPENDIR
{"fdlistdir", posix_fdlistdir, METH_VARARGS, posix_fdlistdir__doc__},
#endif
{"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
{"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
#ifdef HAVE_NICE #ifdef HAVE_NICE

6
configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh #! /bin/sh
# From configure.in Revision: 88608 . # From configure.in Revision: 88624 .
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 3.3. # Generated by GNU Autoconf 2.65 for python 3.3.
# #
@ -9311,8 +9311,8 @@ $as_echo "MACHDEP_OBJS" >&6; }
# checks for library functions # checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat fork \ clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \
fpathconf fstatat ftime ftruncate futimesat \ fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
initgroups kill killpg lchmod lchown linkat lstat mbrtowc mkdirat mkfifo \ initgroups kill killpg lchmod lchown linkat lstat mbrtowc mkdirat mkfifo \

View File

@ -2534,8 +2534,8 @@ AC_MSG_RESULT(MACHDEP_OBJS)
# checks for library functions # checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat fork \ clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \
fpathconf fstatat ftime ftruncate futimesat \ fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
initgroups kill killpg lchmod lchown linkat lstat mbrtowc mkdirat mkfifo \ initgroups kill killpg lchmod lchown linkat lstat mbrtowc mkdirat mkfifo \

View File

@ -229,6 +229,9 @@
/* Define if you have the 'fdatasync' function. */ /* Define if you have the 'fdatasync' function. */
#undef HAVE_FDATASYNC #undef HAVE_FDATASYNC
/* Define to 1 if you have the `fdopendir' function. */
#undef HAVE_FDOPENDIR
/* Define to 1 if you have the `finite' function. */ /* Define to 1 if you have the `finite' function. */
#undef HAVE_FINITE #undef HAVE_FINITE
@ -533,6 +536,9 @@
/* Define if the OS supports pipe2() */ /* Define if the OS supports pipe2() */
#undef HAVE_PIPE2 #undef HAVE_PIPE2
/* Define if the OS supports pipe2() */
#undef HAVE_PIPE2
/* Define to 1 if you have the `plock' function. */ /* Define to 1 if you have the `plock' function. */
#undef HAVE_PLOCK #undef HAVE_PLOCK