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}