mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #15177: Added dir_fd parameter to os.fwalk().
This commit is contained in:
parent
2a193a818a
commit
c48fe98a7c
4 changed files with 42 additions and 14 deletions
18
Lib/os.py
18
Lib/os.py
|
@ -422,9 +422,9 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
|
|||
|
||||
__all__.append("walk")
|
||||
|
||||
if open in supports_dir_fd:
|
||||
if {open, stat} <= supports_dir_fd and {listdir, stat} <= supports_fd:
|
||||
|
||||
def fwalk(top, topdown=True, onerror=None, followlinks=False):
|
||||
def fwalk(top=".", topdown=True, onerror=None, followlinks=False, *, dir_fd=None):
|
||||
"""Directory tree generator.
|
||||
|
||||
This behaves exactly like walk(), except that it yields a 4-tuple
|
||||
|
@ -434,9 +434,13 @@ if open in supports_dir_fd:
|
|||
`dirpath`, `dirnames` and `filenames` are identical to walk() output,
|
||||
and `dirfd` is a file descriptor referring to the directory `dirpath`.
|
||||
|
||||
The advantage of walkfd() over walk() is that it's safe against symlink
|
||||
The advantage of fwalk() over walk() is that it's safe against symlink
|
||||
races (when followlinks is False).
|
||||
|
||||
If dir_fd is not None, it should be a file descriptor open to a directory,
|
||||
and top should be relative; top will then be relative to that directory.
|
||||
(dir_fd is always supported for fwalk.)
|
||||
|
||||
Caution:
|
||||
Since fwalk() yields file descriptors, those are only valid until the
|
||||
next iteration step, so you should dup() them if you want to keep them
|
||||
|
@ -455,11 +459,11 @@ if open in supports_dir_fd:
|
|||
"""
|
||||
# Note: To guard against symlink races, we use the standard
|
||||
# lstat()/open()/fstat() trick.
|
||||
orig_st = lstat(top)
|
||||
topfd = open(top, O_RDONLY)
|
||||
orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
|
||||
topfd = open(top, O_RDONLY, dir_fd=dir_fd)
|
||||
try:
|
||||
if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
|
||||
path.samestat(orig_st, fstat(topfd)))):
|
||||
path.samestat(orig_st, stat(topfd)))):
|
||||
yield from _fwalk(topfd, top, topdown, onerror, followlinks)
|
||||
finally:
|
||||
close(topfd)
|
||||
|
@ -502,7 +506,7 @@ if open in supports_dir_fd:
|
|||
onerror(err)
|
||||
return
|
||||
try:
|
||||
if followlinks or path.samestat(orig_st, fstat(dirfd)):
|
||||
if followlinks or path.samestat(orig_st, stat(dirfd)):
|
||||
dirpath = path.join(toppath, name)
|
||||
yield from _fwalk(dirfd, dirpath, topdown, onerror, followlinks)
|
||||
finally:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue