On Fri, Dec 2, 2016 at 12:59 PM, Clark Wang <dearv...@gmail.com> wrote:
> On Fri, Dec 2, 2016 at 6:28 AM, Vladimir Marek <vladimir.ma...@oracle.com> > wrote: > >> Hi, >> >> I'm not sure what is going on, but the bash test suite was getting >> stopped (as if SIGSTOP was received) in the middle. Trying to find >> minimal set of conditions it came to this: >> >> - my ~/.bashrc has to contain 'cd /' (any dir works) >> - the tests have to first execute run-execscript, namely it has to >> execute exec6.sub, namely the line ${THIS_SH} -i ./exec8.sub >> - the file exec8.sub is reported as not found (I presume because of the >> 'cd /' in .bashrc) >> - the tests then have to run read-test, exactly in read2.sub when >> 'read -t 2 a < /dev/tty' was executed whole thing was stopped >> >> When I removed the 'cd' command from my ~/.bashrc, all worked fine. >> >> I then tried to make minimal reproducible case and came to this (this >> time there is no 'cd /' in my ~/.bashrc needed): >> >> $ bash -c 'bash -i i; bash -i i' >> bash -c 'bash -i i; bash -i i' >> bash: i: No such file or directory >> >> [1]+ Stopped bash -c 'bash -i i; bash -i i' >> > > I can reproduce this with bash 4.4.5 on Debian 8.5. > > foo@deb64:~$ bash -c 'bash -i 1; bash -i 2' > bash: 1: No such file or directory > > [1]+ Stopped bash -c 'bash -i 1; bash -i 2' > foo@deb64:~$ echo $? > 149 > > It was stopped by SIGTTIN. According to gdb backtrace it was killed by the > second "bash -i". > > 4099 while ((terminal_pgrp = tcgetpgrp (shell_tty)) != -1) > 4100 { > 4101 if (shell_pgrp != terminal_pgrp) > 4102 { > 4103 SigHandler *ottin; > 4104 > 4105 ottin = set_signal_handler (SIGTTIN, SIG_DFL); > 4106 kill (0, SIGTTIN); > 4107 set_signal_handler (SIGTTIN, ottin); > 4108 continue; > 4109 } > 4110 break; > 4111 } > > The problem is tcgetpgrp() still returns the pgrp of the first "bash -i" > when the second "bash -i" is running. This can be shown with following > example: > > foo@deb64:~$ bash -c 'bash -i 1; sleep 9999' > bash: 1: No such file or directory <-- CTRL-C does not work here > > root@deb64:~# ps t pts/10 j > PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND > 96886 96887 96887 96887 pts/10 97073 Ss 1001 0:00 -bash > 96887 97072 97072 96887 pts/10 97073 S 1001 0:00 bash -c > bash -i 1; sleep 9999 > 97072 97074 97072 96887 pts/10 97073 S 1001 0:00 sleep 9999 > > Here the TPGID 97073 must be the first "bash -i" which has already exited. > Seems like for some reason the "bash -c" does not set the foreground pgrp > to the second "bash -i". > Found the problem. The first "bash -i" changed the foreground pgrp to its own pgrp at startup but did not restore the original foreground pgrp when it exited. The following patch (not a real fix) works for me: --- a/shell.c +++ b/shell.c @@ -1504,6 +1504,7 @@ open_shell_script (script_name) { e = errno; file_error (filename); + end_job_control (); sh_exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT); }