shithub: front

Download patch

ref: 30cccba7ec86185fa726c61a67560cf8406a6393
parent: 9ee2b3a6867504b2ad37c13f2ea9fe25a9165b64
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jun 14 12:59:25 EDT 2025

rc: fix fn sigexit handling (thanks nepomuk)

The sigexit pseudo note handler was only ran when we
did a explicit exit call, not when returning from
the last thread.

Also, the exitnext() check in Xsimple() that  avoids
an extra fork/wait must take into account if we need
to run the sigexit handler, so add a trapexit() function
that tells if we need to run the handler and skip
the optimization when we have to.

--- a/sys/src/cmd/rc/exec.c
+++ b/sys/src/cmd/rc/exec.c
@@ -386,22 +386,27 @@
 	if(!truestatus()) Xexit();
 }
 
+static int trapped;
+
+var*
+trapexit(void)
+{
+	if(getpid()==mypid && !trapped){
+		var *trap = vlook("sigexit");
+		if(trap->fn)
+			return trap;
+	}
+	return (var*)0;
+}
+
 void
 Xexit(void)
 {
-	static int beenhere = 0;
-
-	if(getpid()==mypid && !beenhere){
-		var *trapreq = vlook("sigexit");
-		word *starval = vlook("*")->val;
-		if(trapreq->fn){
-			beenhere = 1;
-			--runq->pc;
-			startfunc(trapreq, copywords(starval, (word*)0), (var*)0, (redir*)0);
-			return;
-		}
-	}
-	Exit();
+	var *trap = trapexit();
+	if(trap==0) Exit();
+	if(runq) --runq->pc;
+	startfunc(trap, copywords(vlook("*")->val, (word*)0), (var*)0, (redir*)0);
+	trapped = 1;
 }
 
 void
@@ -591,7 +596,7 @@
 		Xpopredir();
 	popthread();
 	if(runq==0)
-		Exit();
+		Xexit();
 }
 
 void
--- a/sys/src/cmd/rc/fns.h
+++ b/sys/src/cmd/rc/fns.h
@@ -63,6 +63,7 @@
 void	setstatus(char*);
 void	skipnl(void);
 void	start(code*, int, var*, redir*);
+var*	trapexit(void);
 int	truestatus(void);
 void	usage(char*);
 int	wordchr(int);
--- a/sys/src/cmd/rc/simple.c
+++ b/sys/src/cmd/rc/simple.c
@@ -86,7 +86,7 @@
 			(*f)();
 			return;
 		}
-		if(exitnext()){
+		if(exitnext() && trapexit()==0){
 			/* fork and wait is redundant */
 			pushword("exec");
 			execexec();
--