Re: bug in force_interactive handling

2012-01-05 Thread Stas Sergeev

05.01.2012 06:50, Chet Ramey wrote:

So you'd like the shell to act on a signal without `consulting' the
foreground job?

For only the dedicated traps. For example:
trap -b /bin/true USR1

-b here would mean that the foreground job, if
any, is to be moved to the background before
executing the command. Since the command is
not really needed (I only need to move the job
to the background), I specified /bin/true as an
example, and in my previous example I used
bg which was not needed too.



Re: bug in force_interactive handling

2012-01-04 Thread Stas Sergeev

03.01.2012 00:07, Chet Ramey wrote:

I tried:
---
trap bg USR1
---
Now if I first send SIGSTOP to the job and then SIGUSR1 to
bash, that works.
Is it possible to avoid sending SIGSTOP to the job, and make
the trap handler to do both things at once? Not that it is strictly
required since you already described a few other ways, but I wonder. :)

Well, this is getting pretty esoteric.  On one hand, you can avoid the
entire SIGSTOP/SIGCONT issue by initially starting the job in the
background with `'.  On the other, if you want to move a foreground
job to the background, you have to get it to give up control somehow, and
sending it a signal is the way to do that.

Hello Chet, I double-checked that, and with the attached
quick hack I was able to do:
trap bg USR1
and move the job to the background with just that SIGUSR1.
Do you think such a feature is worth being implemented?
If yes, feel free to give me the suggestions and I'll try to
implement it properly. The attached patch is just a POC of
course, it is entirely incorrect.
--- jobs.c.old  2011-01-07 18:59:29.0 +0300
+++ jobs.c  2012-01-04 16:07:49.001668244 +0400
@@ -1391,6 +1391,26 @@
   return (NO_JOB);
 }
 
+static int
+find_foreground_job (procp)
+ PROCESS **procp;
+{
+  register int i;
+
+  /* XXX could use js.j_firstj here, and should check js.j_lastj */
+  for (i = 0; i  js.j_jobslots; i++)
+{
+  if (jobs[i]  IS_FOREGROUND (i))
+{
+  if (procp)
+*procp = jobs[i]-pipe;
+  return (i);
+}
+}
+
+  return (NO_JOB);
+}
+
 /* Find a job given a PID.  If BLOCK is non-zero, block SIGCHLD as
required by find_job. */
 int
@@ -3067,6 +3087,7 @@
   PROCESS *child;
   pid_t pid;
   int call_set_current, last_stopped_job, job, children_exited, waitpid_flags;
+  int wifcontinued;
   static int wcontinued = WCONTINUED;  /* run-time fix for glibc problem */
 
   call_set_current = children_exited = 0;
@@ -3117,12 +3138,24 @@
   /* If waitpid returns 0, there are running children.  If it returns -1,
 the only other error POSIX says it can return is EINTR. */
   CHECK_TERMSIG;
+  wifcontinued = WIFCONTINUED(status);
+  if (pid = 0  errno == EINTR)
+   {
+ PROCESS *p;
+ int i = find_foreground_job(p);
+ if (i != NO_JOB)
+   {
+ pid = p-pid;
+ wifcontinued = 0;
+ status = 0x7f;
+   }
+   }
   if (pid = 0)
continue;   /* jumps right to the test */
 
   /* children_exited is used to run traps on SIGCHLD.  We don't want to
  run the trap if a process is just being continued. */
-  if (WIFCONTINUED(status) == 0)
+  if (wifcontinued == 0)
{
  children_exited++;
  js.c_living--;
@@ -3148,7 +3181,7 @@
 
   /* Remember status, and whether or not the process is running. */
   child-status = status;
-  child-running = WIFCONTINUED(status) ? PS_RUNNING : PS_DONE;
+  child-running = wifcontinued ? PS_RUNNING : PS_DONE;
 
   if (PEXITED (child))
{


Re: bug in force_interactive handling

2012-01-04 Thread Chet Ramey
On 1/4/12 7:20 AM, Stas Sergeev wrote:

 Hello Chet, I double-checked that, and with the attached
 quick hack I was able to do:
 trap bg USR1
 and move the job to the background with just that SIGUSR1.
 Do you think such a feature is worth being implemented?

I don't think there's enough need to change bg from operating on stopped
jobs to operating on running jobs.  I would not add this to bash.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: bug in force_interactive handling

2012-01-04 Thread Stas Sergeev

04.01.2012 17:28, Chet Ramey wrote:

Hello Chet, I double-checked that, and with the attached
quick hack I was able to do:
trap bg USR1
and move the job to the background with just that SIGUSR1.
Do you think such a feature is worth being implemented?

I don't think there's enough need to change bg from operating on stopped
jobs to operating on running jobs.  I would not add this to bash.

I didn't mean that at all, and bg have almost
nothing to do with the idea.
I just meant for the way to make the trap handler
executed when the foreground job is running.
In my hack it temporary becames the background
job, then the trap is executed. Since the trap executes
bg, it stays in the background. The command (bg) is
not even needed, maybe it just should be the special
kind of a trap that moves the job to the background
without executing any command? There can be any
kind of an implementation if you think the feature
itself is useful (I think it is, I'll use it :))



Re: bug in force_interactive handling

2012-01-04 Thread Chet Ramey
On 1/4/12 8:42 AM, Stas Sergeev wrote:

 I just meant for the way to make the trap handler
 executed when the foreground job is running.

So you'd like the shell to act on a signal without `consulting' the
foreground job?  Take a look at http://www.cons.org/cracauer/sigint.html ,
keeping in mind that it applies to signals other than those generated
from the keyboard, and that it applies whether or not job control is
enabled, and see if you feel the same way.

