7
7
use crate :: { bindings, types:: Opaque } ;
8
8
use core:: {
9
9
ffi:: { c_int, c_long, c_uint} ,
10
+ cmp:: { Eq , PartialEq } ,
10
11
marker:: PhantomData ,
11
12
ops:: Deref ,
12
13
ptr,
@@ -94,6 +95,12 @@ unsafe impl Sync for Task {}
94
95
/// The type of process identifiers (PIDs).
95
96
type Pid = bindings:: pid_t ;
96
97
98
+ /// The type of user identifiers (UIDs).
99
+ #[ derive( Copy , Clone ) ]
100
+ pub struct Kuid {
101
+ kuid : bindings:: kuid_t ,
102
+ }
103
+
97
104
impl Task {
98
105
/// Returns a task reference for the currently executing task/thread.
99
106
///
@@ -148,12 +155,32 @@ impl Task {
148
155
unsafe { * ptr:: addr_of!( ( * self . 0 . get( ) ) . pid) }
149
156
}
150
157
158
+ /// Returns the UID of the given task.
159
+ pub fn uid ( & self ) -> Kuid {
160
+ // SAFETY: By the type invariant, we know that `self.0` is valid.
161
+ Kuid :: from_raw ( unsafe { bindings:: task_uid ( self . 0 . get ( ) ) } )
162
+ }
163
+
164
+ /// Returns the effective UID of the given task.
165
+ pub fn euid ( & self ) -> Kuid {
166
+ // SAFETY: By the type invariant, we know that `self.0` is valid.
167
+ Kuid :: from_raw ( unsafe { bindings:: task_euid ( self . 0 . get ( ) ) } )
168
+ }
169
+
151
170
/// Determines whether the given task has pending signals.
152
171
pub fn signal_pending ( & self ) -> bool {
153
172
// SAFETY: By the type invariant, we know that `self.0` is valid.
154
173
unsafe { bindings:: signal_pending ( self . 0 . get ( ) ) != 0 }
155
174
}
156
175
176
+ /// Returns the given task's pid in the current pid namespace.
177
+ pub fn pid_in_current_ns ( & self ) -> Pid {
178
+ // SAFETY: Calling `task_active_pid_ns` with the current task is always safe.
179
+ let namespace = unsafe { bindings:: task_active_pid_ns ( bindings:: get_current ( ) ) } ;
180
+ // SAFETY: We know that `self.0.get()` is valid by the type invariant.
181
+ unsafe { bindings:: task_tgid_nr_ns ( self . 0 . get ( ) , namespace) }
182
+ }
183
+
157
184
/// Wakes up the task.
158
185
pub fn wake_up ( & self ) {
159
186
// SAFETY: By the type invariant, we know that `self.0.get()` is non-null and valid.
@@ -163,6 +190,41 @@ impl Task {
163
190
}
164
191
}
165
192
193
+ impl Kuid {
194
+ /// Get the current euid.
195
+ pub fn current_euid ( ) -> Kuid {
196
+ // SAFETY: Just an FFI call.
197
+ Self :: from_raw ( unsafe { bindings:: current_euid ( ) } )
198
+ }
199
+
200
+ /// Create a `Kuid` given the raw C type.
201
+ pub fn from_raw ( kuid : bindings:: kuid_t ) -> Self {
202
+ Self { kuid }
203
+ }
204
+
205
+ /// Turn this kuid into the raw C type.
206
+ pub fn into_raw ( self ) -> bindings:: kuid_t {
207
+ self . kuid
208
+ }
209
+
210
+ /// Converts this kernel UID into a userspace UID.
211
+ ///
212
+ /// Uses the namespace of the current task.
213
+ pub fn into_uid_in_current_ns ( self ) -> bindings:: uid_t {
214
+ // SAFETY: Just an FFI call.
215
+ unsafe { bindings:: from_kuid ( bindings:: current_user_ns ( ) , self . kuid ) }
216
+ }
217
+ }
218
+
219
+ impl PartialEq for Kuid {
220
+ fn eq ( & self , other : & Kuid ) -> bool {
221
+ // SAFETY: Just an FFI call.
222
+ unsafe { bindings:: uid_eq ( self . kuid , other. kuid ) }
223
+ }
224
+ }
225
+
226
+ impl Eq for Kuid { }
227
+
166
228
// SAFETY: The type invariants guarantee that `Task` is always ref-counted.
167
229
unsafe impl crate :: types:: AlwaysRefCounted for Task {
168
230
fn inc_ref ( & self ) {
0 commit comments