1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-05 11:01:13 +02:00

users/16289: don't delete temporary files on disown.

Document.
This commit is contained in:
Peter Stephenson 2011-08-28 16:38:28 +00:00
parent c4beabbc64
commit ca7269e82d
4 changed files with 43 additions and 21 deletions

View file

@ -1,3 +1,8 @@
2011-08-28 Peter Stephenson <p.w.stephenson@ntlworld.com>
* users/16289: Doc/Zsh/expn.yo, Src/exec.c, Src/jobs.c: don't
delete temporary files when disowning and document this.
2011-08-20 Barton E. Schaefer <schaefer@brasslantern.com> 2011-08-20 Barton E. Schaefer <schaefer@brasslantern.com>
* unposted: Functions/Zle/.distfiles: add move-line-in-buffer * unposted: Functions/Zle/.distfiles: add move-line-in-buffer
@ -15330,5 +15335,5 @@
***************************************************** *****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL * This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.5445 $ * $Revision: 1.5446 $
***************************************************** *****************************************************

View file

@ -471,6 +471,18 @@ example(tt({ paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2
The extra processes here are The extra processes here are
spawned from the parent shell which will wait for their completion. spawned from the parent shell which will wait for their completion.
Another problem arises any time a job with a substitution that requires
a temporary file is disowned by the shell, including the case where
`tt(&!)' or `tt(&|)' appears at the end of a command containing a
subsitution. In that case the temporary file will not be cleaned up as
the shell no longer has any memory of the job. A workaround is to use
a subshell, for example,
example(LPAR()mycmd =(myoutput)RPAR() &!)
as the forked subshell will wait for the command to finish then remove
the temporary file.
texinode(Parameter Expansion)(Command Substitution)(Process Substitution)(Expansion) texinode(Parameter Expansion)(Command Substitution)(Process Substitution)(Expansion)
sect(Parameter Expansion) sect(Parameter Expansion)
cindex(parameter expansion) cindex(parameter expansion)

View file

@ -405,7 +405,7 @@ execcursh(Estate state, int do_exec)
state->pc++; state->pc++;
if (!list_pipe && thisjob != list_pipe_job && !hasprocs(thisjob)) if (!list_pipe && thisjob != list_pipe_job && !hasprocs(thisjob))
deletejob(jobtab + thisjob); deletejob(jobtab + thisjob, 0);
cmdpush(CS_CURSH); cmdpush(CS_CURSH);
execlist(state, 1, do_exec); execlist(state, 1, do_exec);
cmdpop(); cmdpop();
@ -1434,7 +1434,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
zclose(opipe[0]); zclose(opipe[0]);
} }
if (how & Z_DISOWN) { if (how & Z_DISOWN) {
deletejob(jobtab + thisjob); deletejob(jobtab + thisjob, 1);
thisjob = -1; thisjob = -1;
} }
else else
@ -1484,7 +1484,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
printjob(jn, !!isset(LONGLISTJOBS), 1); printjob(jn, !!isset(LONGLISTJOBS), 1);
} }
else if (newjob != list_pipe_job) else if (newjob != list_pipe_job)
deletejob(jn); deletejob(jn, 0);
else else
lastwj = -1; lastwj = -1;
} }
@ -1588,7 +1588,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
if (list_pipe && (lastval & 0200) && pj >= 0 && if (list_pipe && (lastval & 0200) && pj >= 0 &&
(!(jn->stat & STAT_INUSE) || (jn->stat & STAT_DONE))) { (!(jn->stat & STAT_INUSE) || (jn->stat & STAT_DONE))) {
deletejob(jn); deletejob(jn, 0);
jn = jobtab + pj; jn = jobtab + pj;
if (jn->gleader) if (jn->gleader)
killjb(jn, lastval & ~0200); killjb(jn, lastval & ~0200);
@ -1596,7 +1596,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
if (list_pipe_child || if (list_pipe_child ||
((jn->stat & STAT_DONE) && ((jn->stat & STAT_DONE) &&
(list_pipe || (pline_level && !(jn->stat & STAT_SUBJOB))))) (list_pipe || (pline_level && !(jn->stat & STAT_SUBJOB)))))
deletejob(jn); deletejob(jn, 0);
thisjob = pj; thisjob = pj;
} }
@ -4271,7 +4271,7 @@ execshfunc(Shfunc shf, LinkList args)
* would be filled by a recursive function. */ * would be filled by a recursive function. */
last_file_list = jobtab[thisjob].filelist; last_file_list = jobtab[thisjob].filelist;
jobtab[thisjob].filelist = NULL; jobtab[thisjob].filelist = NULL;
deletejob(jobtab + thisjob); deletejob(jobtab + thisjob, 0);
} }
if (isset(XTRACE)) { if (isset(XTRACE)) {
@ -4300,7 +4300,7 @@ execshfunc(Shfunc shf, LinkList args)
cmdsp = ocsp; cmdsp = ocsp;
if (!list_pipe) if (!list_pipe)
deletefilelist(last_file_list); deletefilelist(last_file_list, 0);
} }
/* Function to execute the special type of command that represents an * /* Function to execute the special type of command that represents an *

View file

@ -269,7 +269,7 @@ handle_sub(int job, int fg)
sleep, the rest will be executed by a sub-shell, sleep, the rest will be executed by a sub-shell,
but the parent shell gets notified for the but the parent shell gets notified for the
sleep. sleep.
deletejob(sj); */ deletejob(sj, 0); */
/* If this super-job contains only the sub-shell, /* If this super-job contains only the sub-shell,
we have to attach the tty to its process group we have to attach the tty to its process group
now. */ now. */
@ -955,7 +955,7 @@ printjob(Job jn, int lng, int synch)
if (jn->stat & STAT_DONE) { if (jn->stat & STAT_DONE) {
if (should_report_time(jn)) if (should_report_time(jn))
dumptime(jn); dumptime(jn);
deletejob(jn); deletejob(jn, 0);
if (job == curjob) { if (job == curjob) {
curjob = prevjob; curjob = prevjob;
prevjob = job; prevjob = job;
@ -1085,7 +1085,7 @@ printjob(Job jn, int lng, int synch)
if (jn->stat & STAT_DONE) { if (jn->stat & STAT_DONE) {
if (should_report_time(jn)) if (should_report_time(jn))
dumptime(jn); dumptime(jn);
deletejob(jn); deletejob(jn, 0);
if (job == curjob) { if (job == curjob) {
curjob = prevjob; curjob = prevjob;
prevjob = job; prevjob = job;
@ -1100,11 +1100,12 @@ printjob(Job jn, int lng, int synch)
/**/ /**/
void void
deletefilelist(LinkList file_list) deletefilelist(LinkList file_list, int disowning)
{ {
char *s; char *s;
if (file_list) { if (file_list) {
while ((s = (char *)getlinknode(file_list))) { while ((s = (char *)getlinknode(file_list))) {
if (!disowning)
unlink(s); unlink(s);
zsfree(s); zsfree(s);
} }
@ -1141,7 +1142,7 @@ freejob(Job jn, int deleting)
/* careful in case we shrink and move the job table */ /* careful in case we shrink and move the job table */
int job = jn - jobtab; int job = jn - jobtab;
if (deleting) if (deleting)
deletejob(jobtab + jn->other); deletejob(jobtab + jn->other, 0);
else else
freejob(jobtab + jn->other, 0); freejob(jobtab + jn->other, 0);
jn = jobtab + job; jn = jobtab + job;
@ -1161,13 +1162,17 @@ freejob(Job jn, int deleting)
/* /*
* We are actually finished with this job, rather * We are actually finished with this job, rather
* than freeing it to make space. * than freeing it to make space.
*
* If "disowning" is set, files associated with the job are not
* actually deleted --- and won't be as there is nothing left
* to clear up.
*/ */
/**/ /**/
void void
deletejob(Job jn) deletejob(Job jn, int disowning)
{ {
deletefilelist(jn->filelist); deletefilelist(jn->filelist, disowning);
if (jn->stat & STAT_ATTACH) { if (jn->stat & STAT_ATTACH) {
attachtty(mypgrp); attachtty(mypgrp);
adjustwinsize(0); adjustwinsize(0);
@ -1343,7 +1348,7 @@ zwaitjob(int job, int wait_cmd)
child_block(); child_block();
} }
} else { } else {
deletejob(jn); deletejob(jn, 0);
pipestats[0] = lastval; pipestats[0] = lastval;
numpipestats = 1; numpipestats = 1;
} }
@ -1366,7 +1371,7 @@ waitjobs(void)
if (jn->procs || jn->auxprocs) if (jn->procs || jn->auxprocs)
zwaitjob(thisjob, 0); zwaitjob(thisjob, 0);
else { else {
deletejob(jn); deletejob(jn, 0);
pipestats[0] = lastval; pipestats[0] = lastval;
numpipestats = 1; numpipestats = 1;
} }
@ -1494,7 +1499,7 @@ spawnjob(void)
} }
} }
if (!hasprocs(thisjob)) if (!hasprocs(thisjob))
deletejob(jobtab + thisjob); deletejob(jobtab + thisjob, 0);
else else
jobtab[thisjob].stat |= STAT_LOCKED; jobtab[thisjob].stat |= STAT_LOCKED;
thisjob = -1; thisjob = -1;
@ -2070,7 +2075,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
waitjobs(); waitjobs();
retval = lastval2; retval = lastval2;
} else if (ofunc == BIN_DISOWN) } else if (ofunc == BIN_DISOWN)
deletejob(jobtab + job); deletejob(jobtab + job, 1);
break; break;
case BIN_JOBS: case BIN_JOBS:
printjob(job + (oldjobtab ? oldjobtab : jobtab), lng, 2); printjob(job + (oldjobtab ? oldjobtab : jobtab), lng, 2);
@ -2106,7 +2111,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
#endif #endif
pids); pids);
} }
deletejob(jobtab + job); deletejob(jobtab + job, 1);
break; break;
} }
thisjob = ocj; thisjob = ocj;