Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r86392:43568988afe8 Date: 2016-08-22 10:05 +0200 http://bitbucket.org/pypy/pypy/changeset/43568988afe8/
Log: Test and fix for rposix.fdopendir() diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -620,6 +620,8 @@ [rffi.CCHARP], DIRP, save_err=rffi.RFFI_SAVE_ERRNO) c_fdopendir = external('fdopendir', [rffi.INT], DIRP, save_err=rffi.RFFI_SAVE_ERRNO) + c_rewinddir = external('rewinddir', + [DIRP], lltype.Void, releasegil=False) # XXX macro=True is hack to make sure we get the correct kind of # dirent struct (which depends on defines) c_readdir = external('readdir', [DIRP], DIRENTP, @@ -629,7 +631,7 @@ else: dirent_config = {} -def _listdir(dirp): +def _listdir(dirp, rewind=False): result = [] while True: direntp = c_readdir(dirp) @@ -640,6 +642,8 @@ name = rffi.charp2str(namep) if name != '.' and name != '..': result.append(name) + if rewind: + c_rewinddir(dirp) c_closedir(dirp) if error: raise OSError(error, "readdir failed") @@ -650,12 +654,16 @@ Like listdir(), except that the directory is specified as an open file descriptor. - Note: fdlistdir() closes the file descriptor. + Note: fdlistdir() closes the file descriptor. To emulate the + Python 3.x 'os.opendir(dirfd)', you must first duplicate the + file descriptor. """ dirp = c_fdopendir(dirfd) if not dirp: - raise OSError(get_saved_errno(), "opendir failed") - return _listdir(dirp) + error = get_saved_errno() + c_close(dirfd) + raise OSError(error, "opendir failed") + return _listdir(dirp, rewind=True) @replace_os_function('listdir') @specialize.argtype(0) @@ -1799,7 +1807,7 @@ 'fcntl.h'], ) for _name in """faccessat fchdir fchmod fchmodat fchown fchownat fexecve - fdopendir fpathconf fstat fstatat fstatvfs ftruncate + fpathconf fstat fstatat fstatvfs ftruncate futimens futimes futimesat linkat chflags lchflags lchmod lchown lstat lutimes mkdirat mkfifoat mknodat openat readlinkat renameat symlinkat unlinkat utimensat""".split(): diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -552,6 +552,14 @@ # Note: fdlistdir() always closes dirfd assert result == ['file'] +@rposix_requires('fdlistdir') +def test_fdlistdir_rewinddir(tmpdir): + tmpdir.join('file').write('text') + dirfd = os.open(str(tmpdir), os.O_RDONLY) + result1 = rposix.fdlistdir(os.dup(dirfd)) + result2 = rposix.fdlistdir(dirfd) + assert result1 == result2 == ['file'] + @rposix_requires('symlinkat') def test_symlinkat(tmpdir): tmpdir.join('file').write('text') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit