diff mbox series

AT&T Unix PC : 11-simplify-wait-loop

Message ID 6bf2ff43-214d-4629-8998-f9ee32cf820e@knaff.lu (mailing list archive)
State Under Review
Delegated to: Herbert Xu
Headers show
Series AT&T Unix PC : 11-simplify-wait-loop | expand

Commit Message

Alain Knaff Nov. 17, 2024, 5:25 p.m. UTC
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 mbox series

Patch

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