rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

commit 459dd7b4bc6225e712b25359785558cb61283113
parent 041360f4f34aad297b173e64e0a72956bd86415f
Author: Bert Münnich <ber.t@posteo.de>
Date:   Sun, 24 Mar 2019 14:32:23 +0100

Report children as soon as possible when waiting for all

The following example demonstrates the problem:

    ; false & sleep 300 & wait
    2317 # pid of false
    2318 # pid of sleep
    # blocking for 300s
    2318: done (0)
    2817: done (1)

With this commit the status for false is reported instantly:

    ; false & sleep 300 & wait
    4205 # pid of false
    4206 # pid of sleep
    4205: done (1)
    # blocking for 300s
    4206: done (0)

Diffstat:
Mwait.c | 31++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/wait.c b/wait.c @@ -48,15 +48,15 @@ extern pid_t rc_fork() { } extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) { - Pid *r, *prev; + Pid **p, *r; /* Find the child on the list. */ - for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n) - if (r->pid == pid) + for (p = &plist; *p; p = &(*p)->n) + if ((*p)->pid == pid || (pid == -1 && !(*p)->alive)) break; /* Uh-oh, not there. */ - if (r == NULL) { + if (pid != -1 && *p == NULL) { errno = ECHILD; /* no children */ uerror("wait"); *stat = 0x100; /* exit(1) */ @@ -64,9 +64,9 @@ extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) { } /* If it's still alive, wait() for it. */ - while (r->alive) { + while (*p == NULL || (*p)->alive) { int ret; - Pid *q; + Pid **q; ret = rc_wait(stat); @@ -79,18 +79,19 @@ extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) { return ret; } - for (q = plist; q != NULL; q = q->n) - if (q->pid == ret) { - q->alive = FALSE; - q->stat = *stat; + for (q = &plist; *q; q = &(*q)->n) + if ((*q)->pid == ret) { + if (pid == -1) + p = q; + (*q)->alive = FALSE; + (*q)->stat = *stat; break; } } + r = *p; + pid = r->pid; *stat = r->stat; - if (prev == NULL) - plist = r->n; /* remove element from head of list */ - else - prev->n = r->n; + *p = r->n; /* remove element from list */ efree(r); return pid; } @@ -115,7 +116,7 @@ extern void waitforall() { int stat; while (plist != NULL) { - pid_t pid = rc_wait4(plist->pid, &stat, FALSE); + pid_t pid = rc_wait4(-1, &stat, FALSE); if (pid > 0) setstatus(pid, stat); else {