diff options
author | Jason Francis <zxzax@protonmail.com> | 2021-05-11 12:16:06 -0400 |
---|---|---|
committer | Jason Francis <zxzax@protonmail.com> | 2021-05-23 10:35:24 -0400 |
commit | 41fa8e2a26fb053820730f524e78810a6f1c6173 (patch) | |
tree | ae009d0287404abaf3e1bca9a290781ffbeaf4bb /src/fcntl.rs | |
parent | 86dde6c33d4a923013f61406587c8ddf9c50b248 (diff) | |
download | nix-41fa8e2a26fb053820730f524e78810a6f1c6173.zip |
Use fstatat to check long path sizes in fcntl::readlinkat
Diffstat (limited to 'src/fcntl.rs')
-rw-r--r-- | src/fcntl.rs | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs index 9da7d33f..2532724b 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -252,7 +252,18 @@ fn inner_readlink<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P) -> Result } // Uh oh, the result is too long... // Let's try to ask lstat how many bytes to allocate. - let reported_size = super::sys::stat::lstat(path) + let reported_size = match dirfd { + #[cfg(target_os = "redox")] + Some(_) => unreachable!(), + #[cfg(any(target_os = "android", target_os = "linux"))] + Some(dirfd) => { + let flags = if path.is_empty() { AtFlags::AT_EMPTY_PATH } else { AtFlags::empty() }; + super::sys::stat::fstatat(dirfd, path, flags | AtFlags::AT_SYMLINK_NOFOLLOW) + }, + #[cfg(not(any(target_os = "android", target_os = "linux", target_os = "redox")))] + Some(dirfd) => super::sys::stat::fstatat(dirfd, path, AtFlags::AT_SYMLINK_NOFOLLOW), + None => super::sys::stat::lstat(path) + } .and_then(|x| Ok(x.st_size)) .unwrap_or(0); let mut try_size = if reported_size > 0 { |