From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26438 invoked by alias); 28 Aug 2011 16:19:36 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 16289 Received: (qmail 13228 invoked from network); 28 Aug 2011 16:19:33 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.6 required=5.0 tests=BAYES_00,PLING_QUERY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 Received-SPF: neutral (ns1.primenet.com.au: 74.125.82.171 is neither permitted nor denied by SPF record at ntlworld.com) X-ProxyUser-IP: 81.97.71.129 Date: Sun, 28 Aug 2011 17:19:25 +0100 From: Peter Stephenson To: zsh-users Subject: Re: =() and &! don't go together? Message-ID: <20110828171925.0b1510ea@pws-pc.ntlworld.com> In-Reply-To: <878vqhivmm.fsf@gmail.com> References: <878vqhivmm.fsf@gmail.com> X-Mailer: Claws Mail 3.7.9 (GTK+ 2.24.4; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Thu, 25 Aug 2011 13:22:09 +0200 =C5=A0t=C4=9Bp=C3=A1n N=C4=9Bmec wrote: > It looks like when &! is used (i.e., "program =3D(computation) &!"), the > temporary file created by =3D() does not exist at the point the command > tries to access it. Is there a solution to this? I think the basic problem here is that =3D(...) uses a temporary file, and if you've told the shell to forget about the process it's just created there's nothing to tidy up the temporary file. I would have guessed it would simply not tidy up the file at all, however instead it seems it tidies it up even before it's used, which doesn't seem particularly useful. You can work around both problems with (program =3D(computation)) &! In this case, the subshell will hang around to tidy up the temporary file. The following patch does what I think is the best we can, namely just leave the files lying around but document the fact and the workaround. Index: Doc/Zsh/expn.yo =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v retrieving revision 1.139 diff -p -u -r1.139 expn.yo --- Doc/Zsh/expn.yo 14 Aug 2011 23:19:22 -0000 1.139 +++ Doc/Zsh/expn.yo 28 Aug 2011 16:15:23 -0000 @@ -471,6 +471,18 @@ example(tt({ paste pc++; =20 if (!list_pipe && thisjob !=3D list_pipe_job && !hasprocs(thisjob)) - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); cmdpush(CS_CURSH); execlist(state, 1, do_exec); cmdpop(); @@ -1434,7 +1434,7 @@ execpline(Estate state, wordcode slcode, zclose(opipe[0]); } if (how & Z_DISOWN) { - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 1); thisjob =3D -1; } else @@ -1484,7 +1484,7 @@ execpline(Estate state, wordcode slcode, printjob(jn, !!isset(LONGLISTJOBS), 1); } else if (newjob !=3D list_pipe_job) - deletejob(jn); + deletejob(jn, 0); else lastwj =3D -1; } @@ -1588,7 +1588,7 @@ execpline(Estate state, wordcode slcode, =20 if (list_pipe && (lastval & 0200) && pj >=3D 0 && (!(jn->stat & STAT_INUSE) || (jn->stat & STAT_DONE))) { - deletejob(jn); + deletejob(jn, 0); jn =3D jobtab + pj; if (jn->gleader) killjb(jn, lastval & ~0200); @@ -1596,7 +1596,7 @@ execpline(Estate state, wordcode slcode, if (list_pipe_child || ((jn->stat & STAT_DONE) && (list_pipe || (pline_level && !(jn->stat & STAT_SUBJOB))))) - deletejob(jn); + deletejob(jn, 0); thisjob =3D pj; =20 } @@ -4271,7 +4271,7 @@ execshfunc(Shfunc shf, LinkList args) * would be filled by a recursive function. */ last_file_list =3D jobtab[thisjob].filelist; jobtab[thisjob].filelist =3D NULL; - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); } =20 if (isset(XTRACE)) { @@ -4300,7 +4300,7 @@ execshfunc(Shfunc shf, LinkList args) cmdsp =3D ocsp; =20 if (!list_pipe) - deletefilelist(last_file_list); + deletefilelist(last_file_list, 0); } =20 /* Function to execute the special type of command that represents an * Index: Src/jobs.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v retrieving revision 1.87 diff -p -u -r1.87 jobs.c --- Src/jobs.c 16 Aug 2011 15:27:08 -0000 1.87 +++ Src/jobs.c 28 Aug 2011 16:15:23 -0000 @@ -269,7 +269,7 @@ handle_sub(int job, int fg) sleep, the rest will be executed by a sub-shell, but the parent shell gets notified for the sleep. - deletejob(sj); */ + deletejob(sj, 0); */ /* If this super-job contains only the sub-shell, we have to attach the tty to its process group now. */ @@ -955,7 +955,7 @@ printjob(Job jn, int lng, int synch) if (jn->stat & STAT_DONE) { if (should_report_time(jn)) dumptime(jn); - deletejob(jn); + deletejob(jn, 0); if (job =3D=3D curjob) { curjob =3D prevjob; prevjob =3D job; @@ -1085,7 +1085,7 @@ printjob(Job jn, int lng, int synch) if (jn->stat & STAT_DONE) { if (should_report_time(jn)) dumptime(jn); - deletejob(jn); + deletejob(jn, 0); if (job =3D=3D curjob) { curjob =3D prevjob; prevjob =3D job; @@ -1100,12 +1100,13 @@ printjob(Job jn, int lng, int synch) =20 /**/ void -deletefilelist(LinkList file_list) +deletefilelist(LinkList file_list, int disowning) { char *s; if (file_list) { while ((s =3D (char *)getlinknode(file_list))) { - unlink(s); + if (!disowning) + unlink(s); zsfree(s); } zfree(file_list, sizeof(struct linklist)); @@ -1141,7 +1142,7 @@ freejob(Job jn, int deleting) /* careful in case we shrink and move the job table */ int job =3D jn - jobtab; if (deleting) - deletejob(jobtab + jn->other); + deletejob(jobtab + jn->other, 0); else freejob(jobtab + jn->other, 0); jn =3D jobtab + job; @@ -1161,13 +1162,17 @@ freejob(Job jn, int deleting) /* * We are actually finished with this job, rather * 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. */ =20 /**/ void -deletejob(Job jn) +deletejob(Job jn, int disowning) { - deletefilelist(jn->filelist); + deletefilelist(jn->filelist, disowning); if (jn->stat & STAT_ATTACH) { attachtty(mypgrp); adjustwinsize(0); @@ -1343,7 +1348,7 @@ zwaitjob(int job, int wait_cmd) child_block(); } } else { - deletejob(jn); + deletejob(jn, 0); pipestats[0] =3D lastval; numpipestats =3D 1; } @@ -1366,7 +1371,7 @@ waitjobs(void) if (jn->procs || jn->auxprocs) zwaitjob(thisjob, 0); else { - deletejob(jn); + deletejob(jn, 0); pipestats[0] =3D lastval; numpipestats =3D 1; } @@ -1494,7 +1499,7 @@ spawnjob(void) } } if (!hasprocs(thisjob)) - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); else jobtab[thisjob].stat |=3D STAT_LOCKED; thisjob =3D -1; @@ -2070,7 +2075,7 @@ bin_fg(char *name, char **argv, Options=20 waitjobs(); retval =3D lastval2; } else if (ofunc =3D=3D BIN_DISOWN) - deletejob(jobtab + job); + deletejob(jobtab + job, 1); break; case BIN_JOBS: printjob(job + (oldjobtab ? oldjobtab : jobtab), lng, 2); @@ -2106,7 +2111,7 @@ bin_fg(char *name, char **argv, Options=20 #endif pids); } - deletejob(jobtab + job); + deletejob(jobtab + job, 1); break; } thisjob =3D ocj; =20 --=20 Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/