I don't think it's a good idea.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: bug in force_interactive handling

2012-01-04 Thread Chet Ramey
On 1/4/12 9:50 PM, Chet Ramey wrote:
 On 1/4/12 8:42 AM, Stas Sergeev wrote:
 
 I just meant for the way to make the trap handler
 executed when the foreground job is running.
 
 So you'd like the shell to act on a signal without `consulting' the
 foreground job?  Take a look at http://www.cons.org/cracauer/sigint.html ,
 keeping in mind that it applies to signals other than those generated
 from the keyboard, and that it applies whether or not job control is
 enabled, and see if you feel the same way.
 
 I don't think it's a good idea.

The reference isn't really applicable -- though it's still a good read --
since it assumes the signal is sent to both the shell and the foreground
process.  I still don't think this is a good idea, though.

Chet


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: bug in force_interactive handling

2012-01-02 Thread Stas Sergeev

02.01.2012 07:15, Chet Ramey wrote:

On 12/30/11 5:36 AM, Stas Sergeev wrote:

Hello Chet, thanks for your patch file.
It is slightly broken, attached is the fixed version
of your patch.
BUT: it solves only half of the bug.

Thanks, I inadvertently left that part of the patch out of what I sent.

Will you apply this patch for the next bash release?


Do you know how to fix also this?

If you send the `cat' a SIGCONT it will end up running in the background:
its process group id will never be the same as the terminal's.  Sending
SIGCONT from another process will not set the terminal's process group to
cat's pgid.  That's why things like `fg' and `bg' are shell builtins --
so the shell can multiplex the terminal's process group among its children.

Thanks for the explanation.
In this case it would be nice for bash to have
a signal that will move the background process
to the foreground. Without this I still can't do
what I intended: I wanted the script to finish,
leaving the background process running. This
works only if my script sleeps till I send SIGCONT
to the process.
If it doesn't sleep, the SIGCONT may arrive later
than the script finishes, and the job gets killed.
I wonder if its possible in bash to implement the
signal handler to move the process to the background,
but that's probably about asking too much. :)
Thanks for your help!



Re: bug in force_interactive handling

2012-01-02 Thread Chet Ramey
On 1/2/12 4:27 AM, Stas Sergeev wrote:
 02.01.2012 07:15, Chet Ramey wrote:

 Thanks, I inadvertently left that part of the patch out of what I sent.
 Will you apply this patch for the next bash release?

Yes, it's already applied.

 In this case it would be nice for bash to have
 a signal that will move the background process
 to the foreground.

