Skip to content

Commit ab2cf38

Browse files
committed
add support for chown/lchown/fchown/fchownat
1 parent f964e81 commit ab2cf38

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1212
([#582](https://github.com/nix-rust/nix/pull/582)
1313
- Added `nix::unistd::{openat, fstatat, readlink, readlinkat, rename, renameat, mknodat, unlinkat, mkdirat, link, linkat, symlink, symlinkat, access, faccessat}`
1414
([#552](https://github.com/nix-rust/nix/pull/552), [#561](https://github.com/nix-rust/nix/pull/561))
15+
- Added `nix::stat::{chmod, fchmod, fchmodat}` ([#561](https://github.com/nix-rust/nix/pull/561))
16+
- Added `nix::unistd::{chown, lchown, fchown, fchownat}` ([#561](https://github.com/nix-rust/nix/pull/561))
1517
- Added `nix::pty::{grantpt, posix_openpt, ptsname/ptsname_r, unlockpt}`
1618
([#556](https://github.com/nix-rust/nix/pull/556)
1719

src/unistd.rs

+58-6
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,13 @@ pub fn getcwd() -> Result<PathBuf> {
375375
}
376376
}
377377

378+
// According to the POSIX specification, -1 is used to indicate that
379+
// owner and group, respectively, are not to be changed. Since uid_t and
380+
// gid_t are unsigned types, we use wrapping_sub to get '-1'.
381+
fn optional_arg(val: Option<u32>) -> u32 {
382+
val.unwrap_or(0).wrapping_sub(1)
383+
}
384+
378385
/// Change the ownership of the file at `path` to be owned by the specified
379386
/// `owner` (user) and `group` (see
380387
/// [chown(2)](http://man7.org/linux/man-pages/man2/lchown.2.html)).
@@ -389,12 +396,57 @@ pub fn getcwd() -> Result<PathBuf> {
389396
#[inline]
390397
pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<uid_t>, group: Option<gid_t>) -> Result<()> {
391398
let res = try!(path.with_nix_path(|cstr| {
392-
// According to the POSIX specification, -1 is used to indicate that
393-
// owner and group, respectively, are not to be changed. Since uid_t and
394-
// gid_t are unsigned types, we use wrapping_sub to get '-1'.
395-
unsafe { libc::chown(cstr.as_ptr(),
396-
owner.unwrap_or((0 as uid_t).wrapping_sub(1)),
397-
group.unwrap_or((0 as gid_t).wrapping_sub(1))) }
399+
unsafe {
400+
libc::chown(cstr.as_ptr(),
401+
optional_arg(owner),
402+
optional_arg(group))
403+
}
404+
}));
405+
406+
Errno::result(res).map(drop)
407+
}
408+
409+
/// Change ownership of a file
410+
/// (see [lchown(2)](http://man7.org/linux/man-pages/man2/lchown.2.html))
411+
pub fn lchown<P: ?Sized + NixPath>(path: &P, owner: Option<uid_t>, group: Option<gid_t>) -> Result<()> {
412+
let res = try!(path.with_nix_path(|cstr| {
413+
unsafe {
414+
libc::lchown(cstr.as_ptr(),
415+
optional_arg(owner),
416+
optional_arg(group))
417+
}
418+
}));
419+
420+
Errno::result(res).map(drop)
421+
}
422+
423+
/// Change ownership of a file
424+
/// (see [fchown(2)](http://man7.org/linux/man-pages/man2/fchown.2.html))
425+
pub fn fchown(fd: RawFd, owner: Option<uid_t>, group: Option<gid_t>) -> Result<()> {
426+
let res = unsafe {
427+
libc::fchown(fd,
428+
optional_arg(owner),
429+
optional_arg(group))
430+
};
431+
432+
Errno::result(res).map(drop)
433+
}
434+
435+
/// Change ownership of a file
436+
/// (see [fchownat(2)](http://man7.org/linux/man-pages/man2/fchownat.2.html))
437+
pub fn fchownat<P: ?Sized + NixPath>(dirfd: RawFd,
438+
pathname: &P,
439+
owner: Option<uid_t>,
440+
group: Option<gid_t>,
441+
flags: AtFlags) -> Result<()> {
442+
let res = try!(pathname.with_nix_path(|cstr| {
443+
unsafe {
444+
libc::fchownat(dirfd,
445+
cstr.as_ptr(),
446+
optional_arg(owner),
447+
optional_arg(group),
448+
flags.bits())
449+
}
398450
}));
399451

400452
Errno::result(res).map(drop)

0 commit comments

Comments
 (0)