Skip to content

Commit 2b0bee2

Browse files
committed
implement long path fallback for stat() when statx isn't available
1 parent 923ac9f commit 2b0bee2

File tree

1 file changed

+14
-2
lines changed
  • library/std/src/sys/unix

1 file changed

+14
-2
lines changed

library/std/src/sys/unix/fs.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,13 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
17011701
})
17021702
}
17031703

1704+
// On linux this is the default behavior for lstat and stat but it has to be set explicitly for fstatat
1705+
#[cfg(any(target_os = "linux", target_os = "android"))]
1706+
const DEFAULT_STATAT_FLAGS: c_int = libc::AT_NO_AUTOMOUNT;
1707+
1708+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
1709+
const DEFAULT_STATAT_FLAGS: c_int = 0;
1710+
17041711
pub fn stat(path: &Path) -> io::Result<FileAttr> {
17051712
run_path_with_cstr(path, |p| {
17061713
cfg_has_statx! {
@@ -1716,7 +1723,12 @@ pub fn stat(path: &Path) -> io::Result<FileAttr> {
17161723
}
17171724

17181725
let mut stat: stat64 = unsafe { mem::zeroed() };
1719-
cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?;
1726+
let result = cvt(unsafe { stat64(p.as_ptr(), &mut stat) });
1727+
long_filename_fallback!(path, result, |dirfd, file_name| {
1728+
cvt(unsafe {
1729+
fstatat64(dirfd.as_raw_fd(), file_name.as_ptr(), &mut stat, DEFAULT_STATAT_FLAGS)
1730+
})
1731+
})?;
17201732
Ok(FileAttr::from_stat64(stat))
17211733
})
17221734
}
@@ -1743,7 +1755,7 @@ pub fn lstat(path: &Path) -> io::Result<FileAttr> {
17431755
dirfd.as_raw_fd(),
17441756
file_name.as_ptr(),
17451757
&mut stat,
1746-
libc::AT_SYMLINK_NOFOLLOW,
1758+
DEFAULT_STATAT_FLAGS | libc::AT_SYMLINK_NOFOLLOW,
17471759
)
17481760
})
17491761
})?;

0 commit comments

Comments
 (0)