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