diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/unistd.rs | 64 | ||||
-rw-r--r-- | test/test_unistd.rs | 19 |
3 files changed, 85 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d950ab18..423ca665 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] - ReleaseDate ### Added +- Added `getresuid` and `getresgid` + (#[1430](https://github.com/nix-rust/nix/pull/1430)) - Added TIMESTAMPNS support for linux (#[1402](https://github.com/nix-rust/nix/pull/1402)) - Added `sendfile64` (#[1439](https://github.com/nix-rust/nix/pull/1439)) diff --git a/src/unistd.rs b/src/unistd.rs index 8e361bad..d406efe8 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -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"))] +pub use self::getres::*; + /// User identifier /// /// Newtype pattern around `uid_t` (which is just alias). It prevents bugs caused by accidentally @@ -2516,6 +2519,67 @@ mod setres { } } +#[cfg(any(target_os = "android", target_os = "linux"))] +mod getres { + use crate::Result; + use crate::errno::Errno; + use super::{Uid, Gid}; + + /// Real, effective and saved user IDs. + #[derive(Debug, Copy, Clone, Eq, PartialEq)] + pub struct ResUid { + pub real: Uid, + pub effective: Uid, + pub saved: Uid + } + + /// Real, effective and saved group IDs. + #[derive(Debug, Copy, Clone, Eq, PartialEq)] + pub struct ResGid { + pub real: Gid, + pub effective: Gid, + pub saved: Gid + } + + /// Gets the real, effective, and saved user IDs. + /// + /// ([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<ResUid> { + 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(|_| ResUid{ real: Uid(ruid), effective: Uid(euid), saved: Uid(suid) }) + } + + /// Gets the real, effective, and saved group IDs. + /// + /// ([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<ResGid> { + 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(|_| ResGid { real: Gid(rgid), effective: Gid(egid), saved: Gid(sgid) } ) + } +} + libc_bitflags!{ /// Options for access() pub struct AccessFlags : c_int { diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 73341947..94d2d1b9 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -624,6 +624,25 @@ fn test_sysconf_unsupported() { assert!(open_max.expect("sysconf failed").is_none()) } + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[test] +fn test_getresuid() { + let resuids = getresuid().unwrap(); + assert!(resuids.real.as_raw() != libc::uid_t::max_value()); + assert!(resuids.effective.as_raw() != libc::uid_t::max_value()); + assert!(resuids.saved.as_raw() != libc::uid_t::max_value()); +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[test] +fn test_getresgid() { + let resgids = getresgid().unwrap(); + assert!(resgids.real.as_raw() != libc::gid_t::max_value()); + assert!(resgids.effective.as_raw() != libc::gid_t::max_value()); + assert!(resgids.saved.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] |