Skip to content

Commit

Permalink
Add getresuid() and getresgid() to unistd
Browse files Browse the repository at this point in the history
  • Loading branch information
jerylvaz committed Apr 24, 2021
1 parent 68d01f0 commit 43e074e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased] - ReleaseDate
### Added
- Added `getresuid` and `getresgid`
(#[1430](https://github.com/nix-rust/nix/pull/1430))

### Added
- Added TIMESTAMPNS support for linux
(#[1402](https://github.com/nix-rust/nix/pull/1402))
Expand Down
50 changes: 49 additions & 1 deletion src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub use self::pivot_root::*;
target_os = "linux", target_os = "openbsd"))]
pub use self::setres::*;

#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))]
pub use self::getres::*;

/// User identifier
///
/// Newtype pattern around `uid_t` (which is just alias). It prevents bugs caused by accidentally
Expand Down Expand Up @@ -1078,7 +1081,7 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
/// The following flags are supported, and will be set atomically as the pipe is
/// created:
///
/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
#[cfg_attr(target_os = "linux", doc = "`O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode. ")]
#[cfg_attr(target_os = "netbsd", doc = "`O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`. ")]
/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
Expand Down Expand Up @@ -2524,6 +2527,51 @@ mod setres {
}
}

#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))]
mod getres {
use crate::Result;
use crate::errno::Errno;
use super::{Uid, Gid};

/// Gets the real, effective, and saved uid.
///
/// ([see getresuid(2)](http://man7.org/linux/man-pages/man2/getresuid.2.html))
///
/// #Returns
///
/// - `Ok((Uid, Uid, Uid))`: tuple of real, effective and saved uids on success.
/// - `Err(x)`: libc error code on failure.
///
#[inline]
pub fn getresuid() -> Result<(Uid, Uid, Uid)> {
let mut ruid = libc::uid_t::max_value();
let mut euid = libc::uid_t::max_value();
let mut suid = libc::uid_t::max_value();
let res = unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) };

Errno::result(res).map(|_| (Uid(ruid), Uid(euid), Uid(suid)))
}

/// Gets the real, effective, and saved gid.
///
/// ([see getresgid(2)](http://man7.org/linux/man-pages/man2/getresgid.2.html))
///
/// #Returns
///
/// - `Ok((Gid, Gid, Gid))`: tuple of real, effective and saved gids on success.
/// - `Err(x)`: libc error code on failure.
///
#[inline]
pub fn getresgid() -> Result<(Gid, Gid, Gid)> {
let mut rgid = libc::gid_t::max_value();
let mut egid = libc::gid_t::max_value();
let mut sgid = libc::gid_t::max_value();
let res = unsafe { libc::getresgid(&mut rgid, &mut egid, &mut sgid) };

Errno::result(res).map(|_| (Gid(rgid), Gid(egid), Gid(sgid)))
}
}

libc_bitflags!{
/// Options for access()
pub struct AccessFlags : c_int {
Expand Down
19 changes: 19 additions & 0 deletions test/test_unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,25 @@ fn test_sysconf_unsupported() {
assert!(open_max.expect("sysconf failed").is_none())
}


#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))]
#[test]
fn test_getresuid() {
let resuid = getresuid().unwrap();
assert!(resuid.0.as_raw() != libc::uid_t::max_value());
assert!(resuid.1.as_raw() != libc::uid_t::max_value());
assert!(resuid.2.as_raw() != libc::uid_t::max_value());
}

#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))]
#[test]
fn test_getresgid() {
let resgid = getresgid().unwrap();
assert!(resgid.0.as_raw() != libc::gid_t::max_value());
assert!(resgid.1.as_raw() != libc::gid_t::max_value());
assert!(resgid.2.as_raw() != libc::gid_t::max_value());
}

// Test that we can create a pair of pipes. No need to verify that they pass
// data; that's the domain of the OS, not nix.
#[test]
Expand Down

0 comments on commit 43e074e

Please sign in to comment.