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 | pub use crate::pid::{Pid, RawPid}; |
17 | pub 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)] |
23 | pub struct Cpuid(RawCpuid); |
24 | |
25 | #[cfg (linux_kernel)] |
26 | impl 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 ] |
54 | pub 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 ] |
68 | pub 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 ] |
82 | pub 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 ] |
96 | pub 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 ] |
110 | pub 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 ] |
127 | pub 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 ] |
140 | pub 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 ] |
153 | pub 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 ] |
167 | pub 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 ] |
181 | pub 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 ] |
194 | pub 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" )] |
207 | pub 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 = Vec::with_capacity(0); |
211 | let ngroups: usize = backend::process::syscalls::getgroups(&mut buffer)?; |
212 | buffer.resize(new_len:ngroups, value:Gid::ROOT); |
213 | backend::process::syscalls::getgroups(&mut buffer)?; |
214 | Ok(buffer) |
215 | } |
216 | |