diff mbox series

jobs: Preserve parent jobs for simple commands

Message ID Zh0XHZYkHvBUbHde@gondor.apana.org.au (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show
Series jobs: Preserve parent jobs for simple commands | expand

Commit Message

Herbert Xu April 15, 2024, 12:01 p.m. UTC
Do not free parent shell jobs if a simple command with the first
word being "jobs" is executed as a command substitution.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
 src/jobs.c   | 6 ++++++
 src/parser.c | 6 ++++++
 src/parser.h | 3 +++
 src/trap.c   | 5 +++--
 4 files changed, 18 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/src/jobs.c b/src/jobs.c
index dce8e22..7053e22 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -53,6 +53,7 @@ 
 #include <termios.h>
 #undef CEOF			/* syntax.h redefines this */
 #endif
+#include "builtins.h"
 #include "exec.h"
 #include "eval.h"
 #include "init.h"
@@ -913,6 +914,11 @@  static void forkchild(struct job *jp, union node *n, int mode)
 	if (lvforked)
 		return;
 
+	freejob(jp);
+
+	if (issimplecmd(n, JOBSCMD->name))
+		return;
+
 	for (jp = curjob; jp; jp = jp->prev_job)
 		freejob(jp);
 }
diff --git a/src/parser.c b/src/parser.c
index 299c260..f4d76c2 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -132,6 +132,12 @@  int isassignment(const char *p)
 	return *q == '=';
 }
 
+int issimplecmd(union node *n, const char *name)
+{
+	return n && n->type == NCMD && n->ncmd.args &&
+	       equal(n->ncmd.args->narg.text, name);
+}
+
 static inline int realeofmark(const char *eofmark)
 {
 	return eofmark && eofmark != FAKEEOFMARK;
diff --git a/src/parser.h b/src/parser.h
index 729c15c..433573d 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -36,6 +36,8 @@ 
 
 #include "token.h"
 
+union node;
+
 /* control characters in argument strings */
 #define CTL_FIRST -127		/* first 'special' character */
 #define CTLESC -127		/* escape next character */
@@ -85,6 +87,7 @@  extern int checkkwd;
 
 
 int isassignment(const char *p);
+int issimplecmd(union node *n, const char *name);
 union node *parsecmd(int);
 void fixredir(union node *, const char *, int);
 const char *getprompt(void *);
diff --git a/src/trap.c b/src/trap.c
index 525a009..0886619 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -37,6 +37,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 
+#include "builtins.h"
 #include "shell.h"
 #include "main.h"
 #include "nodes.h"	/* for other headers */
@@ -47,6 +48,7 @@ 
 #include "options.h"
 #include "syntax.h"
 #include "output.h"
+#include "parser.h"
 #include "memalloc.h"
 #include "error.h"
 #include "trap.h"
@@ -170,8 +172,7 @@  void clear_traps(union node *n)
 	int simplecmd;
 	char **tp;
 
-	simplecmd = n && n->type == NCMD && n->ncmd.args &&
-		    equal(n->ncmd.args->narg.text, "trap");
+	simplecmd = issimplecmd(n, TRAPCMD->name);
 
 	INTOFF;
 	for (tp = trap ; tp < &trap[NSIG] ; tp++) {