From 3c5732223f65309c6820f15b8519f674bd21185b Mon Sep 17 00:00:00 2001
From: Peter Stephenson
Date: Wed, 17 Jul 2013 21:33:16 +0100
Subject: 31528: use job table to record file descriptors associated with
process subst
---
ChangeLog | 4 ++++
Src/exec.c | 33 ++++++---------------------------
Src/jobs.c | 42 +++++++++++++++++++++++++++++++++++++-----
Src/zsh.h | 19 ++++++++++++++++---
4 files changed, 63 insertions(+), 35 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a2e4d120b..8d7e62a1b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2013-07-17 Peter Stephenson
+ * 31528: Src/exec.c, Src/jobs.c, Src/zsh.h: use job table
+ to record file descriptors associated with process
+ substitution.
+
* Jun T: 31525: Completion/Unix/Command/_make: fix some option
handling.
diff --git a/Src/exec.c b/Src/exec.c
index 75805d3f5..d462d97c6 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2860,9 +2860,6 @@ execcmd(Estate state, int input, int output, int how, int last1)
close(synch[1]);
read_loop(synch[0], &dummy, 1);
close(synch[0]);
-#ifdef PATH_DEV_FD
- closem(FDT_PROC_SUBST);
-#endif
if (how & Z_ASYNC) {
lastpid = (zlong) pid;
/* indicate it's possible to set status for lastpid */
@@ -3247,32 +3244,16 @@ execcmd(Estate state, int input, int output, int how, int last1)
if (is_shfunc) {
/* It's a shell function */
-#ifdef PATH_DEV_FD
- int i;
-
- for (i = 10; i <= max_zsh_fd; i++)
- if (fdtable[i] >= FDT_PROC_SUBST)
- fdtable[i]++;
-#endif
if (subsh_close >= 0)
zclose(subsh_close);
subsh_close = -1;
execshfunc((Shfunc) hn, args);
-#ifdef PATH_DEV_FD
- for (i = 10; i <= max_zsh_fd; i++)
- if (fdtable[i] >= FDT_PROC_SUBST)
- if (--(fdtable[i]) <= FDT_PROC_SUBST)
- zclose(i);
-#endif
} else {
/* It's a builtin */
if (forked)
closem(FDT_INTERNAL);
lastval = execbuiltin(args, (Builtin) hn);
-#ifdef PATH_DEV_FD
- closem(FDT_PROC_SUBST);
-#endif
fflush(stdout);
if (save[1] == -2) {
if (ferror(stdout)) {
@@ -3887,9 +3868,7 @@ getoutputfile(char *cmd, char **eptr)
untokenize(s);
}
- if (!jobtab[thisjob].filelist)
- jobtab[thisjob].filelist = znewlinklist();
- zaddlinknode(jobtab[thisjob].filelist, nam);
+ addfilelist(nam, 0);
if (!s)
child_block();
@@ -3975,9 +3954,7 @@ getproc(char *cmd, char **eptr)
return NULL;
if (!(prog = parsecmd(cmd, eptr)))
return NULL;
- if (!jobtab[thisjob].filelist)
- jobtab[thisjob].filelist = znewlinklist();
- zaddlinknode(jobtab[thisjob].filelist, ztrdup(pnam));
+ addfilelist(pnam, 0);
if ((pid = zfork(&bgtime))) {
if (pid == -1)
@@ -3995,7 +3972,7 @@ getproc(char *cmd, char **eptr)
entersubsh(ESUB_ASYNC|ESUB_PGRP);
redup(fd, out);
#else /* PATH_DEV_FD */
- int pipes[2];
+ int pipes[2], fd;
if (thisjob == -1)
return NULL;
@@ -4012,7 +3989,9 @@ getproc(char *cmd, char **eptr)
zclose(pipes[!out]);
return NULL;
}
- fdtable[pipes[!out]] = FDT_PROC_SUBST;
+ fd = pipes[!out];
+ fdtable[fd] = FDT_PROC_SUBST;
+ addfilelist(NULL, fd);
if (!out)
{
addproc(pid, NULL, 1, &bgtime);
diff --git a/Src/jobs.c b/Src/jobs.c
index 0dbb10b4f..a1955bb0f 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1113,16 +1113,48 @@ printjob(Job jn, int lng, int synch)
return doneprint;
}
+/* Add a file to be deleted or fd to be closed to the current job */
+
+/**/
+void
+addfilelist(const char *name, int fd)
+{
+ Jobfile jf = (Jobfile)zalloc(sizeof(struct jobfile));
+ LinkList ll = jobtab[thisjob].filelist;
+
+ if (!ll)
+ ll = jobtab[thisjob].filelist = znewlinklist();
+ if (name)
+ {
+ jf->u.name = ztrdup(name);
+ jf->is_fd = 0;
+ }
+ else
+ {
+ jf->u.fd = fd;
+ jf->is_fd = 1;
+ }
+ zaddlinknode(ll, jf);
+}
+
+/* Finished with list of files for a job */
+
/**/
void
deletefilelist(LinkList file_list, int disowning)
{
- char *s;
+ Jobfile jf;
if (file_list) {
- while ((s = (char *)getlinknode(file_list))) {
- if (!disowning)
- unlink(s);
- zsfree(s);
+ while ((jf = (Jobfile)getlinknode(file_list))) {
+ if (jf->is_fd) {
+ if (!disowning)
+ zclose(jf->u.fd);
+ } else {
+ if (!disowning)
+ unlink(jf->u.name);
+ zsfree(jf->u.name);
+ }
+ zfree(jf, sizeof(*jf));
}
zfree(file_list, sizeof(struct linklist));
}
diff --git a/Src/zsh.h b/Src/zsh.h
index 299357de8..ebd3cb75d 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -374,9 +374,8 @@ enum {
#ifdef PATH_DEV_FD
/*
* Entry used by a process substition.
- * The value will be incremented on entering a function and
- * decremented on exit; we don't close entries greater than
- * FDT_PROC_SUBST except when closing everything.
+ * This marker is not tested internally as we associated the file
+ * descriptor with a job for closing.
*/
#define FDT_PROC_SUBST 6
#endif
@@ -422,6 +421,7 @@ typedef struct heap *Heap;
typedef struct heapstack *Heapstack;
typedef struct histent *Histent;
typedef struct hookdef *Hookdef;
+typedef struct jobfile *Jobfile;
typedef struct job *Job;
typedef struct linkedmod *Linkedmod;
typedef struct linknode *LinkNode;
@@ -878,6 +878,18 @@ struct eccstr {
/* Definitions for job table and job control */
/********************************************/
+/* Entry in filelist linked list in job table */
+
+struct jobfile {
+ /* Record to be deleted or closed */
+ union {
+ char *name; /* Name of file to delete */
+ int fd; /* File descriptor to close */
+ } u;
+ /* Discriminant */
+ int is_fd;
+};
+
/* entry in the job table */
struct job {
@@ -889,6 +901,7 @@ struct job {
struct process *procs; /* list of processes */
struct process *auxprocs; /* auxiliary processes e.g multios */
LinkList filelist; /* list of files to delete when done */
+ /* elements are struct jobfile */
int stty_in_env; /* if STTY=... is present */
struct ttyinfo *ty; /* the modes specified by STTY */
};
--
cgit 1.4.1