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();
--
⑨