summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scsh-process.scm30
1 files changed, 20 insertions, 10 deletions
diff --git a/scsh-process.scm b/scsh-process.scm
index e2be39c..4153c00 100644
--- a/scsh-process.scm
+++ b/scsh-process.scm
@@ -115,7 +115,12 @@
(error 'process-wait
"Not a scsh-type process object or pid"
pid-or-process))
- (let ((p (if (and pid-or-process (number? pid-or-process))
+ ;; We need to make a copy because when waiting for #f, we
+ ;; can't predict which pid we'll receive, and the SIGCHLD
+ ;; handler will drop the pid from the pending list.
+ (let ((pending-before
+ (hash-table-copy *scsh-pending-processes*))
+ (p (if (and pid-or-process (number? pid-or-process))
(hash-table-ref/default *scsh-pending-processes*
pid-or-process #f)
pid-or-process)))
@@ -138,16 +143,21 @@
(scsh-process-pid p))
(abort exn))
(receive (pid ok? status)
- (posix-process-wait (and p (scsh-process-pid p)) nohang)
+ (posix-process-wait (if p
+ (scsh-process-pid p)
+ pid-or-process) nohang)
(cond
((zero? pid) (values #f #f #f))
- (else (when p
- (scsh-process-exit-status-set! p status)
- (scsh-process-ok?-set! p ok?)
- (condition-variable-broadcast!
- (scsh-process-child-condition p)))
- (remove-scsh-pending-process! pid)
- (values status ok? pid))))))))))
+ (else
+ (and-let* ((p (or p (hash-table-ref/default
+ pending-before pid #f))))
+ (scsh-process-exit-status-set! p status)
+ (scsh-process-ok?-set! p ok?)
+ (condition-variable-broadcast!
+ (scsh-process-child-condition p)))
+
+ (remove-scsh-pending-process! pid)
+ (values status ok? pid))))))))))
(set-signal-handler!
signal/chld
@@ -163,7 +173,7 @@
(for-each (lambda (pid)
(handle-exceptions exn
;; User might have waited manually
- (begin (remove-scsh-pending-process! pid) (void))
+ (begin (remove-scsh-pending-process! pid) (void))
(receive (pid ok? status)
(posix-process-wait pid #t)
(unless (zero? pid)