5
5
//! C header: [`include/linux/sched.h`](../../../../include/linux/sched.h).
6
6
7
7
use crate :: { bindings, types:: Opaque } ;
8
- use core:: { marker:: PhantomData , ops:: Deref , ptr} ;
8
+ use core:: {
9
+ cmp:: { Eq , PartialEq } ,
10
+ marker:: PhantomData ,
11
+ ops:: Deref ,
12
+ ptr,
13
+ } ;
9
14
10
15
/// Returns the currently running task.
11
16
#[ macro_export]
@@ -78,6 +83,12 @@ unsafe impl Sync for Task {}
78
83
/// The type of process identifiers (PIDs).
79
84
type Pid = bindings:: pid_t ;
80
85
86
+ /// The type of user identifiers (UIDs).
87
+ #[ derive( Copy , Clone ) ]
88
+ pub struct Kuid {
89
+ kuid : bindings:: kuid_t ,
90
+ }
91
+
81
92
impl Task {
82
93
/// Returns a task reference for the currently executing task/thread.
83
94
///
@@ -132,12 +143,32 @@ impl Task {
132
143
unsafe { * ptr:: addr_of!( ( * self . 0 . get( ) ) . pid) }
133
144
}
134
145
146
+ /// Returns the UID of the given task.
147
+ pub fn uid ( & self ) -> Kuid {
148
+ // SAFETY: By the type invariant, we know that `self.0` is valid.
149
+ Kuid :: from_raw ( unsafe { bindings:: task_uid ( self . 0 . get ( ) ) } )
150
+ }
151
+
152
+ /// Returns the effective UID of the given task.
153
+ pub fn euid ( & self ) -> Kuid {
154
+ // SAFETY: By the type invariant, we know that `self.0` is valid.
155
+ Kuid :: from_raw ( unsafe { bindings:: task_euid ( self . 0 . get ( ) ) } )
156
+ }
157
+
135
158
/// Determines whether the given task has pending signals.
136
159
pub fn signal_pending ( & self ) -> bool {
137
160
// SAFETY: By the type invariant, we know that `self.0` is valid.
138
161
unsafe { bindings:: signal_pending ( self . 0 . get ( ) ) != 0 }
139
162
}
140
163
164
+ /// Returns the given task's pid in the current pid namespace.
165
+ pub fn pid_in_current_ns ( & self ) -> Pid {
166
+ // SAFETY: Calling `task_active_pid_ns` with the current task is always safe.
167
+ let namespace = unsafe { bindings:: task_active_pid_ns ( bindings:: get_current ( ) ) } ;
168
+ // SAFETY: We know that `self.0.get()` is valid by the type invariant.
169
+ unsafe { bindings:: task_tgid_nr_ns ( self . 0 . get ( ) , namespace) }
170
+ }
171
+
141
172
/// Wakes up the task.
142
173
pub fn wake_up ( & self ) {
143
174
// SAFETY: By the type invariant, we know that `self.0.get()` is non-null and valid.
@@ -147,6 +178,41 @@ impl Task {
147
178
}
148
179
}
149
180
181
+ impl Kuid {
182
+ /// Get the current euid.
183
+ pub fn current_euid ( ) -> Kuid {
184
+ // SAFETY: Just an FFI call.
185
+ Self :: from_raw ( unsafe { bindings:: current_euid ( ) } )
186
+ }
187
+
188
+ /// Create a `Kuid` given the raw C type.
189
+ pub fn from_raw ( kuid : bindings:: kuid_t ) -> Self {
190
+ Self { kuid }
191
+ }
192
+
193
+ /// Turn this kuid into the raw C type.
194
+ pub fn into_raw ( self ) -> bindings:: kuid_t {
195
+ self . kuid
196
+ }
197
+
198
+ /// Converts this kernel UID into a userspace UID.
199
+ ///
200
+ /// Uses the namespace of the current task.
201
+ pub fn into_uid_in_current_ns ( self ) -> bindings:: uid_t {
202
+ // SAFETY: Just an FFI call.
203
+ unsafe { bindings:: from_kuid ( bindings:: current_user_ns ( ) , self . kuid ) }
204
+ }
205
+ }
206
+
207
+ impl PartialEq for Kuid {
208
+ fn eq ( & self , other : & Kuid ) -> bool {
209
+ // SAFETY: Just an FFI call.
210
+ unsafe { bindings:: uid_eq ( self . kuid , other. kuid ) }
211
+ }
212
+ }
213
+
214
+ impl Eq for Kuid { }
215
+
150
216
// SAFETY: The type invariants guarantee that `Task` is always ref-counted.
151
217
unsafe impl crate :: types:: AlwaysRefCounted for Task {
152
218
fn inc_ref ( & self ) {
0 commit comments