summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/jobs.c62
2 files changed, 40 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index 5181e859c..cc1080d21 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2003-02-21 Peter Stephenson <pws@csr.com>
+
+ * 18264: Src/jobs.c: free unused bits of job table properly
+ when we enter a subshell.
+
2003-02-21 Oliver Kiddle <opk@zsh.org>
* 18269: Completion/Unix/Command/_sccs: improve file completion
diff --git a/Src/jobs.c b/Src/jobs.c
index eb8d24450..fba7fd26e 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -789,30 +789,28 @@ deletefilelist(LinkList file_list)
/**/
void
-deletejob(Job jn)
+freejob(Job jn, int deleting)
{
struct process *pn, *nx;
- if (jn->stat & STAT_ATTACH) {
- attachtty(mypgrp);
- adjustwinsize(0);
- }
-
pn = jn->procs;
jn->procs = NULL;
for (; pn; pn = nx) {
nx = pn->next;
zfree(pn, sizeof(struct process));
}
- deletefilelist(jn->filelist);
if (jn->ty)
zfree(jn->ty, sizeof(struct ttyinfo));
if (jn->pwd)
zsfree(jn->pwd);
jn->pwd = NULL;
- if (jn->stat & STAT_WASSUPER)
- deletejob(jobtab + jn->other);
+ if (jn->stat & STAT_WASSUPER) {
+ if (deleting)
+ deletejob(jobtab + jn->other);
+ else
+ freejob(jobtab + jn->other, 0);
+ }
jn->gleader = jn->other = 0;
jn->stat = jn->stty_in_env = 0;
jn->procs = NULL;
@@ -820,6 +818,24 @@ deletejob(Job jn)
jn->ty = NULL;
}
+/*
+ * We are actually finished with this job, rather
+ * than freeing it to make space.
+ */
+
+/**/
+void
+deletejob(Job jn)
+{
+ deletefilelist(jn->filelist);
+ if (jn->stat & STAT_ATTACH) {
+ attachtty(mypgrp);
+ adjustwinsize(0);
+ }
+
+ freejob(jn, 1);
+}
+
/* add a process to the current job */
/**/
@@ -975,24 +991,16 @@ clearjobtab(int monitor)
int i;
for (i = 1; i < MAXJOB; i++) {
- if (jobtab[i].ty) {
- zfree(jobtab[i].ty, sizeof(struct ttyinfo));
- jobtab[i].ty = NULL;
- }
- if (jobtab[i].pwd) {
- zsfree(jobtab[i].pwd);
- jobtab[i].pwd = NULL;
- }
- if (monitor) {
- /*
- * See if there is a jobtable worth saving.
- * We never free the saved version; it only happens
- * once for each subshell of a shell with job control,
- * so doesn't create a leak.
- */
- if (jobtab[i].stat)
- oldmaxjob = i+1;
- }
+ /*
+ * See if there is a jobtable worth saving.
+ * We never free the saved version; it only happens
+ * once for each subshell of a shell with job control,
+ * so doesn't create a leak.
+ */
+ if (monitor && jobtab[i].stat)
+ oldmaxjob = i+1;
+ else if (jobtab[i].stat & STAT_INUSE)
+ freejob(jobtab + i, 0);
}
if (monitor && oldmaxjob) {