Skip to content

Commit ba3f3e5

Browse files
committed
Add fchown(2) wrapper.
1 parent 93af76f commit ba3f3e5

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased] - ReleaseDate
77
### Added
8+
- Added `fchown(2)` wrapper.
9+
(#[1257](https://github.com/nix-rust/nix/pull/1257))
810
- Added support on linux systems for `MAP_HUGE_`_`SIZE`_ family of flags.
911
(#[1211](https://github.com/nix-rust/nix/pull/1211))
1012
- Added support for `F_OFD_*` `fcntl` commands on Linux and Android.

src/unistd.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,20 @@ pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gi
651651
Errno::result(res).map(drop)
652652
}
653653

654+
/// Change the ownership of the file referred to by the open file descriptor `fd` to be owned by
655+
/// the specified `owner` (user) and `group` (see
656+
/// [fchown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)).
657+
///
658+
/// The owner/group for the provided file will not be modified if `None` is
659+
/// provided for that argument. Ownership change will be attempted for the path
660+
/// only if `Some` owner/group is provided.
661+
#[inline]
662+
pub fn fchown(fd: RawFd, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
663+
let (uid, gid) = chown_raw_ids(owner, group);
664+
let res = unsafe { libc::fchown(fd, uid, gid) };
665+
Errno::result(res).map(drop)
666+
}
667+
654668
/// Flags for `fchownat` function.
655669
#[derive(Clone, Copy, Debug)]
656670
pub enum FchownatFlags {

test/test_unistd.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::ffi::CString;
1717
use std::fs::DirBuilder;
1818
use std::fs::{self, File};
1919
use std::io::Write;
20+
use std::mem;
2021
use std::os::unix::prelude::*;
2122
use tempfile::{tempdir, tempfile};
2223
use libc::{_exit, off_t};
@@ -409,6 +410,23 @@ fn test_chown() {
409410
chown(&path, uid, gid).unwrap_err();
410411
}
411412

413+
#[test]
414+
fn test_fchown() {
415+
// Testing for anything other than our own UID/GID is hard.
416+
let uid = Some(getuid());
417+
let gid = Some(getgid());
418+
419+
let path = tempfile().unwrap();
420+
let fd = path.as_raw_fd();
421+
422+
fchown(fd, uid, gid).unwrap();
423+
fchown(fd, uid, None).unwrap();
424+
fchown(fd, None, gid).unwrap();
425+
426+
mem::drop(path);
427+
fchown(fd, uid, gid).unwrap_err();
428+
}
429+
412430
#[test]
413431
#[cfg(not(target_os = "redox"))]
414432
fn test_fchownat() {

0 commit comments

Comments
 (0)