This is the mail archive of the
cygwin-developers@cygwin.com
mailing list for the Cygwin project.
Getting the terminal while in the background.
- From: "Pierre A. Humblet" <Pierre dot Humblet at ieee dot org>
- To: chet at po dot cwru dot edu
- Cc: cygwin-developers at cygwin dot com,ronald at landheer dot com
- Date: Tue, 28 Sep 2004 23:29:25 -0400
- Subject: Getting the terminal while in the background.
Chet,
Under Cygwin, the command below gives rise to a warning:
~: true | `echo true` &
[1] 380723
~: Use "logout" to leave the shell.
[1]+ Done true | `echo true`
I found the explanation, please bear with me.
There are 4 processe involved:
the main interactive pid M
a subprocess A evaluating the first true,
a subprocess B evaluating `echo true',
which still has "interactive" = 1,
and forking a subprocess C that evaluates the second true.
What's happening is that process B has
subshell_environment 0x18 = SUBSHELL_PIPE | SUBSHELL_FORK
Accordingly in command_substitute() it sees
if ((subshell_environment & SUBSHELL_PIPE) == 0)
pipeline_pgrp = shell_pgrp;
and it does NOT set pipeline_pgrp to shell_pgrp.
It then calls make_child() with async_p = 0.
In the child part of make_child(), subprocess C
sees [PGRP_PIPE is not defined on Cygwin]
if (async_p == 0 && pipeline_pgrp != shell_pgrp)
give_terminal_to (pipeline_pgrp, 0);
and it dutifully gives the terminal to the background pipeline_pgrp,
which isn't right.
The comment below suggests that we should have pipeline_pgrp == shell_pgrp
for command substitution...
/* By convention (and assumption above), if
pipeline_pgrp == shell_pgrp, we are making a child for
command substitution.
Meanwhile process B does a wait_for(C), which returns
the terminal to the top shell_pgrp. However toward the end
of command_substitute() it sees
if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
#endif
give_terminal_to (pipeline_pgrp, 0);
and it gives control to the pipeline_pgrp.
This directly contradicts the adjoining comment:
/* ..
pipeline was started in the background. A pipeline started in
the background should never get the tty back here. */
The error message is produced when a read() fails with EIO because
the main shell does not have the terminal.
getc_with_restart() translates the error to an EOF.
I don't know why the error does not show up on other systems,
but I don't see anything unusual in Cygwin that explains
the incorrect behavior outlined above.
Regards,
Pierre