But there is already a command to do that: fg.  You can hook SIGCHLD
with a trap handler, process the `jobs' output, and fg the appropriate
process.  I still think that's way more work than you need to do.

 Without this I still can't do
 what I intended: I wanted the script to finish,
 leaving the background process running. This
 works only if my script sleeps till I send SIGCONT
 to the process.

Since you're not really using job control at all, but controlling the
process's status by sending it signals from another process, you
could add a process in between, making the job you're interested in
a grandchild of the shell.  That way it doesn't matter what the shell
does when it exits.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: bug in force_interactive handling

2012-01-02 Thread Stas Sergeev

02.01.2012 22:27, Chet Ramey wrote:

In this case it would be nice for bash to have
a signal that will move the background process
to the foreground.

But there is already a command to do that: fg.

Sorry, mistyped, I meant the other way around: move
the foreground process to the background, then finish
the script, leaving the process alive.
Will your suggestion about the trap handler work
also for ^Z+bg rather than just fg?


 could add a process in between, making the job you're interested in


The extra process in-between is a good workaround,
yes, but I wonder if this can be avoided.



Re: bug in force_interactive handling

2012-01-02 Thread Chet Ramey
On 1/2/12 1:38 PM, Stas Sergeev wrote:
 02.01.2012 22:27, Chet Ramey wrote:
 In this case it would be nice for bash to have
 a signal that will move the background process
 to the foreground.
 But there is already a command to do that: fg.
 Sorry, mistyped, I meant the other way around: move
 the foreground process to the background, then finish
 the script, leaving the process alive.

The SIGSTOP/SIGCONT works to put the process into the background: the
jobs pgrp is not the same as the terminal's pgrp.  If you don't want
the shell to terminate the job at exit because it's stopped, use
`disown' after the job stops to have the shell forget it while you
continue it from another process.

 Will your suggestion about the trap handler work
 also for ^Z+bg rather than just fg?

It should.

I know that `cat' was just an example, but you have to make sure the
job you want to stop/continue is not attempting to read from the terminal.
If it is, the kernel will SIGTSTP it every time.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: bug in force_interactive handling

2012-01-02 Thread Stas Sergeev

02.01.2012 22:53, Chet Ramey wrote:

the script, leaving the process alive.

The SIGSTOP/SIGCONT works to put the process into the background: the
jobs pgrp is not the same as the terminal's pgrp.  If you don't want
the shell to terminate the job at exit because it's stopped, use
`disown' after the job stops to have the shell forget it while you
continue it from another process.

Thanks! The disown might do the trick.


Will your suggestion about the trap handler work
also for ^Z+bg rather than just fg?

It should.

I tried:
---
trap bg USR1
---
Now if I first send SIGSTOP to the job and then SIGUSR1 to
bash, that works.
Is it possible to avoid sending SIGSTOP to the job, and make
the trap handler to do both things at once? Not that it is strictly
required since you already described a few other ways, but I wonder. :)



Re: bug in force_interactive handling

2012-01-02 Thread Chet Ramey
On 1/2/12 2:10 PM, Stas Sergeev wrote:

 Will your suggestion about the trap handler work
 also for ^Z+bg rather than just fg?
 It should.
 I tried:
 ---
 trap bg USR1
 ---
 Now if I first send SIGSTOP to the job and then SIGUSR1 to
 bash, that works.
 Is it possible to avoid sending SIGSTOP to the job, and make
 the trap handler to do both things at once? Not that it is strictly
 required since you already described a few other ways, but I wonder. :)

Well, this is getting pretty esoteric.  On one hand, you can avoid the
entire SIGSTOP/SIGCONT issue by initially starting the job in the
background with `'.  On the other, if you want to move a foreground
job to the background, you have to get it to give up control somehow, and
sending it a signal is the way to do that.

You can install a trap handler for another signal, say SIGALRM, and have
some process send SIGALRM to the shell after some period (e.g.,
`( sleep 20 ; kill -ALRM $$)' ), but you'll have to get the shell to react
to the signal once it's received rather than waiting for the foreground
process to change state.  Once you get the shell running, it can issue
the SIGSTOP/bg.

Chet


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: bug in force_interactive handling

2012-01-02 Thread Stas Sergeev

03.01.2012 00:07, Chet Ramey wrote:

