diff --git a/changelog/2267.added.md b/changelog/2267.added.md new file mode 100644 index 0000000000..0a09558511 --- /dev/null +++ b/changelog/2267.added.md @@ -0,0 +1 @@ +Enable the `AT_EMPTY_PATH` flag for the `fchownat()` function diff --git a/changelog/2267.removed.md b/changelog/2267.removed.md new file mode 100644 index 0000000000..bedb77fd20 --- /dev/null +++ b/changelog/2267.removed.md @@ -0,0 +1 @@ +The `FchownatFlags` type has been deprecated, please use `AtFlags` instead. diff --git a/src/fcntl.rs b/src/fcntl.rs index 8ede0777b3..638d6f6ea6 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -43,7 +43,7 @@ use crate::{sys::stat::Mode, NixPath, Result}; pub use self::posix_fadvise::{posix_fadvise, PosixFadviseAdvice}; #[cfg(not(target_os = "redox"))] -#[cfg(any(feature = "fs", feature = "process"))] +#[cfg(any(feature = "fs", feature = "process", feature = "user"))] libc_bitflags! { #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "process"))))] pub struct AtFlags: c_int { diff --git a/src/unistd.rs b/src/unistd.rs index 92840f7e8b..a7f784eae4 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -737,11 +737,17 @@ pub fn fchown(fd: RawFd, owner: Option, group: Option) -> Result<()> { Errno::result(res).map(drop) } -/// Flags for `fchownat` function. -#[derive(Clone, Copy, Debug)] -pub enum FchownatFlags { - FollowSymlink, - NoFollowSymlink, +// Just a wrapper around `AtFlags` so that we can help our users migrate. +#[cfg(not(target_os = "redox"))] +pub type FchownatFlags = AtFlags; +#[cfg(not(target_os = "redox"))] +impl FchownatFlags { + #[deprecated(since = "0.28.0", note = "The variant is deprecated, please use `AtFlags` instead")] + #[allow(non_upper_case_globals)] + pub const FollowSymlink: FchownatFlags = FchownatFlags::empty(); + #[deprecated(since = "0.28.0", note = "The variant is deprecated, please use `AtFlags` instead")] + #[allow(non_upper_case_globals)] + pub const NoFollowSymlink: FchownatFlags = FchownatFlags::AT_SYMLINK_NOFOLLOW; } /// Change the ownership of the file at `path` to be owned by the specified @@ -755,10 +761,10 @@ pub enum FchownatFlags { /// with the file descriptor `dirfd` or the current working directory /// if `dirfd` is `None`. /// -/// If `flag` is `FchownatFlags::NoFollowSymlink` and `path` names a symbolic link, +/// If `flag` is `AtFlags::AT_SYMLINK_NOFOLLOW` and `path` names a symbolic link, /// then the mode of the symbolic link is changed. /// -/// `fchownat(None, path, owner, group, FchownatFlags::NoFollowSymlink)` is identical to +/// `fchownat(None, path, owner, group, AtFlags::AT_SYMLINK_NOFOLLOW)` is identical to /// a call `libc::lchown(path, owner, group)`. That's why `lchown` is unimplemented in /// the `nix` crate. /// @@ -771,12 +777,8 @@ pub fn fchownat( path: &P, owner: Option, group: Option, - flag: FchownatFlags, + flag: AtFlags, ) -> Result<()> { - let atflag = match flag { - FchownatFlags::FollowSymlink => AtFlags::empty(), - FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, - }; let res = path.with_nix_path(|cstr| unsafe { let (uid, gid) = chown_raw_ids(owner, group); libc::fchownat( @@ -784,7 +786,7 @@ pub fn fchownat( cstr.as_ptr(), uid, gid, - atflag.bits() as libc::c_int, + flag.bits() ) })?; diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 354f816362..b156951e93 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -551,6 +551,8 @@ fn test_fchown() { #[test] #[cfg(not(target_os = "redox"))] fn test_fchownat() { + use nix::fcntl::AtFlags; + let _dr = crate::DirRestore::new(); // Testing for anything other than our own UID/GID is hard. let uid = Some(getuid()); @@ -564,14 +566,13 @@ fn test_fchownat() { let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); - fchownat(Some(dirfd), "file", uid, gid, FchownatFlags::FollowSymlink) - .unwrap(); + fchownat(Some(dirfd), "file", uid, gid, AtFlags::empty()).unwrap(); chdir(tempdir.path()).unwrap(); - fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap(); + fchownat(None, "file", uid, gid, AtFlags::empty()).unwrap(); fs::remove_file(&path).unwrap(); - fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap_err(); + fchownat(None, "file", uid, gid, AtFlags::empty()).unwrap_err(); } #[test]