ref: 3e907e648d7263c159c604dc51aa8ca5d5fcd7f8
parent: ab2af6895d0e66aa9e5a94f77c2ba132c08f28d8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jun 14 13:01:16 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/exec.c
+++ b/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/fns.h
+++ b/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/simple.c
+++ b/simple.c
@@ -18,7 +18,7 @@
loop:
c=&p->code[p->pc];
while(1){
- if(c->f==Xpopredir || c->f==Xunlocal)
+ if(c->f==Xpopredir || c->f==Xunlocal || c->f==Xeflag)
c++;
else if(c->f==Xsrcline)
c += 2;
@@ -86,7 +86,7 @@
(*f)();
return;
}
- if(exitnext()){
+ if(exitnext() && trapexit()==0){
/* fork and wait is redundant */
pushword("exec");
execexec();
--
⑨