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; }