1
1
use core:: { mem, time:: Duration } ;
2
2
3
+ use alloc:: sync:: Arc ;
3
4
use arceos_posix_api:: ctypes:: timespec;
4
5
use axerrno:: { LinuxError , LinuxResult } ;
5
6
use axprocess:: { Pid , Process , ProcessGroup , Thread } ;
@@ -70,6 +71,10 @@ fn check_sigset_size(size: usize) -> LinuxResult<()> {
70
71
Ok ( ( ) )
71
72
}
72
73
74
+ fn parse_signo ( signo : u32 ) -> LinuxResult < Signo > {
75
+ Signo :: from_repr ( signo as u8 ) . ok_or ( LinuxError :: EINVAL )
76
+ }
77
+
73
78
pub fn sys_rt_sigprocmask (
74
79
how : i32 ,
75
80
set : UserConstPtr < SignalSet > ,
@@ -103,14 +108,14 @@ pub fn sys_rt_sigprocmask(
103
108
}
104
109
105
110
pub fn sys_rt_sigaction (
106
- signo : i32 ,
111
+ signo : u32 ,
107
112
act : UserConstPtr < kernel_sigaction > ,
108
113
oldact : UserPtr < kernel_sigaction > ,
109
114
sigsetsize : usize ,
110
115
) -> LinuxResult < isize > {
111
116
check_sigset_size ( sigsetsize) ?;
112
117
113
- let signo = Signo :: from_repr ( signo as u8 ) . ok_or ( LinuxError :: EINVAL ) ?;
118
+ let signo = parse_signo ( signo) ?;
114
119
if matches ! ( signo, Signo :: SIGKILL | Signo :: SIGSTOP ) {
115
120
return Err ( LinuxError :: EINVAL ) ;
116
121
}
@@ -167,12 +172,12 @@ fn make_siginfo(signo: u32, code: u32) -> LinuxResult<Option<SignalInfo>> {
167
172
if signo == 0 {
168
173
return Ok ( None ) ;
169
174
}
170
- let signo = Signo :: from_repr ( signo as u8 ) . ok_or ( LinuxError :: EINVAL ) ?;
175
+ let signo = parse_signo ( signo) ?;
171
176
Ok ( Some ( SignalInfo :: new ( signo, code) ) )
172
177
}
173
178
174
- pub fn sys_kill ( pid : i32 , sig : u32 ) -> LinuxResult < isize > {
175
- let Some ( sig) = make_siginfo ( sig , SI_USER ) ? else {
179
+ pub fn sys_kill ( pid : i32 , signo : u32 ) -> LinuxResult < isize > {
180
+ let Some ( sig) = make_siginfo ( signo , SI_USER ) ? else {
176
181
// TODO: should also check permissions
177
182
return Ok ( 0 ) ;
178
183
} ;
@@ -208,8 +213,8 @@ pub fn sys_kill(pid: i32, sig: u32) -> LinuxResult<isize> {
208
213
Ok ( result as isize )
209
214
}
210
215
211
- pub fn sys_tkill ( tid : Pid , sig : u32 ) -> LinuxResult < isize > {
212
- let Some ( sig) = make_siginfo ( sig , SI_TKILL as u32 ) ? else {
216
+ pub fn sys_tkill ( tid : Pid , signo : u32 ) -> LinuxResult < isize > {
217
+ let Some ( sig) = make_siginfo ( signo , SI_TKILL as u32 ) ? else {
213
218
// TODO: should also check permissions
214
219
return Ok ( 0 ) ;
215
220
} ;
@@ -219,17 +224,62 @@ pub fn sys_tkill(tid: Pid, sig: u32) -> LinuxResult<isize> {
219
224
Ok ( 0 )
220
225
}
221
226
222
- pub fn sys_tgkill ( tgid : Pid , tid : Pid , sig : u32 ) -> LinuxResult < isize > {
223
- let Some ( sig) = make_siginfo ( sig , SI_TKILL as u32 ) ? else {
227
+ pub fn sys_tgkill ( tgid : Pid , tid : Pid , signo : u32 ) -> LinuxResult < isize > {
228
+ let Some ( sig) = make_siginfo ( signo , SI_TKILL as u32 ) ? else {
224
229
// TODO: should also check permissions
225
230
return Ok ( 0 ) ;
226
231
} ;
227
232
233
+ send_signal_thread ( get_thread_checked ( tgid, tid) ?. as_ref ( ) , sig) ?;
234
+ Ok ( 0 )
235
+ }
236
+
237
+ fn get_thread_checked ( tgid : Pid , tid : Pid ) -> LinuxResult < Arc < Thread > > {
228
238
let thr = get_thread ( tid) ?;
229
239
if thr. process ( ) . pid ( ) != tgid {
230
240
return Err ( LinuxError :: ESRCH ) ;
231
241
}
232
- send_signal_thread ( & thr, sig) ?;
242
+ Ok ( thr)
243
+ }
244
+
245
+ fn make_queue_signal_info (
246
+ tgid : Pid ,
247
+ signo : u32 ,
248
+ sig : UserConstPtr < SignalInfo > ,
249
+ ) -> LinuxResult < SignalInfo > {
250
+ let signo = parse_signo ( signo) ?;
251
+ let mut sig = unsafe { sig. get ( ) ?. read ( ) } ;
252
+ sig. set_signo ( signo) ;
253
+ if sig. code ( ) != SI_USER && current ( ) . task_ext ( ) . thread . process ( ) . pid ( ) != tgid {
254
+ return Err ( LinuxError :: EPERM ) ;
255
+ }
256
+ Ok ( sig)
257
+ }
258
+
259
+ pub fn sys_rt_sigqueueinfo (
260
+ tgid : Pid ,
261
+ signo : u32 ,
262
+ sig : UserConstPtr < SignalInfo > ,
263
+ sigsetsize : usize ,
264
+ ) -> LinuxResult < isize > {
265
+ check_sigset_size ( sigsetsize) ?;
266
+
267
+ let sig = make_queue_signal_info ( tgid, signo, sig) ?;
268
+ send_signal_process ( get_process ( tgid) ?. as_ref ( ) , sig) ?;
269
+ Ok ( 0 )
270
+ }
271
+
272
+ pub fn sys_rt_tgsigqueueinfo (
273
+ tgid : Pid ,
274
+ tid : Pid ,
275
+ signo : u32 ,
276
+ sig : UserConstPtr < SignalInfo > ,
277
+ sigsetsize : usize ,
278
+ ) -> LinuxResult < isize > {
279
+ check_sigset_size ( sigsetsize) ?;
280
+
281
+ let sig = make_queue_signal_info ( tgid, signo, sig) ?;
282
+ send_signal_thread ( get_thread_checked ( tgid, tid) ?. as_ref ( ) , sig) ?;
233
283
Ok ( 0 )
234
284
}
235
285
@@ -262,7 +312,7 @@ pub fn sys_rt_sigtimedwait(
262
312
} ;
263
313
264
314
if let Some ( info) = info. nullable ( UserPtr :: get) ? {
265
- sig . to_ctype ( unsafe { & mut * info } ) ;
315
+ unsafe { * info = sig . 0 } ;
266
316
}
267
317
268
318
Ok ( 0 )
0 commit comments