Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: How to misplace an entire pipeline
On Sun, 07 Aug 2011 21:05:07 -0700
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> The following is clearly not a complete fix and maybe is even wrong if
> a different problem is fixed elsewhere, but this at least allows the
> suspended pipeline to be manipulated with jobs/fg/bg/wait.
>
> --- ../zsh-forge/current/Src/exec.c 2011-07-27 01:13:48.000000000 -0700
> +++ Src/exec.c 2011-08-07 19:07:59.000000000 -0700
> @@ -2845,7 +2845,9 @@
> /* This is a current shell procedure that didn't need to fork. *
> * This includes current shell procedures that are being exec'ed, *
> * as well as null execs. */
> - jobtab[thisjob].stat |= STAT_CURSH|STAT_NOPRINT;
> + jobtab[thisjob].stat |= STAT_CURSH;
> + if (!jobtab[thisjob].procs)
> + jobtab[thisjob].stat |= STAT_NOPRINT;
> } else {
> /* This is an exec (real or fake) for an external command. *
> * Note that any form of exec means that the subshell is fake *
Looks fairly plausible, anyway.
> When "read" is the tail of the pipe, the above all happens behind the
> scenes and then the I/O system call gets restarted, which is how the
> shell ends up stuck. I'm not sure how to escape from that, except
> maybe to have zhandler() kill the shell with a different signal from
> which the system call will not recover.
I suppose so. I can hardly believe this ever worked.
> When something like "true" is the tail of the pipe, we return into
> execpline at line 1500 (from waitjobs()), where list_pipe_job is set
> but list_pipe and list_pipe_child are not. If all three were nonzero,
> a dummy shell would be forked off as PWS described to act as the
> suspended job, but instead execpline() simply returns because the
> last job in the pipeline has exited.
>
> The only obvious thing I can think to do here is to note in zhandler()
> that we have STAT_CURSH but not list_pipe, and therefore SIGCONT the
> left-hand-side immediately and return as if no signal had occurred
> (possibly printing a warning about not being able to suspend the job,
> which is what happens elsewhere if pipe() or fork() fails). However,
> that could lead to a serious busy-loop if somehow TTIN or TTOU was
> the signal instead of TSTP.
But we can test if it's TSTP (or STOP)?
There are so many special cases here --- there's one for each state the
current shell might be in during the process, each of which would be
handled straighforwardly if the processing was in another shell --- that
even if it sometimes worked before it's not that surprising if it's
sensitive to knock-on effects. I suppose it would be nice to be able to
test the things that seem to be working, at least, which would need some
care and probably a bit of extra test framework.
--
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
Messages sorted by:
Reverse Date,
Date,
Thread,
Author