background with `'.  On the other, if you want to move a foreground
job to the background, you have to get it to give up control somehow, and
sending it a signal is the way to do that.

Unless I am mistaken, nothing special is required
for that, and SIGSTOP only makes waitpid() to return,
but any other signal can be used to interrupt waitpid()
with EINTR. But, in case of EINTR, bash simply restarts
waitpid() it seems.
So my wild guess is that the functionality of moving
the process to the background can be implemented
with some special type of trap that will not restart
waitpid() after that signal is received.
But anyway, I already have the workable solutions to
this. :)



Re: bug in force_interactive handling

2012-01-01 Thread Chet Ramey
On 12/30/11 5:36 AM, Stas Sergeev wrote:
 Hello Chet, thanks for your patch file.
 It is slightly broken, attached is the fixed version
 of your patch.
 BUT: it solves only half of the bug.

Thanks, I inadvertently left that part of the patch out of what I sent.

 Please check it yourself, here's the script:
 ---
 #!./bash -i
 set -m; cat
 echo Finished!
 while :; do jobs; sleep 2; done
 ---
 
 Run this script, then do
 killall -STOP cat
 You'll start seeing the output of jobs every 2 seconds,
 and the cat is marked Stopped.
 Then do
 killall -CONT cat
 Nothing changes, the cat is still listed as stopped.
 Then bash will run terminate_stopped_jobs() on it. :(
 Do you know how to fix also this?

I don't get this behavior; after the patch I get the `cat' listed as
running until it gets rescheduled, which depends on the kernel and
the scheduler.  (I have to wait much longer for it to be rescheduled
and run on Mac OS X than Linux, for instance.)  Let's talk through the
behavior you'd like to see happen.

If you send the `cat' a SIGCONT it will end up running in the background:
its process group id will never be the same as the terminal's.  Sending
SIGCONT from another process will not set the terminal's process group to
cat's pgid.  That's why things like `fg' and `bg' are shell builtins --
so the shell can multiplex the terminal's process group among its children.

Because cat is running as a background job, it will get SIGTTIN from the
kernel as soon as it runs and attempts to read from the terminal (and, in
fact, when you look at it with `ps', the status is `T').

Since the cat is stopped, and will be sent SIGTSTP every time it reads
from the terminal no matter how many times it gets SIGCONT, chances are
pretty good that bash will find it stopped, report it as such, and
terminate it before exiting.

What about this would you like to change?

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: bug in force_interactive handling

2011-12-30 Thread Stas Sergeev
Hello Chet, thanks for your patch file.
It is slightly broken, attached is the fixed version
of your patch.
BUT: it solves only half of the bug.
Please check it yourself, here's the script:
---
#!./bash -i
set -m; cat
echo Finished!
while :; do jobs; sleep 2; done
---

Run this script, then do
killall -STOP cat
You'll start seeing the output of jobs every 2 seconds,
and the cat is marked Stopped.
Then do
killall -CONT cat
Nothing changes, the cat is still listed as stopped.
Then bash will run terminate_stopped_jobs() on it. :(
Do you know how to fix also this?

29.12.2011 20:54, Chet Ramey wrote:
 When you run bash with -i, interactive and interactive_shell are set
 when initialize_job_control is called, so the correct initialization
 happens.  It's only later that job control gets turned off inappropriately.
As a side note it would be nice to not flip the interactive
value back and forth to make the code understanding
easier.
--- shell.c.old 2009-11-19 18:05:54.0 +0300
+++ shell.c 2011-12-29 21:07:24.960908301 +0400
@@ -1618,7 +1618,7 @@
   expand_aliases = posixly_correct;/* XXX - was 0 not posixly_correct */
   no_line_editing = 1;
 #if defined (JOB_CONTROL)
-  set_job_control (0);
+  set_job_control (forced_interactive||jobs_m_flag);
 #endif /* JOB_CONTROL */
 }
 
--- flags.h.old 2009-01-04 22:32:29.0 +0300
+++ flags.h 2011-12-30 14:18:28.171298742 +0400
@@ -47,7 +47,7 @@
   echo_command_at_execute, no_invisible_vars, noclobber,
   hashing_enabled, forced_interactive, privileged_mode,
   asynchronous_notification, interactive_comments, no_symbolic_links,
-  function_trace_mode, error_trace_mode, pipefail_opt;
+  function_trace_mode, error_trace_mode, pipefail_opt, jobs_m_flag;
 
 #if 0
 extern int lexical_scoping;


Re: bug in force_interactive handling

2011-12-29 Thread Chet Ramey
On 12/28/11 4:42 AM, Stas Sergeev wrote:

 But, -i sets interactive_shell variable, not interactive, so the
 aforementioned comment and code makes no sense, though it
 might have been working in the past.
 `-i' sets the `forced_interactive' variable; look at flags.c.  The shell
 sets interactive and interactive_shell internally. (And -i does end up
 setting `interactive'; look at shell.c:init_interactive() ).
 -i does not end up setting `interactive' when used from the
 script, see shell.c:init_interactive_script(). Sorry for not mentioning
 initially that I am talking about the script, but I thought -i is
 mainly useful for scripts.

You're on the right track.  The fix is to pay attention to the values
of forced_interactive and jobs_m_flag (the variables set by -i and -m,
respectively) when setting job control in init_noninterative().  I've
attached a patch that does the right thing.

When you run bash with -i, interactive and interactive_shell are set
when initialize_job_control is called, so the correct initialization
happens.  It's only later that job control gets turned off inappropriately.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.2-patched/shell.c	2011-01-02 16:04:51.0 -0500
--- shell.c	2011-12-29 09:18:52.0 -0500
***
*** 1620,1624 
no_line_editing = 1;
  #if defined (JOB_CONTROL)
!   set_job_control (0);
  #endif /* JOB_CONTROL */
  }
--- 1620,1626 
no_line_editing = 1;
  #if defined (JOB_CONTROL)
!   /* Even if the shell is not interactive, enable job control if the -i or
!  -m option is supplied at startup. */
!   set_job_control (forced_interactive||jobs_m_flag);
  #endif /* JOB_CONTROL */
  }


