From: Alan Cox Date: Sat, 13 Feb 2016 20:34:15 +0000 (+0000) Subject: waitpid: add more job control bits X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=99a85682a5040679a1cfcb7b06e27916ca0dca54;p=FUZIX.git waitpid: add more job control bits Our SIGSTOP handling still isn't quite right for the case we get a stop while already sleeping. --- diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 1b938187..22fa1ea8 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -382,6 +382,7 @@ typedef struct p_tab { /**HP**/ uint16_t p_pgrp; /* Process group */ uint8_t p_nice; + uint8_t p_event; /* Events */ usize_t p_top; /* Copy of u_top */ #ifdef CONFIG_PROFIL uint8_t p_profscale; @@ -471,8 +472,9 @@ struct s_argblk { /* waitpid options */ -#define WNOHANG 1 /* don't support others yet */ - +#define WNOHANG 1 +#define WUNTRACED 2 +#define _WSTOPPED 0xFF /* Open() parameters. */ diff --git a/Kernel/process.c b/Kernel/process.c index 0846ceb2..11ae84ca 100644 --- a/Kernel/process.c +++ b/Kernel/process.c @@ -500,21 +500,23 @@ void ssig(ptptr proc, uint16_t sig) irq = di(); if (proc->p_status != P_EMPTY) { /* Presumably was killed just now */ - /* SIGSTOP can't be ignored and puts the process into P_STOPPED */ - /* FIXME: Level 2 will need a lot more handling here, both SIGTSTP - handling and the wait() handling for stopping */ + /* SIGSTOP can't be ignored and puts the process into P_STOPPED. + We need to sort out handling of SIGSTOP when waiting - we should + really interrupt the syscall and stop */ if (sig == SIGSTOP || sig == SIGTTIN || sig == SIGTTOU) { if (proc->p_status == P_RUNNING || proc->p_status == P_READY) nready--; proc->p_status = P_STOPPED; + proc->p_event = sig; /* SIGCONT likewise has an unblockable effect */ } else if (sig == SIGCONT && proc->p_status == P_STOPPED) { proc->p_status = P_READY; + proc->p_event = 0; nready++; } /* Routine signal behaviour */ - else if (!(proc->p_ignored & sigm)) { + if (!(proc->p_ignored & sigm)) { /* Don't wake for held signals */ if (!(proc->p_held & sigm)) { switch (proc->p_status) { diff --git a/Kernel/syscall_proc.c b/Kernel/syscall_proc.c index ff900ee7..2d88b56a 100644 --- a/Kernel/syscall_proc.c +++ b/Kernel/syscall_proc.c @@ -302,14 +302,12 @@ arg_t _waitpid(void) return -1; } for (p = ptab; p < ptab_end; ++p) { - if (p->p_status == P_ZOMBIE - && p->p_pptr == udata.u_ptab) { - if (pid == -1 || p->p_pid == pid - || p->p_pgrp == -pid) { + if (p->p_pptr == udata.u_ptab && + (pid == -1 || p->p_pid == pid || + p->p_pgrp == -pid)) { + if (p->p_status == P_ZOMBIE) { if (statloc) - uputw(p->p_exitval, - statloc); - + uputw(p->p_exitval, statloc); retval = p->p_pid; p->p_status = P_EMPTY; @@ -319,6 +317,11 @@ arg_t _waitpid(void) udata.u_cstime += ((clock_t *)&p->p_priority)[1]; return retval; } + if (p->p_event && (options & WUNTRACED)) { + retval = (uint16_t)p->p_event << 8 | _WSTOPPED; + p->p_event = 0; + return retval; + } } } /* Nothing yet, so wait */