1//! Unix user, group, and process identifiers.
2//!
3//! # Safety
4//!
5//! The `Uid`, `Gid`, and `Pid` types can be constructed from raw integers,
6//! which is marked unsafe because actual OS's assign special meaning to some
7//! integer values.
8#![allow(unsafe_code)]
9
10use crate::{backend, io};
11#[cfg(feature = "alloc")]
12use alloc::vec::Vec;
13#[cfg(linux_kernel)]
14use backend::process::types::RawCpuid;
15
16/// The raw integer value of a Unix user ID.
17pub use crate::ugid::RawUid;
18
19/// The raw integer value of a Unix group ID.
20pub use crate::ugid::RawGid;
21
22/// The raw integer value of a Unix process ID.
23pub use crate::pid::RawPid;
24
25pub use crate::pid::Pid;
26pub use crate::ugid::{Gid, Uid};
27
28/// A Linux CPU ID.
29#[cfg(linux_kernel)]
30#[repr(transparent)]
31#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
32pub struct Cpuid(RawCpuid);
33
34#[cfg(linux_kernel)]
35impl Cpuid {
36 /// Converts a `RawCpuid` into a `Cpuid`.
37 ///
38 /// # Safety
39 ///
40 /// `raw` must be the value of a valid Linux CPU ID.
41 #[inline]
42 pub const unsafe fn from_raw(raw: RawCpuid) -> Self {
43 Self(raw)
44 }
45
46 /// Converts a `Cpuid` into a `RawCpuid`.
47 #[inline]
48 pub const fn as_raw(self) -> RawCpuid {
49 self.0
50 }
51}
52
53/// `getuid()`—Returns the process' real user ID.
54///
55/// # References
56/// - [POSIX]
57/// - [Linux]
58///
59/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html
60/// [Linux]: https://man7.org/linux/man-pages/man2/getuid.2.html
61#[inline]
62#[must_use]
63pub fn getuid() -> Uid {
64 backend::ugid::syscalls::getuid()
65}
66
67/// `geteuid()`—Returns the process' effective user ID.
68///
69/// # References
70/// - [POSIX]
71/// - [Linux]
72///
73/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html
74/// [Linux]: https://man7.org/linux/man-pages/man2/geteuid.2.html
75#[inline]
76#[must_use]
77pub fn geteuid() -> Uid {
78 backend::ugid::syscalls::geteuid()
79}
80
81/// `getgid()`—Returns the process' real group ID.
82///
83/// # References
84/// - [POSIX]
85/// - [Linux]
86///
87/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html
88/// [Linux]: https://man7.org/linux/man-pages/man2/getgid.2.html
89#[inline]
90#[must_use]
91pub fn getgid() -> Gid {
92 backend::ugid::syscalls::getgid()
93}
94
95/// `getegid()`—Returns the process' effective group ID.
96///
97/// # References
98/// - [POSIX]
99/// - [Linux]
100///
101/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html
102/// [Linux]: https://man7.org/linux/man-pages/man2/getegid.2.html
103#[inline]
104#[must_use]
105pub fn getegid() -> Gid {
106 backend::ugid::syscalls::getegid()
107}
108
109/// `getpid()`—Returns the process' ID.
110///
111/// # References
112/// - [POSIX]
113/// - [Linux]
114///
115/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html
116/// [Linux]: https://man7.org/linux/man-pages/man2/getpid.2.html
117#[inline]
118#[must_use]
119pub fn getpid() -> Pid {
120 backend::pid::syscalls::getpid()
121}
122
123/// `getppid()`—Returns the parent process' ID.
124///
125/// # References
126/// - [POSIX]
127/// - [Linux]
128///
129/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html
130/// [Linux]: https://man7.org/linux/man-pages/man2/getppid.2.html
131#[inline]
132#[must_use]
133pub fn getppid() -> Option<Pid> {
134 backend::process::syscalls::getppid()
135}
136
137/// `getpgid(pid)`—Returns the process group ID of the given process.
138///
139/// # References
140/// - [POSIX]
141/// - [Linux]
142///
143/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgid.html
144/// [Linux]: https://man7.org/linux/man-pages/man2/getpgid.2.html
145#[inline]
146pub fn getpgid(pid: Option<Pid>) -> io::Result<Pid> {
147 backend::process::syscalls::getpgid(pid)
148}
149
150/// `setpgid(pid, pgid)`—Sets the process group ID of the given process.
151///
152/// # References
153/// - [POSIX]
154/// - [Linux]
155///
156/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html
157/// [Linux]: https://man7.org/linux/man-pages/man2/setpgid.2.html
158#[inline]
159pub fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> {
160 backend::process::syscalls::setpgid(pid, pgid)
161}
162
163/// `getpgrp()`—Returns the process' group ID.
164///
165/// # References
166/// - [POSIX]
167/// - [Linux]
168///
169/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html
170/// [Linux]: https://man7.org/linux/man-pages/man2/getpgrp.2.html
171#[inline]
172#[must_use]
173pub fn getpgrp() -> Pid {
174 backend::process::syscalls::getpgrp()
175}
176
177/// `getsid(pid)`—Get the session ID of the given process.
178///
179/// # References
180/// - [POSIX]
181/// - [Linux]
182///
183/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html
184/// [Linux]: https://man7.org/linux/man-pages/man2/getsid.2.html
185#[cfg(not(target_os = "redox"))]
186#[inline]
187pub fn getsid(pid: Option<Pid>) -> io::Result<Pid> {
188 backend::process::syscalls::getsid(pid)
189}
190
191/// `setsid()`—Create a new session.
192///
193/// # References
194/// - [POSIX]
195/// - [Linux]
196///
197/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html
198/// [Linux]: https://man7.org/linux/man-pages/man2/setsid.2.html
199#[inline]
200pub fn setsid() -> io::Result<Pid> {
201 backend::process::syscalls::setsid()
202}
203
204/// `getgroups()`—Return a list of the current user's groups.
205///
206/// # References
207/// - [POSIX]
208/// - [Linux]
209///
210/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgroups.html
211/// [Linux]: https://man7.org/linux/man-pages/man2/getgroups.2.html
212#[cfg(feature = "alloc")]
213pub fn getgroups() -> io::Result<Vec<Gid>> {
214 // This code would benefit from having a better way to read into
215 // uninitialized memory, but that requires `unsafe`.
216 let mut buffer: Vec = Vec::with_capacity(0);
217 let ngroups: usize = backend::process::syscalls::getgroups(&mut buffer)?;
218 buffer.resize(new_len:ngroups, value:Gid::ROOT);
219 backend::process::syscalls::getgroups(&mut buffer)?;
220 Ok(buffer)
221}
222