summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-12-27 00:58:17 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-12-27 01:01:57 +0100
commitb9fe5b6eadc913ead80531905aeafa51ed0d4ccd (patch)
tree92866f4a59fe8c852f9ab10611acc63e47e56fa9
parentd7964b08211f5221e73400ed36093d44f9455fff (diff)
Add proc_waitid
proc_wait assumes that the caller always wants WEXITED, but waitid() does not. The new proc_waitid RPC requires the caller to specify at least one of WEXITED, WSTOPPED, or WCONTINUED. * hurd/process.defs (proc_waitid): New RPC. * hurd/process_reply.defs (proc_waitid): New RPC. * hurd/process_request.defs (proc_waitid): New RPC. * proc/proc.h (struct proc): Add p_continued field. * proc/wait.c (WCONTINUED, WEXITED): Define if not already defined. (S_proc_wait): Rename implementation to S_proc_waitid, and modify to stop assuming WEXITED. Add support for WCONTINUED. (S_proc_wait): Reimplement by just calling S_proc_waitid with an additional WEXITED. (proc_mark_stop): Clear p_continued. (proc_mark_cont): Set p_continued, clear p_waited, wake any waiting parent.
-rw-r--r--hurd/process.defs17
-rw-r--r--hurd/process_reply.defs2
-rw-r--r--hurd/process_request.defs2
-rw-r--r--proc/proc.h1
-rw-r--r--proc/wait.c56
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);