Subject: Re: Weird issue with pipeviewer and multiple pipes
From: Bart Schaefer <[email-masked]>
To: Jason L Tibbitts III <[email-masked]>
Cc: Zsh hackers list <[email-masked]>
Date: Tue, 3 May 2016 20:56:14 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Tue, May 3, 2016 at 6:15 PM, Jason L Tibbitts III <[email-masked]> wrote:
>
> [2]  + 11459 done                    echo 1 |
>        11461 suspended (tty output)  pv -l -s $(echo 1) |
>        11462 interrupt               cat

Something weird is definitely going on with pv, because it's receiving
a TTOU signal even when the terminal stty setting is supposed to
suppress that.

It doesn't happen with "-s 1" in place of the $(echo 1) substitution,
but it also doesn't happen if pv is replaced by e.g. tee $(echo
/dev/fd/2), so it's some combination of using command substitution and
something pv is doing.  By examination of strace output, it has to be
ioctl(2, TCSETS, ...).

So what is pv doing with that ioctl()?  (There doesn't seem to be a
way to get strace to both print the entire structure and decode it
from hexadecimal.)  I suspect that it's putting itself in its own
process group, which means that kills of the parent job don't reach it
any longer, which is why zsh ends up waiting forever when it tries to
resume the whole pipeline.  But I don't know why the $(echo) makes any
difference to it receiving the TTOU in the first place.

All of these also avoid the problem:

    echo 1 | { trap '' TTOU ; pv -p -s $(echo 1) } | cat
    echo 1 | pv -p -s $(echo 1) 2>/dev/tty | cat
    echo 1 | { x=$(echo 1); pv -p -s $x } | cat

> If I type fg, the shell is pretty much hung.  You have to kill -9 the pv
> process either way to get rid of the job.  (Lesser kills don't seem to
> work.)

Lesser kills do work, you just have to follow them with -CONT to
resume the stopped process; e.g. with GNU killall,
  killall pv
  killall -CONT pv