Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug in sh emulation



(Sorry if you get this twice, but it kind of fits the theme.)

On Sat, 10 Dec 2011 19:40:22 +0000
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx> wrote:
>> emulate -sh '(echo | grep)'
>
> What's confusing me, possibly based on ignorance, is that I naively
> expect something like the following to happen (without my
> ultra-ultra-tentative patch).

I've examined this a bit further, and got to the point where my brain's
stopped working.

> - Shell forks.  This is treated pretty much like any other fork to
> create a new foreground process.
>
> - Job control is active, so the forked shell takes over the TTY and sets
> itself as the group leader.  That's the first time through the code
> under discussion, in entersubsh() for the case where MONITOR is still
> set.
> 
> - Shell forks again.  This is a pipeline, so part of the same process
> group.  I would expect this to find there is already a group leader from
> the previous fork, so this process doesn't try to make itself group
> leader and grab the pipeline.  Evidently this isn't happening,
> however.

I think what's happening is

- We entersubsh() for the initial fork for the subshell.  This sets job
  1 as group leader and attaches that to the TTY.   This is the normal
  case; what's different at this point is simply that we leave MONITOR
  set.

- We execlist() to run the list for the subshell.

- In execpline() we set the job to 2; execpline() always starts a new
  job.

- We get execmd() to start the pipeline.  We fork because we're
  executing the first command of a pipeline.  All basically as
  expected so far.

- We entersubsh() again.  MONITOR is still set (this is where the
  difference really kicks in) so we execute the code for handling the
  tty again.  We're now job 2, so no group leader for this.  We create a
  new group leader, and try to attach this to the tty, but we can't
  because job 1 is attached to it.

- Something goes KAPOW! loudly in some moral sense.

I suppose the problem is we're doing the attach in the wrong way.
Normally we make the parent shell hand over the terminal to the
appropriate job (er, right?  that's basically what job control is?)  In
this case we grab it from the subprocess.  That blows up when
subprocesses themselves are doing job control --- they should be handing
it on to their subprocesses.  Er... maybe?  So what's with the stuff in
entersubsh() that we always execute anyway, and successfully does
atttachtty() the first time?  Should we really have done that in the
parent shell?

I wonder if this is related to the business with the "superjob" in the
case of a non-subshell that I never understood?  There's code in
handle_sub() in jobs.c line 278 that looks like it might be trying to do
something like what we need to do here.

Confused of Cambridge

-- 
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