Hi,
Currently, the "wait" shell builtin is implemented by calling wait3
non-blockingly, and relying on a subsequent sigsuspend to do the
actual waiting.
This is needlessly complex, wait3 can do the job just fine on its
own. Wait_cmd can still be interrupted by a ctrl-c signal. Indeed,
that's what EINTR is for... just test for !pending_sig, like done
elsewhere in dash.
Return of 0 for DOWAIT_WAITCMD is now done using an explicit test
before return of the function.
Regards,
Alain
diff -X ../exclude.txt -urN dash-0.5.12+10-ctype/src/jobs.c dash-0.5.12+11-simplify-wait-loop/src/jobs.c
--- dash-0.5.12+10-ctype/src/jobs.c 2024-10-27 20:11:44.570509446 +0000
+++ dash-0.5.12+11-simplify-wait-loop/src/jobs.c 2024-10-27 20:11:58.026830752 +0000
@@ -1173,8 +1173,7 @@
STATIC int
waitproc(int block, int *status)
{
- sigset_t oldmask;
- int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG;
+ int flags = block != DOWAIT_NONBLOCK ? 0 : WNOHANG;
int err;
#if JOBS
@@ -1186,19 +1185,19 @@
gotsigchld = 0;
do
err = wait3(status, flags, NULL);
- while (err < 0 && errno == EINTR);
+ while (err < 0 && errno == EINTR && !pending_sig);
if (err || (err = -!block))
break;
- sigblockall(&oldmask);
-
- while (!gotsigchld && !pending_sig)
- sigsuspend(&oldmask);
-
- sigclearmask();
} while (gotsigchld);
+ if(block == DOWAIT_WAITCMD &&
+ err < 0 && errno == EINTR && pending_sig)
+ /* If block is DOWAIT_WAITCMD, we return 0 when a signal
+ * other than SIGCHLD interrupted the wait. */
+ return 0;
+
return err;
}