diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/unistd.rs | 14 | ||||
-rw-r--r-- | test/test_unistd.rs | 18 |
3 files changed, 34 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 4df5615b..6b508e5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate ### Added +- Added `fchown(2)` wrapper. + (#[1257](https://github.com/nix-rust/nix/pull/1257)) - Added support on linux systems for `MAP_HUGE_`_`SIZE`_ family of flags. (#[1211](https://github.com/nix-rust/nix/pull/1211)) - Added support for `F_OFD_*` `fcntl` commands on Linux and Android. diff --git a/src/unistd.rs b/src/unistd.rs index 8ff71e05..c09e4019 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -651,6 +651,20 @@ pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gi Errno::result(res).map(drop) } +/// Change the ownership of the file referred to by the open file descriptor `fd` to be owned by +/// the specified `owner` (user) and `group` (see +/// [fchown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)). +/// +/// The owner/group for the provided file will not be modified if `None` is +/// provided for that argument. Ownership change will be attempted for the path +/// only if `Some` owner/group is provided. +#[inline] +pub fn fchown(fd: RawFd, owner: Option<Uid>, group: Option<Gid>) -> Result<()> { + let (uid, gid) = chown_raw_ids(owner, group); + let res = unsafe { libc::fchown(fd, uid, gid) }; + Errno::result(res).map(drop) +} + /// Flags for `fchownat` function. #[derive(Clone, Copy, Debug)] pub enum FchownatFlags { diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 0a41b65f..183d8337 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -17,6 +17,7 @@ use std::ffi::CString; use std::fs::DirBuilder; use std::fs::{self, File}; use std::io::Write; +use std::mem; use std::os::unix::prelude::*; use tempfile::{tempdir, tempfile}; use libc::{_exit, off_t}; @@ -410,6 +411,23 @@ fn test_chown() { } #[test] +fn test_fchown() { + // Testing for anything other than our own UID/GID is hard. + let uid = Some(getuid()); + let gid = Some(getgid()); + + let path = tempfile().unwrap(); + let fd = path.as_raw_fd(); + + fchown(fd, uid, gid).unwrap(); + fchown(fd, uid, None).unwrap(); + fchown(fd, None, gid).unwrap(); + + mem::drop(path); + fchown(fd, uid, gid).unwrap_err(); +} + +#[test] #[cfg(not(target_os = "redox"))] fn test_fchownat() { let _dr = crate::DirRestore::new(); |