77use crate :: { bindings, types:: Opaque } ;
88use core:: {
99 ffi:: { c_int, c_long, c_uint} ,
10+ cmp:: { Eq , PartialEq } ,
1011 marker:: PhantomData ,
1112 ops:: Deref ,
1213 ptr,
@@ -94,6 +95,12 @@ unsafe impl Sync for Task {}
9495/// The type of process identifiers (PIDs).
9596type Pid = bindings:: pid_t ;
9697
98+ /// The type of user identifiers (UIDs).
99+ #[ derive( Copy , Clone ) ]
100+ pub struct Kuid {
101+ kuid : bindings:: kuid_t ,
102+ }
103+
97104impl Task {
98105 /// Returns a task reference for the currently executing task/thread.
99106 ///
@@ -148,12 +155,32 @@ impl Task {
148155 unsafe { * ptr:: addr_of!( ( * self . 0 . get( ) ) . pid) }
149156 }
150157
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+
151170 /// Determines whether the given task has pending signals.
152171 pub fn signal_pending ( & self ) -> bool {
153172 // SAFETY: By the type invariant, we know that `self.0` is valid.
154173 unsafe { bindings:: signal_pending ( self . 0 . get ( ) ) != 0 }
155174 }
156175
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+
157184 /// Wakes up the task.
158185 pub fn wake_up ( & self ) {
159186 // SAFETY: By the type invariant, we know that `self.0.get()` is non-null and valid.
@@ -163,6 +190,41 @@ impl Task {
163190 }
164191}
165192
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+
166228// SAFETY: The type invariants guarantee that `Task` is always ref-counted.
167229unsafe impl crate :: types:: AlwaysRefCounted for Task {
168230 fn inc_ref ( & self ) {
0 commit comments