//! Unix user, group, and process identifiers. //! //! # Safety //! //! The `Uid`, `Gid`, and `Pid` types can be constructed from raw integers, //! which is marked unsafe because actual OS's assign special meaning to some //! integer values. #![allow(unsafe_code)] use crate::{backend, io}; #[cfg(feature = "alloc")] use alloc::vec::Vec; #[cfg(linux_kernel)] use backend::process::types::RawCpuid; /// The raw integer value of a Unix user ID. pub use crate::ugid::RawUid; /// The raw integer value of a Unix group ID. pub use crate::ugid::RawGid; /// The raw integer value of a Unix process ID. pub use crate::pid::RawPid; pub use crate::pid::Pid; pub use crate::ugid::{Gid, Uid}; /// A Linux CPU ID. #[cfg(linux_kernel)] #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] pub struct Cpuid(RawCpuid); #[cfg(linux_kernel)] impl Cpuid { /// Converts a `RawCpuid` into a `Cpuid`. /// /// # Safety /// /// `raw` must be the value of a valid Linux CPU ID. #[inline] pub const unsafe fn from_raw(raw: RawCpuid) -> Self { Self(raw) } /// Converts a `Cpuid` into a `RawCpuid`. #[inline] pub const fn as_raw(self) -> RawCpuid { self.0 } } /// `getuid()`—Returns the process' real user ID. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html /// [Linux]: https://man7.org/linux/man-pages/man2/getuid.2.html #[inline] #[must_use] pub fn getuid() -> Uid { backend::ugid::syscalls::getuid() } /// `geteuid()`—Returns the process' effective user ID. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html /// [Linux]: https://man7.org/linux/man-pages/man2/geteuid.2.html #[inline] #[must_use] pub fn geteuid() -> Uid { backend::ugid::syscalls::geteuid() } /// `getgid()`—Returns the process' real group ID. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html /// [Linux]: https://man7.org/linux/man-pages/man2/getgid.2.html #[inline] #[must_use] pub fn getgid() -> Gid { backend::ugid::syscalls::getgid() } /// `getegid()`—Returns the process' effective group ID. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html /// [Linux]: https://man7.org/linux/man-pages/man2/getegid.2.html #[inline] #[must_use] pub fn getegid() -> Gid { backend::ugid::syscalls::getegid() } /// `getpid()`—Returns the process' ID. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html /// [Linux]: https://man7.org/linux/man-pages/man2/getpid.2.html #[inline] #[must_use] pub fn getpid() -> Pid { backend::pid::syscalls::getpid() } /// `getppid()`—Returns the parent process' ID. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html /// [Linux]: https://man7.org/linux/man-pages/man2/getppid.2.html #[inline] #[must_use] pub fn getppid() -> Option { backend::process::syscalls::getppid() } /// `getpgid(pid)`—Returns the process group ID of the given process. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgid.html /// [Linux]: https://man7.org/linux/man-pages/man2/getpgid.2.html #[inline] pub fn getpgid(pid: Option) -> io::Result { backend::process::syscalls::getpgid(pid) } /// `setpgid(pid, pgid)`—Sets the process group ID of the given process. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html /// [Linux]: https://man7.org/linux/man-pages/man2/setpgid.2.html #[inline] pub fn setpgid(pid: Option, pgid: Option) -> io::Result<()> { backend::process::syscalls::setpgid(pid, pgid) } /// `getpgrp()`—Returns the process' group ID. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html /// [Linux]: https://man7.org/linux/man-pages/man2/getpgrp.2.html #[inline] #[must_use] pub fn getpgrp() -> Pid { backend::process::syscalls::getpgrp() } /// `getsid(pid)`—Get the session ID of the given process. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html /// [Linux]: https://man7.org/linux/man-pages/man2/getsid.2.html #[cfg(not(target_os = "redox"))] #[inline] pub fn getsid(pid: Option) -> io::Result { backend::process::syscalls::getsid(pid) } /// `setsid()`—Create a new session. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html /// [Linux]: https://man7.org/linux/man-pages/man2/setsid.2.html #[inline] pub fn setsid() -> io::Result { backend::process::syscalls::setsid() } /// `getgroups()`—Return a list of the current user's groups. /// /// # References /// - [POSIX] /// - [Linux] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgroups.html /// [Linux]: https://man7.org/linux/man-pages/man2/getgroups.2.html #[cfg(feature = "alloc")] pub fn getgroups() -> io::Result> { // This code would benefit from having a better way to read into // uninitialized memory, but that requires `unsafe`. let mut buffer = Vec::with_capacity(8); buffer.resize(buffer.capacity(), Gid::ROOT); loop { let ngroups = backend::process::syscalls::getgroups(&mut buffer)?; let ngroups = ngroups as usize; assert!(ngroups <= buffer.len()); if ngroups < buffer.len() { buffer.resize(ngroups, Gid::ROOT); return Ok(buffer); } // Use `Vec` reallocation strategy to grow capacity exponentially. buffer.reserve(1); buffer.resize(buffer.capacity(), Gid::ROOT); } }