2002-12-21 Roland McGrath <roland@redhat.com>
* syscall.c (force_result): New function.
* process.c (internal_wait): Handle ECHILD exit from wait call with
WNOHANG flag set; force the return value to 0 in the inferior when it
has live children we are tracing.
diff --git a/process.c b/process.c
index 06ef7f2..9705ba6 100644
--- a/process.c
+++ b/process.c
@@ -1592,14 +1592,35 @@
internal_wait(tcp)
struct tcb *tcp;
{
- if (entering(tcp)) {
- /* WTA: fix bug with hanging children */
- if (!(tcp->u_arg[2] & WNOHANG) && tcp->nchildren > 0) {
+ if (entering(tcp) && tcp->nchildren > 0) {
+ /* There are children that this parent should block for.
+ But ptrace made us the parent of the traced children
+ and the real parent will get ECHILD from the wait call.
+
+ XXX If we attached with strace -f -p PID, then there
+ may be untraced dead children the parent could be reaping
+ now, but we make him block. */
+
+ /* ??? WTA: fix bug with hanging children */
+
+ if (!(tcp->u_arg[2] & WNOHANG)) {
/* There are traced children */
tcp->flags |= TCB_SUSPENDED;
tcp->waitpid = tcp->u_arg[0];
}
}
+ if (exiting(tcp) && tcp->u_error == ECHILD && tcp->nchildren > 0) {
+ if (tcp->u_arg[2] & WNOHANG) {
+ /* We must force a fake result of 0 instead of
+ the ECHILD error. */
+ extern int force_result();
+ return force_result(tcp, 0, 0);
+ }
+ else
+ fprintf(stderr,
+ "internal_wait: should not have resumed %d\n",
+ tcp->pid);
+ }
return 0;
}