Subject: Re: use of "less" in function and interrupt
From: Bart Schaefer <[email-masked]>
To: [email-masked]
Date: Wed, 20 Jul 2016 20:40:47 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Jul 20,  1:21pm, Peter Stephenson wrote:
} Subject: Re: use of "less" in function and interrupt
}
} On Wed, 20 Jul 2016 13:36:33 +0200
} Vincent Lefevre <[email-masked]> wrote:
} > With zsh 5.2, if I type:
} > 
} > zira% tless() { less "$@"; }
} > zira% sleep 5 | tless
} > 
} > then "less" is left stopped in background after I type a key.

After you type ^C, you mean?

} Interestingly, I can get this to happen with
} 
} sleep 5 | { less }

In both cases it works as expected provided that "sleep 5" has exited,
so you have to interrupt the sleep.

} but not
} 
} sleep 5 | ( less )
} 
} I'm not sure what that says about job control, which I've never really
} understood, but the two cases should be very close as in the second the
} shell knows it's about to exit and should exec less without an extra
} fork.

I believe the difference is that in both the functin case and the curly
brackets case you have a "current shell job" at the tail of the pipeline;
"less" is a subjob of that current shell job.  In the other cases you
have a true external job at the end of the pipeline; you're correct that
the subshell exec's less, so it's equivalent to piping directly to less.

} I'm guessing that in the failing cases less is somehow being
} detached from the terminal while in the other cases it isn't and, when
} you quit less, normal service is resumed.

Pretty much, yes.  I think what's happening is that the "current shell
job" is noticing that a ^C was delivered and therefore stops waiting
for its subjobs, not noticing that that "less" has ignored the signal
and continued on anyway.

Probably there's some point where the one last wait is needed, within
the cleanup of jobs in the current shell, to make sure that all the
subjobs really did go away.  I suspect this to be related to the
breakup of errflag into ERRFLAG_ERROR and ERRFLAG_INT.