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 --- Src/exec.c | 33 ++++++--------------------------- Src/jobs.c | 42 +++++++++++++++++++++++++++++++++++++----- Src/zsh.h | 19 ++++++++++++++++--- 3 files changed, 59 insertions(+), 35 deletions(-) (limited to 'Src') 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