Skip to content

Commit 33f07cc

Browse files
committed
add support for chown/lchown/fchown/fchownat
1 parent 97c4ca2 commit 33f07cc

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2424
([#739](https://github.com/nix-rust/nix/pull/739))
2525
- Added nix::sys::ptrace::detach.
2626
([#749](https://github.com/nix-rust/nix/pull/749))
27+
- Added `nix::unistd::{chown, lchown, fchown, fchownat}`
28+
([#760](https://github.com/nix-rust/nix/pull/760))
2729

2830
### Changed
2931
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))

src/unistd.rs

+62-6
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,17 @@ pub fn getcwd() -> Result<PathBuf> {
492492
}
493493
}
494494

495+
// According to the POSIX, -1 is used to indicate that
496+
// owner and group, respectively, are not to be changed. Since uid_t and
497+
// gid_t are unsigned types, we use wrapping_sub to get '-1'.
498+
fn optional_user(uid: Option<Uid>) -> u32 {
499+
uid.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1))
500+
}
501+
502+
fn optional_group(gid: Option<Gid>) -> u32 {
503+
gid.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1))
504+
}
505+
495506
/// Change the ownership of the file at `path` to be owned by the specified
496507
/// `owner` (user) and `group` (see
497508
/// [chown(2)](http://man7.org/linux/man-pages/man2/lchown.2.html)).
@@ -506,12 +517,57 @@ pub fn getcwd() -> Result<PathBuf> {
506517
#[inline]
507518
pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
508519
let res = try!(path.with_nix_path(|cstr| {
509-
// According to the POSIX specification, -1 is used to indicate that
510-
// owner and group, respectively, are not to be changed. Since uid_t and
511-
// gid_t are unsigned types, we use wrapping_sub to get '-1'.
512-
unsafe { libc::chown(cstr.as_ptr(),
513-
owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)),
514-
group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1))) }
520+
unsafe {
521+
libc::chown(cstr.as_ptr(),
522+
optional_user(owner),
523+
optional_group(group))
524+
}
525+
}));
526+
527+
Errno::result(res).map(drop)
528+
}
529+
530+
/// Change ownership of a file
531+
/// (see [lchown(2)](http://man7.org/linux/man-pages/man2/lchown.2.html)).
532+
pub fn lchown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
533+
let res = try!(path.with_nix_path(|cstr| {
534+
unsafe {
535+
libc::lchown(cstr.as_ptr(),
536+
optional_user(owner),
537+
optional_group(group))
538+
}
539+
}));
540+
541+
Errno::result(res).map(drop)
542+
}
543+
544+
/// Change ownership of a file
545+
/// (see [fchown(2)](http://man7.org/linux/man-pages/man2/fchown.2.html)).
546+
pub fn fchown(fd: RawFd, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
547+
let res = unsafe {
548+
libc::fchown(fd,
549+
optional_user(owner),
550+
optional_group(group))
551+
};
552+
553+
Errno::result(res).map(drop)
554+
}
555+
556+
/// Change ownership of a file
557+
/// (see [fchownat(2)](http://man7.org/linux/man-pages/man2/fchownat.2.html)).
558+
pub fn fchownat<P: ?Sized + NixPath>(dirfd: RawFd,
559+
pathname: &P,
560+
owner: Option<Uid>,
561+
group: Option<Gid>,
562+
flags: AtFlags) -> Result<()> {
563+
let res = try!(pathname.with_nix_path(|cstr| {
564+
unsafe {
565+
libc::fchownat(dirfd,
566+
cstr.as_ptr(),
567+
optional_user(owner),
568+
optional_group(group),
569+
flags.bits())
570+
}
515571
}));
516572

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

0 commit comments

Comments
 (0)