summaryrefslogtreecommitdiffstats
path: root/bin/sh/jobs.c
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2010-05-24 10:35:57 +0000
committerjilles <jilles@FreeBSD.org>2010-05-24 10:35:57 +0000
commit95d1dcb0f4a474d917cb01a3d515ea2850a0adca (patch)
treeabd3f97a6f2c812b44f66b1d435a7387dcf7b1da /bin/sh/jobs.c
parent70f08890fc1cf735f25aaa4982c4789edc7337f2 (diff)
downloadFreeBSD-src-95d1dcb0f4a474d917cb01a3d515ea2850a0adca.zip
FreeBSD-src-95d1dcb0f4a474d917cb01a3d515ea2850a0adca.tar.gz
sh: Reap any zombies before forking for a background command.
This prevents accumulating huge amounts of zombies if a script executes many background commands but no external commands or subshells. Note that zombies will not be reaped during long calculations (within the shell process) or read builtins, but those actions do not create more zombies. The terminated background commands will also still be remembered by the shell. PR: bin/55346
Diffstat (limited to 'bin/sh/jobs.c')
-rw-r--r--bin/sh/jobs.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index 6ba951c..d42848f 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -91,6 +91,7 @@ STATIC void freejob(struct job *);
STATIC struct job *getjob(char *);
STATIC pid_t dowait(int, struct job *);
STATIC pid_t waitproc(int, int *);
+STATIC void checkzombies(void);
STATIC void cmdtxt(union node *);
STATIC void cmdputs(const char *);
#if JOBS
@@ -400,7 +401,7 @@ showjobs(int change, int mode)
struct job *jp;
TRACE(("showjobs(%d) called\n", change));
- while (dowait(0, (struct job *)NULL) > 0);
+ checkzombies();
for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
if (! jp->used)
continue;
@@ -742,6 +743,8 @@ forkshell(struct job *jp, union node *n, int mode)
TRACE(("forkshell(%%%d, %p, %d) called\n", jp - jobtab, (void *)n,
mode));
INTOFF;
+ if (mode == FORK_BG)
+ checkzombies();
flushall();
pid = fork();
if (pid == -1) {
@@ -1056,6 +1059,15 @@ stoppedjobs(void)
return (0);
}
+
+STATIC void
+checkzombies(void)
+{
+ while (njobs > 0 && dowait(0, NULL) > 0)
+ ;
+}
+
+
/*
* Return a string identifying a command (to be printed by the
* jobs command.
OpenPOWER on IntegriCloud