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
10 use crate::{backend, io};
11 #[cfg(feature = "alloc")]
12 use alloc::vec::Vec;
13 #[cfg(linux_kernel)]
14 use backend::process::types::RawCpuid;
15
16 /// The raw integer value of a Unix user ID.
17 pub use crate::ugid::RawUid;
18
19 /// The raw integer value of a Unix group ID.
20 pub use crate::ugid::RawGid;
21
22 /// The raw integer value of a Unix process ID.
23 pub use crate::pid::RawPid;
24
25 pub use crate::pid::Pid;
26 pub 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)]
32 pub struct Cpuid(RawCpuid);
33
34 #[cfg(linux_kernel)]
35 impl 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]
from_raw(raw: RawCpuid) -> Self42 pub const unsafe fn from_raw(raw: RawCpuid) -> Self {
43 Self(raw)
44 }
45
46 /// Converts a `Cpuid` into a `RawCpuid`.
47 #[inline]
as_raw(self) -> RawCpuid48 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]
getuid() -> Uid63 pub 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]
geteuid() -> Uid77 pub 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]
getgid() -> Gid91 pub 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]
getegid() -> Gid105 pub 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]
getpid() -> Pid119 pub 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]
getppid() -> Option<Pid>133 pub 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]
getpgid(pid: Option<Pid>) -> io::Result<Pid>146 pub 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]
setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()>159 pub 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]
getpgrp() -> Pid173 pub 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]
getsid(pid: Option<Pid>) -> io::Result<Pid>187 pub 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]
setsid() -> io::Result<Pid>200 pub 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")]
getgroups() -> io::Result<Vec<Gid>>213 pub 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::with_capacity(8);
217 buffer.resize(buffer.capacity(), Gid::ROOT);
218
219 loop {
220 let ngroups = backend::process::syscalls::getgroups(&mut buffer)?;
221
222 let ngroups = ngroups as usize;
223 assert!(ngroups <= buffer.len());
224 if ngroups < buffer.len() {
225 buffer.resize(ngroups, Gid::ROOT);
226 return Ok(buffer);
227 }
228 // Use `Vec` reallocation strategy to grow capacity exponentially.
229 buffer.reserve(1);
230 buffer.resize(buffer.capacity(), Gid::ROOT);
231 }
232 }
233