#14773: Fix os.fwalk() failing on dangling symlinks
This commit is contained in:
parent
0fb41b56ea
commit
66bfcc1b0f
24
Lib/os.py
24
Lib/os.py
|
@ -353,13 +353,23 @@ if _exists("openat"):
|
|||
names = flistdir(topfd)
|
||||
dirs, nondirs = [], []
|
||||
for name in names:
|
||||
# Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
|
||||
# walk() which reports symlinks to directories as directories. We do
|
||||
# however check for symlinks before recursing into a subdirectory.
|
||||
if st.S_ISDIR(fstatat(topfd, name).st_mode):
|
||||
dirs.append(name)
|
||||
else:
|
||||
nondirs.append(name)
|
||||
try:
|
||||
# Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
|
||||
# walk() which reports symlinks to directories as directories.
|
||||
# We do however check for symlinks before recursing into
|
||||
# a subdirectory.
|
||||
if st.S_ISDIR(fstatat(topfd, name).st_mode):
|
||||
dirs.append(name)
|
||||
else:
|
||||
nondirs.append(name)
|
||||
except FileNotFoundError:
|
||||
try:
|
||||
# Add dangling symlinks, ignore disappeared files
|
||||
if st.S_ISLNK(fstatat(topfd, name, AT_SYMLINK_NOFOLLOW)
|
||||
.st_mode):
|
||||
nondirs.append(name)
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
|
||||
if topdown:
|
||||
yield toppath, dirs, nondirs, topfd
|
||||
|
|
|
@ -651,6 +651,7 @@ class WalkTests(unittest.TestCase):
|
|||
# SUB2/ a file kid and a dirsymlink kid
|
||||
# tmp3
|
||||
# link/ a symlink to TESTFN.2
|
||||
# broken_link
|
||||
# TEST2/
|
||||
# tmp4 a lone file
|
||||
walk_path = join(support.TESTFN, "TEST1")
|
||||
|
@ -663,6 +664,8 @@ class WalkTests(unittest.TestCase):
|
|||
link_path = join(sub2_path, "link")
|
||||
t2_path = join(support.TESTFN, "TEST2")
|
||||
tmp4_path = join(support.TESTFN, "TEST2", "tmp4")
|
||||
link_path = join(sub2_path, "link")
|
||||
broken_link_path = join(sub2_path, "broken_link")
|
||||
|
||||
# Create stuff.
|
||||
os.makedirs(sub11_path)
|
||||
|
@ -679,7 +682,8 @@ class WalkTests(unittest.TestCase):
|
|||
else:
|
||||
symlink_to_dir = os.symlink
|
||||
symlink_to_dir(os.path.abspath(t2_path), link_path)
|
||||
sub2_tree = (sub2_path, ["link"], ["tmp3"])
|
||||
symlink_to_dir('broken', broken_link_path)
|
||||
sub2_tree = (sub2_path, ["link"], ["broken_link", "tmp3"])
|
||||
else:
|
||||
sub2_tree = (sub2_path, [], ["tmp3"])
|
||||
|
||||
|
|
Loading…
Reference in New Issue