kernel: fix waitpid() with WSTOPPED; only return on state change?

This commit is contained in:
K. Lange 2022-08-18 18:19:15 +09:00
parent d600d3d393
commit dd33c722c5
2 changed files with 9 additions and 4 deletions

View File

@ -996,9 +996,12 @@ int waitpid(int pid, int * status, int options) {
candidate = child;
break;
}
if ((options & WSTOPPED) && child->flags & PROC_FLAG_SUSPENDED) {
candidate = child;
break;
if (child->flags & PROC_FLAG_SUSPENDED) {
int status = child->status;
if (((options & WSTOPPED) && (status & 0x7F) == 0x7F) || ((options & WUNTRACED) && status == 0x7F)) {
candidate = child;
break;
}
}
}
}
@ -1027,6 +1030,7 @@ int waitpid(int pid, int * status, int options) {
if (status) {
*status = candidate->status;
}
candidate->status = 0;
int pid = candidate->id;
if (is_parent && (candidate->flags & PROC_FLAG_FINISHED)) {
while (*((volatile int *)&candidate->flags) & PROC_FLAG_RUNNING);

View File

@ -294,6 +294,7 @@ int group_send_signal(pid_t group, int signal, int force_root) {
* @param r Userspace registers before signal entry.
*/
void process_check_signals(struct regs * r) {
_tryagain:
spin_lock(sig_lock);
if (this_core->current_process && !(this_core->current_process->flags & PROC_FLAG_FINISHED)) {
/* Set an pending signals that were previously blocked */
@ -305,7 +306,7 @@ void process_check_signals(struct regs * r) {
this_core->current_process->pending_signals &= ~(1 << signal);
spin_unlock(sig_lock);
if (handle_signal((process_t*)this_core->current_process, signal, r)) return;
spin_lock(sig_lock);
goto _tryagain;
}
active_signals >>= 1;
signal++;