Re: bug in force_interactive handling

2011-12-28 Thread Stas Sergeev
Hi Chet, thanks for taking a look.

28.12.2011 01:16, Chet Ramey wrote:
 On 12/26/11 10:12 AM, Stas Sergeev wrote:
 Hi.

 It seems the -i switch of the bash doesn't work as expected
 these days (I tried with bash-4.1).
 I'm not sure what `expected' means here; both code fragments are
 correct.
Lets get this double-checked.

 I've found 2 places of the breakage.

 1. initialize_job_control () has the following code:
 ---
   if (interactive == 0)
 {
   job_control = 0;
   original_pgrp = NO_PID;
   shell_tty = fileno (stderr);
 }
   else
 {
   shell_tty = -1;

   /* If forced_interactive is set, we skip the normal check that stderr
  is attached to a tty, so we need to check here.  If it's not, we
  need to see whether we have a controlling tty by opening /dev/tty,
  since trying to use job control tty pgrp manipulations on a non-tty
  is going to fail. */
   if (forced_interactive  isatty (fileno (stderr)) == 0)
 ---

 But, -i sets interactive_shell variable, not interactive, so the
 aforementioned comment and code makes no sense, though it
 might have been working in the past.
 `-i' sets the `forced_interactive' variable; look at flags.c.  The shell
 sets interactive and interactive_shell internally. (And -i does end up
 setting `interactive'; look at shell.c:init_interactive() ).
-i does not end up setting `interactive' when used from the
script, see shell.c:init_interactive_script(). Sorry for not mentioning
initially that I am talking about the script, but I thought -i is
mainly useful for scripts.
So, after init_interactive_script() and -i we have
interactive==0, forced_interactive==1, interactive_shell==1.
With the code above, forced_interactive gets ignored.
Is this still not a bug?

 Job control isn't controlled by the `-i' option; it's the `-m' option.
 Interactive shells and shells with job control are not the same thing;
 you can have one without the other.  A shell that would ordinarily
 be non-interactive (e.g., started to run a script, or as part of a
 pipeline) but is forced interactive using `-i' need not have job control
 enabled, though it usually will.
Why this usually will does not apply to the scripts?
The comments in the code clearly suggests this was the
case. Namely, they used to check interactive_shell
in waitchld() in the past, but now they check job_control.
Have the bash changed its behaveor recently?

 The result of this all is that if some script is being run with
 bash -i and that script starts some binary, bash wouldn't honour
 the SIGSTOP sent to that binary.
 What does `honour the SIGSTOP' mean here?  If you want job control,
 try putting `set -m' into the script if $- doesn't include `m'.
Thanks: set -m together with -i kind of works...
The problem now is that bash thinks this job is stopped
forever, even after I send SIGCONT. Then it calls
terminate_stopped_jobs() to the running process... :(
Do you know how to solve this?

The test is simple:
---
#!/bin/bash -i
set -m; cat
echo Finished!
while :; do sleep 2; jobs; done
---
Send SIGSTOP to cat, then SIGCONT.
It is still displayed as Stopped.



Re: bug in force_interactive handling

2011-12-27 Thread Chet Ramey
On 12/26/11 10:12 AM, Stas Sergeev wrote:
 Hi.
 
 It seems the -i switch of the bash doesn't work as expected
 these days (I tried with bash-4.1).

I'm not sure what `expected' means here; both code fragments are
correct.

 I've found 2 places of the breakage.
 
 1. initialize_job_control () has the following code:
 ---
   if (interactive == 0)
 {
   job_control = 0;
   original_pgrp = NO_PID;
   shell_tty = fileno (stderr);
 }
   else
 {
   shell_tty = -1;

   /* If forced_interactive is set, we skip the normal check that stderr
  is attached to a tty, so we need to check here.  If it's not, we
  need to see whether we have a controlling tty by opening /dev/tty,
  since trying to use job control tty pgrp manipulations on a non-tty
  is going to fail. */
   if (forced_interactive  isatty (fileno (stderr)) == 0)
 ---
 
 But, -i sets interactive_shell variable, not interactive, so the
 aforementioned comment and code makes no sense, though it
 might have been working in the past.

`-i' sets the `forced_interactive' variable; look at flags.c.  The shell
sets interactive and interactive_shell internally. (And -i does end up
setting `interactive'; look at shell.c:init_interactive() ).

 2. waitchld() has the code like this:
 ---
   /* We don't want to be notified about jobs stopping if job control
  is not active.  XXX - was interactive_shell instead of
 job_control */
   waitpid_flags = (job_control  subshell_environment == 0)
 ? (WUNTRACED|wcontinued)
 : 0;
 ---
 
 In particular, the XXX part makes sense: it used to work when it
 was checking interactive_shell (for the reason mentioned above),
 but now it doesn't because job_control gets reset together with
 interactive.

Job control isn't controlled by the `-i' option; it's the `-m' option.
Interactive shells and shells with job control are not the same thing;
you can have one without the other.  A shell that would ordinarily
be non-interactive (e.g., started to run a script, or as part of a
pipeline) but is forced interactive using `-i' need not have job control
enabled, though it usually will.

 
 The result of this all is that if some script is being run with
 bash -i and that script starts some binary, bash wouldn't honour
 the SIGSTOP sent to that binary.

What does `honour the SIGSTOP' mean here?  If you want job control,
try putting `set -m' into the script if $- doesn't include `m'.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



bug in force_interactive handling

2011-12-26 Thread Stas Sergeev
Hi.

It seems the -i switch of the bash doesn't work as expected
these days (I tried with bash-4.1).
I've found 2 places of the breakage.

1. initialize_job_control () has the following code:
---
  if (interactive == 0)
{
  job_control = 0;
  original_pgrp = NO_PID;
  shell_tty = fileno (stderr);
}
  else
{
  shell_tty = -1;
   
  /* If forced_interactive is set, we skip the normal check that stderr
 is attached to a tty, so we need to check here.  If it's not, we
 need to see whether we have a controlling tty by opening /dev/tty,
 since trying to use job control tty pgrp manipulations on a non-tty
 is going to fail. */
  if (forced_interactive  isatty (fileno (stderr)) == 0)
---

But, -i sets interactive_shell variable, not interactive, so the
aforementioned comment and code makes no sense, though it
might have been working in the past.

2. waitchld() has the code like this:
---
  /* We don't want to be notified about jobs stopping if job control
 is not active.  XXX - was interactive_shell instead of
job_control */
  waitpid_flags = (job_control  subshell_environment == 0)
? (WUNTRACED|wcontinued)
: 0;
---

In particular, the XXX part makes sense: it used to work when it
was checking interactive_shell (for the reason mentioned above),
but now it doesn't because job_control gets reset together with
interactive.

The result of this all is that if some script is being run with
bash -i and that script starts some binary, bash wouldn't honour
the SIGSTOP sent to that binary.

I made a quick patch to fix the problem, it is attached.
Can someone please take a look into that?

(please CC me the replies)
--- shell.c.old 2009-11-19 18:05:54.0 +0300
+++ shell.c 2011-12-26 16:55:08.452997751 +0400
@@ -1625,8 +1625,13 @@
 static void
 init_interactive_script ()
 {
-  init_noninteractive ();
-  expand_aliases = interactive_shell = startup_state = 1;
+  init_interactive ();
+#if defined (HISTORY)
+  bash_history_reinit (0);
+#endif /* HISTORY */
+  expand_aliases = posixly_correct;/* XXX - was 0 not posixly_correct */
+  no_line_editing = 1;
+  interactive = 0;
 }
 
 void
--- jobs.c.old  2009-11-30 01:12:05.0 +0300
+++ jobs.c  2011-12-26 16:56:13.716721461 +0400
@@ -3581,7 +3581,7 @@
 }
 
   /* We can only have job control if we are interactive. */
-  if (interactive == 0)
+  if (interactive_shell == 0)
 {
   job_control = 0;
   original_pgrp = NO_PID;