diff options
-rw-r--r-- | hurd/process.defs | 17 | ||||
-rw-r--r-- | hurd/process_reply.defs | 2 | ||||
-rw-r--r-- | hurd/process_request.defs | 2 | ||||
-rw-r--r-- | proc/proc.h | 1 | ||||
-rw-r--r-- | proc/wait.c | 56 |
5 files changed, 67 insertions, 11 deletions
diff --git a/hurd/process.defs b/hurd/process.defs index d515a46d..3b091290 100644 --- a/hurd/process.defs +++ b/hurd/process.defs @@ -434,3 +434,20 @@ routine proc_set_entry ( routine proc_get_entry ( process: process_t; out entry: vm_address_t); + +/* Wait for a child process to exit. If pid is zero, it waits for any + child in the same pgrp as the parent. If pid is -1, it waits for + any child. Otherwise, if pid is negative, it waits for any process + in the specified process group. If pid is positive, it waits for + the specified process. The exit status and resource usage of the + process are returned in status and rusage respectively. + options must specify at least one of WEXITED, WSTOPPED, or WCONTINUED. */ +routine proc_waitid ( + process: process_t; + sreplyport reply_port: sreply_port_t; + pid: pid_t; + options: int; + out status: int; + out sigcode: int; + out rusage: rusage_t; + out pid_status: pid_t); diff --git a/hurd/process_reply.defs b/hurd/process_reply.defs index 2eefcc37..4a79024c 100644 --- a/hurd/process_reply.defs +++ b/hurd/process_reply.defs @@ -200,3 +200,5 @@ skip; /* proc_get_exe */ skip; /* proc_set_entry */ skip; /* proc_get_entry */ + +skip; /* proc_waitid */ diff --git a/hurd/process_request.defs b/hurd/process_request.defs index fc9127ab..f200bf15 100644 --- a/hurd/process_request.defs +++ b/hurd/process_request.defs @@ -423,3 +423,5 @@ skip; /* proc_get_exe */ skip; /* proc_set_entry */ skip; /* proc_get_entry */ + +skip; /* proc_waitid */ diff --git a/proc/proc.h b/proc/proc.h index 64f276d3..cafcfaff 100644 --- a/proc/proc.h +++ b/proc/proc.h @@ -94,6 +94,7 @@ struct proc unsigned int p_loginleader:1; /* leader of login collection */ unsigned int p_dead:1; /* process is dead */ unsigned int p_important:1; /* has called proc_mark_important */ + unsigned int p_continued:1; /* has called proc_mark_cont */ }; typedef struct proc *pstruct_t; diff --git a/proc/wait.c b/proc/wait.c index 3c6c8d06..0f82240a 100644 --- a/proc/wait.c +++ b/proc/wait.c @@ -35,6 +35,14 @@ #include "process_S.h" #include <mach/mig_errors.h> +#ifndef WCONTINUED +#define WCONTINUED 4 +#endif + +#ifndef WEXITED +#define WEXITED 16 +#endif + static inline void rusage_add (struct rusage *acc, const struct rusage *b) { @@ -161,24 +169,25 @@ alert_parent (struct proc *p) } kern_return_t -S_proc_wait (struct proc *p, - mach_port_t reply_port, - mach_msg_type_name_t reply_port_type, - pid_t pid, - int options, - int *status, - int *sigcode, - struct rusage *ru, - pid_t *pid_status) +S_proc_waitid (struct proc *p, + mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, + pid_t pid, + int options, + int *status, + int *sigcode, + struct rusage *ru, + pid_t *pid_status) { int cancel; int reap (struct proc *child) { if (child->p_waited - || (!child->p_dead + || ((!child->p_dead || !(options & WEXITED)) && (!child->p_stopped - || !(child->p_traced || (options & WUNTRACED))))) + || !(child->p_traced || (options & WUNTRACED))) + && (!child->p_continued || !(options & WCONTINUED)))) return 0; child->p_waited = 1; *status = child->p_status; @@ -237,6 +246,22 @@ S_proc_wait (struct proc *p, goto start_over; } +kern_return_t +S_proc_wait (struct proc *p, + mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, + pid_t pid, + int options, + int *status, + int *sigcode, + struct rusage *ru, + pid_t *pid_status) +{ + return S_proc_waitid(p, reply_port, reply_port_type, pid, + options | WEXITED, + status, sigcode, ru, pid_status); +} + /* Implement proc_mark_stop as described in <hurd/process.defs>. */ kern_return_t S_proc_mark_stop (struct proc *p, @@ -247,6 +272,7 @@ S_proc_mark_stop (struct proc *p, return EOPNOTSUPP; p->p_stopped = 1; + p->p_continued = 0; p->p_status = W_STOPCODE (signo); p->p_sigcode = sigcode; p->p_waited = 0; @@ -294,6 +320,14 @@ S_proc_mark_cont (struct proc *p) return EOPNOTSUPP; p->p_stopped = 0; + p->p_continued = 1; + p->p_waited = 0; + + if (p->p_parent->p_waiting) + { + pthread_cond_broadcast (&p->p_parent->p_wakeup); + p->p_parent->p_waiting = 0; + } if (!p->p_parent->p_nostopcld) send_signal (p->p_parent->p_msgport, SIGCHLD, CLD_CONTINUED, p->p_parent->p_task); |