[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Strange bash behavior

From: Clark Wang
Subject: Re: Strange bash behavior
Date: Fri, 2 Dec 2016 17:20:50 +0800

On Fri, Dec 2, 2016 at 12:59 PM, Clark Wang <address@hidden> wrote:
On Fri, Dec 2, 2016 at 6:28 AM, Vladimir Marek <address@hidden> wrote:

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.

  address@hidden:~$ 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'
  address@hidden:~$ echo $?

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

  address@hidden:~$ bash -c 'bash -i 1; sleep 9999'
  bash: 1: No such file or directory    <-- CTRL-C does not work here

  address@hidden:~# ps t pts/10 j
   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);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]