Re: Can someone explain this?

2011-02-11 Thread Jon Seymour
On Sat, Feb 12, 2011 at 4:54 PM, Bob Proulx  wrote:
> I am a big fan of piping the script to the remote shell.
>
>  $ echo "cd /tmp && pwd" | ssh example.com bash
>  /tmp
>
> This has two advantages.  One is that you can pick your shell on the
> remote host.  Otherwise it runs as whatever is configured for that
> user in the password file.  If the remote host has csh configured then
> this overrides it and provides a known shell on the remote end.  Two
> is that since this is stdin it avoids having two different shells
> parse the command line.  Quoting is then much simplified.
>

Makes sense...thanks.

jon.



Re: Can someone explain this?

2011-02-11 Thread Bob Proulx
Dennis Williamson wrote:
> Yes, do your quoting like this:
> ssh localhost 'bash -c "cd /tmp; pwd"'

I am a big fan of piping the script to the remote shell.

  $ echo "cd /tmp && pwd" | ssh example.com bash
  /tmp

This has two advantages.  One is that you can pick your shell on the
remote host.  Otherwise it runs as whatever is configured for that
user in the password file.  If the remote host has csh configured then
this overrides it and provides a known shell on the remote end.  Two
is that since this is stdin it avoids having two different shells
parse the command line.  Quoting is then much simplified.

Bob



Re: Can someone explain this?

2011-02-11 Thread Dennis Williamson
On Fri, Feb 11, 2011 at 10:28 PM, Jon Seymour  wrote:
> Ok, so it relates to how ssh interprets its command argument:
>
> So:
>
>    bash -c 'cd /tmp ; pwd'
>
> My expectation was that it would invoke bash with the arguments:
>
> '-c'
> 'cd /tmp; pwd'
>
> But bash is actually invoked with:
>
> '-c'
> 'cd'
> '/tmp'
>
> and then pwd is invoked, presumably in same shell that invoked bash.
>
> This can be seen with this:
>
> jseymour@ubuntu:~$ ssh localhost bash -c 'echo\ \$\$\ \$PPID' ';' echo '$$'
> 11553 11552
> 11552
>
> bash is invoked with:
> '-c'
> 'echo $$ $PPID'
>
> then:
>
> echo $$ runs in the parent shell
>
> jon.
>
>
> On Sat, Feb 12, 2011 at 2:44 PM, Dennis Williamson
>  wrote:
>> On Fri, Feb 11, 2011 at 9:21 PM, Jon Seymour  wrote:
>>> Correction - a _leading_ cd command and only a leading cd command,
>>> seems to be completely ignored in the case I described.
>>>
>>> Why is this?
>>>
>>> jon.
>>>
>>> -- Forwarded message --
>>> From: Jon Seymour 
>>> Date: Sat, Feb 12, 2011 at 2:18 PM
>>> Subject: Can someone explain this?
>>> To: bug-bash@gnu.org
>>>
>>>
>>> Can someone explain why this is happening?
>>>
>>> #expected
>>> $ bash -c 'cd /tmp; pwd'
>>> /tmp
>>>
>>> #expected
>>> $ bash -c 'pwd; cd /tmp; pwd'
>>> /home/jseymour
>>> /tmp
>>>
>>> #expected
>>> $ ssh localhost bash -c 'pwd; cd /tmp; pwd'
>>> /home/jseymour
>>> /tmp
>>>
>>> #unexpected
>>> $ ssh localhost bash -c 'cd /tmp; pwd'
>>> /home/jseymour
>>>
>>> My expectation is that the last command should print:
>>>
>>> /tmp
>>>
>>> But, instead, the cd command seems to be completely ignored when bash
>>> is run under ssh. I have reproduced this with bash 4.1.5 on Linux and
>>> bash 3.0.0 on AIX.
>>>
>>> jon.
>>>
>>>
>>
>> It's not particular to Bash. I can reproduce it in several other shells.
>>
>

Yes, do your quoting like this:

ssh localhost 'bash -c "cd /tmp; pwd"'

and your test would look like this:

$ ssh localhost 'bash -c "echo $$; echo \$\$; cd /tmp; pwd"'; echo $$
6324
6324
/tmp
6370

or this:

$ ssh localhost 'echo $$; bash -c "echo $$; echo \$\$; cd /tmp; pwd"'; echo $$
6523
6523
6524
/tmp
6370

Notice what happens with the PIDs when a shell has to be started
before Bash is explicitly started.



Re: Can someone explain this?

2011-02-11 Thread Jon Seymour
Ok, so it relates to how ssh interprets its command argument:

So:

bash -c 'cd /tmp ; pwd'

My expectation was that it would invoke bash with the arguments:

'-c'
'cd /tmp; pwd'

But bash is actually invoked with:

'-c'
'cd'
'/tmp'

and then pwd is invoked, presumably in same shell that invoked bash.

This can be seen with this:

jseymour@ubuntu:~$ ssh localhost bash -c 'echo\ \$\$\ \$PPID' ';' echo '$$'
11553 11552
11552

bash is invoked with:
'-c'
'echo $$ $PPID'

then:

echo $$ runs in the parent shell

jon.


On Sat, Feb 12, 2011 at 2:44 PM, Dennis Williamson
 wrote:
> On Fri, Feb 11, 2011 at 9:21 PM, Jon Seymour  wrote:
>> Correction - a _leading_ cd command and only a leading cd command,
>> seems to be completely ignored in the case I described.
>>
>> Why is this?
>>
>> jon.
>>
>> -- Forwarded message --
>> From: Jon Seymour 
>> Date: Sat, Feb 12, 2011 at 2:18 PM
>> Subject: Can someone explain this?
>> To: bug-bash@gnu.org
>>
>>
>> Can someone explain why this is happening?
>>
>> #expected
>> $ bash -c 'cd /tmp; pwd'
>> /tmp
>>
>> #expected
>> $ bash -c 'pwd; cd /tmp; pwd'
>> /home/jseymour
>> /tmp
>>
>> #expected
>> $ ssh localhost bash -c 'pwd; cd /tmp; pwd'
>> /home/jseymour
>> /tmp
>>
>> #unexpected
>> $ ssh localhost bash -c 'cd /tmp; pwd'
>> /home/jseymour
>>
>> My expectation is that the last command should print:
>>
>> /tmp
>>
>> But, instead, the cd command seems to be completely ignored when bash
>> is run under ssh. I have reproduced this with bash 4.1.5 on Linux and
>> bash 3.0.0 on AIX.
>>
>> jon.
>>
>>
>
> It's not particular to Bash. I can reproduce it in several other shells.
>



Re: Can someone explain this?

2011-02-11 Thread Dennis Williamson
On Fri, Feb 11, 2011 at 9:21 PM, Jon Seymour  wrote:
> Correction - a _leading_ cd command and only a leading cd command,
> seems to be completely ignored in the case I described.
>
> Why is this?
>
> jon.
>
> -- Forwarded message --
> From: Jon Seymour 
> Date: Sat, Feb 12, 2011 at 2:18 PM
> Subject: Can someone explain this?
> To: bug-bash@gnu.org
>
>
> Can someone explain why this is happening?
>
> #expected
> $ bash -c 'cd /tmp; pwd'
> /tmp
>
> #expected
> $ bash -c 'pwd; cd /tmp; pwd'
> /home/jseymour
> /tmp
>
> #expected
> $ ssh localhost bash -c 'pwd; cd /tmp; pwd'
> /home/jseymour
> /tmp
>
> #unexpected
> $ ssh localhost bash -c 'cd /tmp; pwd'
> /home/jseymour
>
> My expectation is that the last command should print:
>
> /tmp
>
> But, instead, the cd command seems to be completely ignored when bash
> is run under ssh. I have reproduced this with bash 4.1.5 on Linux and
> bash 3.0.0 on AIX.
>
> jon.
>
>

It's not particular to Bash. I can reproduce it in several other shells.



Re: Can someone explain this?

2011-02-11 Thread Jon Seymour
Correction - a _leading_ cd command and only a leading cd command,
seems to be completely ignored in the case I described.

Why is this?

jon.

-- Forwarded message --
From: Jon Seymour 
Date: Sat, Feb 12, 2011 at 2:18 PM
Subject: Can someone explain this?
To: bug-bash@gnu.org


Can someone explain why this is happening?

#expected
$ bash -c 'cd /tmp; pwd'
/tmp

#expected
$ bash -c 'pwd; cd /tmp; pwd'
/home/jseymour
/tmp

#expected
$ ssh localhost bash -c 'pwd; cd /tmp; pwd'
/home/jseymour
/tmp

#unexpected
$ ssh localhost bash -c 'cd /tmp; pwd'
/home/jseymour

My expectation is that the last command should print:

/tmp

But, instead, the cd command seems to be completely ignored when bash
is run under ssh. I have reproduced this with bash 4.1.5 on Linux and
bash 3.0.0 on AIX.

jon.



Can someone explain this?

2011-02-11 Thread Jon Seymour
Can someone explain why this is happening?

#expected
$ bash -c 'cd /tmp; pwd'
/tmp

#expected
$ bash -c 'pwd; cd /tmp; pwd'
/home/jseymour
/tmp

#expected
$ ssh localhost bash -c 'pwd; cd /tmp; pwd'
/home/jseymour
/tmp

#unexpected
$ ssh localhost bash -c 'cd /tmp; pwd'
/home/jseymour

My expectation is that the last command should print:

/tmp

But, instead, the cd command seems to be completely ignored when bash
is run under ssh. I have reproduced this with bash 4.1.5 on Linux and
bash 3.0.0 on AIX.

jon.



Re: Don't show help of `readonly' and `readarray' when I run `help read'

2011-02-11 Thread Clark J. Wang
I forgot to reply to all

On Fri, Feb 11, 2011 at 11:15 PM, Chet Ramey  wrote:

> On 2/11/11 3:53 AM, Clark J. Wang wrote:
> >
> >
> > On Thu, Feb 10, 2011 at 10:21 PM, Chet Ramey  > > wrote:
> >
> > On 2/10/11 4:03 AM, Clark J. Wang wrote:
> > > help: help [-dms] [pattern ...]
> > >
> > > From my understanding the *pattern* here must be a glob-style
> pattern
> > > (wildcard) so `readonly' does not match the pattern `read'.
> >
> > The pattern is composed of the same characters as a glob pattern, but
> > it's treated more like 'grep ^pattern topic' if it doesn't contain
> any
> > special pattern matching characters.
> >
> > Kind of like the following:
> >
> > $ printf "%s\n" read readonly readarray | grep ^read /dev/stdin
> > read
> > readonly
> > readarray
> >
> >
> >
> > But the command `help rea?' can only prints help for `read' so I don't
> > think it's treated more like 'grep ^pattern topic'.
>
> But that contains a pattern character.  I said above that it was treated
> like grep if it didn't contain any special pattern matching characters.
>
> Chet
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
> ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRUc...@case.edu
> http://cnswww.cns.cwru.edu/~chet/
>



-- 
Clark


Re: help's blank lines have four spaces appended

2011-02-11 Thread Clark J. Wang
On Fri, Feb 11, 2011 at 11:16 PM, Chet Ramey  wrote:

> On 2/11/11 4:02 AM, Clark J. Wang wrote:
> > On Mon, Feb 7, 2011 at 12:01 AM, Chet Ramey  > > wrote:
> >
> > On 2/6/11 2:01 AM, jida...@jidanni.org 
> wrote:
> > > Why add the four spaces?
> >
> > Because all lines are prefixed by four spaces to separate the text
> from the
> > usage synopsis.
> >
> > That makes sense but don't add the four spaces for blank lines.
>
> What does it matter?
>
> No matter. Just looks nicer. :)

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



-- 
Clark


Re: [BUG] Bash not reacting to Ctrl-C

2011-02-11 Thread Linus Torvalds
On Fri, Feb 11, 2011 at 1:30 PM, Linus Torvalds
 wrote:
>
> The other case is that the child process was quick and already exited.
> You get ^C, but the child never did. When you do the waitpid(), you'll
> never get the EINTR, because there was no actual wait.

Ok, so here's a suggested patch. It took much longer than expected,
because I found another independent race while trying to fix this:
bash did the "restore_sigint_handler()" _after_ having already tested
the "wait_sigint_received" value, so what could happen is that the
SIGINT would happen _after_ the test of that flag, but before the
signal handler was restored, so bash would (once more) drop the ^C on
the floor.

So there are two fixes here, and while I have by no means done
exhaustive testing, this patch seems to make the problem with dropped
^C really really hard for me to trigger.

I do believe it's still racy, it's just that I think it is much less
racy than it used to be.

And maybe I introduced some new bug. There may be a reason why the
sigint-handler was restored too late. But it not only passes my ^C
tests, it seems to pass "make test" too, so it can't be horribly
broken.

And bash _was_ horribly broken wrt ^C before.

I tried to make the "child_blocked_sigint" logic very trivial and
obvious, and I added comments for it. But if there are any questions
about the patch, feel free to holler.

The basic rule is:
 - we only think that a child blocked sigint if we actually get EINTR
from a system call (and the signal handler set wait_sigint_received)
 - if the child returns with WSIGNALLED and WTERMSIG()==SIGINT, then
we say "it clearly didn't block it after all, or it emulated dying
with SIGINT, so we clear that previous heuristic".
 - then, instead of checking how the child died, we just use the new
'child_blocked_sigint' flag instead.

So instead of testing

  wait_sigint_received && WIFSIGNALED (s) && WTERMSIG (s) == SIGINT

it now tests

  wait_sigint_received && !child_blocked_sigint

which seems to match the comments better anyway.

Long story short: maybe the patch is buggy. But the issue is real, and
the patch looks largely sensible to me.

  Linus
 jobs.c |   35 +++
 1 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/jobs.c b/jobs.c
index df13ad9..8b9320f 100644
--- a/jobs.c
+++ b/jobs.c
@@ -2193,7 +2193,7 @@ restore_sigint_handler ()
 }
 }
 
-static int wait_sigint_received;
+static int wait_sigint_received, child_blocked_sigint;
 
 /* Handle SIGINT while we are waiting for children in a script to exit.
The `wait' builtin should be interruptible, but all others should be
@@ -2365,6 +2365,7 @@ wait_for (pid)
 
   /* This is possibly a race condition -- should it go in stop_pipeline? */
   wait_sigint_received = 0;
+  child_blocked_sigint = 0;
   if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
 {
   old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
@@ -2424,6 +2425,18 @@ wait_for (pid)
 	  sigaction (SIGCHLD, &oact, (struct sigaction *)NULL);
 	  sigprocmask (SIG_SETMASK, &chldset, (sigset_t *)NULL);
 #  endif
+	  /* If the waitchld returned EINTR, and the shell got a SIGINT,
+	 then the child has not died yet, and we assume that the
+	 child has blocked SIGINT. In that case, we require that the
+	 child return with WSIGTERM() == SIGINT to actually consider
+	 the ^C relevant. This is racy (the child may be in the
+	 process of exiting and bash reacted to the EINTR first),
+	 but this makes the race window much much smaller */
+	  if (r == -1 && errno == EINTR && wait_sigint_received)
+	{
+	  child_blocked_sigint = 1;
+	}
+
 	  queue_sigchld = 0;
 	  if (r == -1 && errno == ECHILD && this_shell_builtin == wait_builtin)
 	{
@@ -2461,6 +2474,16 @@ wait_for (pid)
 }
   while (PRUNNING (child) || (job != NO_JOB && RUNNING (job)));
 
+  /* If the child explicitly exited with a SIGINT, we dismiss the
+ fact that we guessed it blocked sigint earlier */
+  if (WIFSIGNALED(child->status) && WTERMSIG(child->status) == SIGINT)
+{
+  child_blocked_sigint = 0;
+}
+
+  /* Restore the original SIGINT signal handler. */
+  restore_sigint_handler ();
+
   /* The exit state of the command is either the termination state of the
  child, or the termination state of the job.  If a job, the status
  of the last child in the pipeline is the significant one.  If the command
@@ -2556,10 +2579,9 @@ if (job == NO_JOB)
 	 pass the status back to our parent. */
 	  s = job_signal_status (job);
 	
-	  if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0)
+	  if (!child_blocked_sigint && signal_is_trapped (SIGINT) == 0)
 	{
 	  UNBLOCK_CHILD (oset);
-	  restore_sigint_handler ();
 	  old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL);
 	  if (old_sigint_handler == SIG_IGN)
 		restore_sigint_handler ();
@@ -2585,9 +26

Re: [BUG] Bash not reacting to Ctrl-C

2011-02-11 Thread Linus Torvalds
On Fri, Feb 11, 2011 at 1:16 PM, Chet Ramey  wrote:
>
> In the meantime, read Martin Cracauer's description of the issue.
> http://www.cons.org/cracauer/sigint.html.

This is now the second time in the thread that this has been quoted,
but bash doesn't even FOLLOW the recommendations in that web-page, so
I don't understand why you and Illia point to it. You violate the
thing egregiously.

Here, let me quote the relevant bit:

  Take no action when SIGINT is received while you wait for a child.
You make a note of the fact that you did receive it, though.

and note the "while you wait for a child" part.

And the fact is, that is not at all what bash does. What bash does is
"Take no action when SIGINT is received
_even_if_you_didn't_wait_for_the_child_".

Not "during the wait". That's the problem. There's a HUGE race
condition in there, and in particular, if the child was quick and
already exited, but bash just hadn't gotten around to noticing it it
yet, bash will still ignore the ^C that happened after the child had
already exited. See?

So let's imagine that you're waiting for GNU emacs, and GNU emacs uses
^C for its own handling. Yes, in that case you need to ignore it. But
in that case, when you get SIGINT, you'll actually get an EINTR from
the waitpid system call.

The other case is that the child process was quick and already exited.
You get ^C, but the child never did. When you do the waitpid(), you'll
never get the EINTR, because there was no actual wait.

See the difference? And see how bash doesn't actually do what that
"Proper handling of SIGINT" page says to do.

  Linus



Re: [BUG] Bash not reacting to Ctrl-C

2011-02-11 Thread Oleg Nesterov
On 02/11, Chet Ramey wrote:
>
> In the meantime, read Martin Cracauer's description of the issue.
> http://www.cons.org/cracauer/sigint.html.

I did.

OK, OK, I didn't ;) I stopped the reading immediately after I started
to think I understand why you sent me this link.

Oleg.




Re: [BUG] Bash not reacting to Ctrl-C

2011-02-11 Thread Linus Torvalds
On Fri, Feb 11, 2011 at 12:21 PM, Chet Ramey  wrote:
>
> You do realize that this case is indistinguishable from the original
> scenario in question: the child gets the SIGINT, handles it, and exits
> successfully (or not).  Have you actually not followed the discussion?

Umm. I'm the one who brought that ambiguity up in the first place. Go
back and read the end of the original analysis posting (not just the
part I had to quote AGAIN, just to get people to admit there is a
bug).

Illia is then the one who claimed it wasn't at all ambiguous, and
suggested the (totally wrong) patch.

So please, somebody from the bash camp finally just admit that I (and
Oleg) actually know what we are talking about, instead of trying to
derail the bug-report by "can't reproduce" or "I'm on OS X, so I don't
see it" or "haven't you followed the discussion" answers?

Will somebody _finally_ admit there is a race, and that bash has a
bug? Please? Instead of this continuing denial?

Here's a suggestion: only consider the child program to have "blocked"
SIGINT if you actually got an EINTR to the waitpid() system call.
Because if the child had exited _before_ you even did a waitpid(),
then the waitpid() will - even if bash gets a ^C - return the success
report rather than returning EINTR.

Now, there's still some room for a race and a bug (^C happens just as
the child is in the middle of exiting and the child exits with no
WIFSIGNALED but still isn't "ready" yet by the time the waitpid
happens), but at least the race condition should hopefully be much
much smaller.

   Linus



Re: [BUG] Bash not reacting to Ctrl-C

2011-02-11 Thread Chet Ramey
On 2/11/11 4:00 PM, Oleg Nesterov wrote:
> On 02/11, Chet Ramey wrote:
>>
>> You do realize that this case is indistinguishable from the original
>> scenario in question: the child gets the SIGINT, handles it, and exits
>> successfully (or not).
> 
> I already tried to discuss this, but you didn't reply ;) See
> http://www.mail-archive.com/bug-bash@gnu.org/msg08528.html

I know.  There are many messages that need a reply.  I'm working on
getting bash-4.2 released; once I finish that, I will go back and
respond to all the messages.

In the meantime, read Martin Cracauer's description of the issue.
http://www.cons.org/cracauer/sigint.html.

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] Bash not reacting to Ctrl-C

2011-02-11 Thread Oleg Nesterov
On 02/11, Chet Ramey wrote:
>
> You do realize that this case is indistinguishable from the original
> scenario in question: the child gets the SIGINT, handles it, and exits
> successfully (or not).

I already tried to discuss this, but you didn't reply ;) See
http://www.mail-archive.com/bug-bash@gnu.org/msg08528.html

So, if I understand correctly, you mean that

#!/bin/sh

interactive_application

echo DONE

shouldn't be interrupted by SIGINT after interactive_application exits.
For example, it can be a text-editor which treats SIGINT specially.

But, in this case, shouldn't we fix the script above? In this case
the shell and the application should not run in the same tty->pgrp
group, or we can add "trap SIGINT".

Oleg.




Re: [BUG] Bash not reacting to Ctrl-C

2011-02-11 Thread Chet Ramey
On 2/11/11 3:01 PM, Linus Torvalds wrote:
> On Fri, Feb 11, 2011 at 8:57 AM, Illia Bobyr
>  wrote:
>> On 2/9/2011 3:57 PM, Linus Torvalds wrote:
>>>
>>> Here's the scenario:
> 
> I'll quote the scenario again, because you clearly didn't bother to read it.
> 
> Please _READ_ it this time before you answer, ok?
> 
>>>   - wait_for() sets wait_sigint_received to zero (look for the comment
>>> here!), and installs the sigint handler
>>>   - it does other things too, but it does waitchld() that does the
>>> actual waitpid() system call
>>>   - now, imagine the following scenario: the ^C happens just as the
>>> child already exited successfully!
>>>   - so bash itself gets the sigint, and sets wait_sigint_received to 1
> 
> Let me repeat: THE CHILD ALREADY EXITED SUCCESSFULLY. IT NEVER SAW THE ^C.
> 
> So 'bash' saw the ^C that came from the keyboard. And the exit status
> from the child does NOT show SIGINT, because the child never saw it.

You do realize that this case is indistinguishable from the original
scenario in question: the child gets the SIGINT, handles it, and exits
successfully (or not).  Have you actually not followed the discussion?

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] Bash not reacting to Ctrl-C

2011-02-11 Thread Linus Torvalds
On Fri, Feb 11, 2011 at 8:57 AM, Illia Bobyr
 wrote:
> On 2/9/2011 3:57 PM, Linus Torvalds wrote:
>>
>> Here's the scenario:

I'll quote the scenario again, because you clearly didn't bother to read it.

Please _READ_ it this time before you answer, ok?

>>   - wait_for() sets wait_sigint_received to zero (look for the comment
>> here!), and installs the sigint handler
>>   - it does other things too, but it does waitchld() that does the
>> actual waitpid() system call
>>   - now, imagine the following scenario: the ^C happens just as the
>> child already exited successfully!
>>   - so bash itself gets the sigint, and sets wait_sigint_received to 1

Let me repeat: THE CHILD ALREADY EXITED SUCCESSFULLY. IT NEVER SAW THE ^C.

So 'bash' saw the ^C that came from the keyboard. And the exit status
from the child does NOT show SIGINT, because the child never saw it.

> Do we really need to check wait_sigint_received here?

Jesus wept. YES.

Because the ONLY thing that has seen the SIGINT is bash. If bash then
ignores "wait_sigint_received", then bash has lost the ^C.

> If the child exits because of SIGINT was indeed received [..]

The amount of pure denial in this thread is astounding.

The bug has been analyzed. I told you exactly what happened. Please
don't make up some unrelated and totally pointless scenarios.

The child exited BECAUSE THE CHILD EXITED. The example child is
"/bin/true", for chissake. It exits immediately. It never saw the ^C.
The "waitpid()" will return a successful exit, so WTERMSIG() will be
zero.

If bash ignores 'wait_sigint_received' in this case, then ^C has been
lost. Which is the bug.

> Maybe the patch should be

No.

> I'm not an expert on Unix signals, but it seems that it is possible to
> tell. Via WTERMSIG (child->status).

Christ, NO!

You didn't read the bug report. Go back and read it. It has a full analysis.

The point is, and let me repeat this for the FIFTH time, since
apparently it's not really being appreciated: the child exited before
the ^C happened. There is no WTERMSIG().

> Again according to the "Proper handling of SIGINT/SIGQUIT" (*)  the
> child is supposed to "rekill" itself if it wishes to do any cleanup

.. and this is just empty blathering, because you didn't read, and
didn't understand, the problem.

The child was never killed to begin with. t wasn't even RUNNING when
the ^C happened. The only thing running was 'bash'.

And bash ignores it, exactly because bash has the buggy

   if (wait_sigint_received&&  (WTERMSIG (child->status) == SIGINT) && ..

test. The WTERMSIG() part of the test is broken.

It's really simple: wait_sigint_received means that bash got a SIGINT.
And ff bash got a SIGINT, then the user pressed ^C. Any random value
of WTERMSIG() and the fact that the child didn't see it is TOTALLY AND
UTTERLY IMMATERIAL.

So ignoring ^C just because it didn't happen while the child was
running is wrong. And telling people that you should check the exit
status of the child is WRONG.

Can we please stop with the stupidity already? Can we please stop with
the "I can't reproduce this" excuses? Can we please stop this "I'm
running OS X and I don't see it" crap? Can we please stop with the "I
didn't even read the bug report, but I'm going to make excuses
anyway"? Can we please stop with the denial?

It's a bug in bash. It really is that simple. Stop making excuses.
Read the source code, and read the bug report.

Linus



Re: [BUG] Bash not reacting to Ctrl-C

2011-02-11 Thread Oleg Nesterov
On 02/11, Illia Bobyr wrote:
>
> Do we really need to check wait_sigint_received here?
> If the child exits because of SIGINT was indeed received all the
> processes on the same terminal will also receive it.

Only if SIGINT was sent to pgrp (like ^C sends SIGTERM to the
foreground process group).

> --- bash-4.1/jobs.c~ctrlc_exit_race   2011-02-07 13:52:48.0 +0100
> +++ bash-4.1/jobs.c   2011-02-07 13:55:30.0 +0100
> @@ -3299,7 +3299,7 @@ set_job_status_and_cleanup (job)
>signals are sent to process groups) or via kill(2) to the foreground
>process by another process (or itself).  If the shell did receive the
>SIGINT, it needs to perform normal SIGINT processing. */
> -  else if (wait_sigint_received&&  (WTERMSIG (child->status) == SIGINT)&&
> +  else if ((WTERMSIG (child->status) == SIGINT)&&

The problems is, if WTERMSIG() == SIGINT everything is fine. Quite
contrary, we need to handle the case when the last running command
was _not_ killed but exited on its own.

Oleg.




Re: Don't show help of `readonly' and `readarray' when I run `help read'

2011-02-11 Thread Chet Ramey
On 2/10/11 5:34 PM, Chris F.A. Johnson wrote:
> On Thu, 10 Feb 2011, Maarten Billemont wrote:
> 
>> On 10 Feb 2011, at 15:21, Chet Ramey wrote:
>>>
>>> On 2/10/11 4:03 AM, Clark J. Wang wrote:
 help: help [-dms] [pattern ...]

 From my understanding the *pattern* here must be a glob-style pattern
 (wildcard) so `readonly' does not match the pattern `read'.
>>>
>>> The pattern is composed of the same characters as a glob pattern, but
>>> it's treated more like 'grep ^pattern topic' if it doesn't contain any
>>> special pattern matching characters.
>>>
>>> Kind of like the following:
>>>
>>> $ printf "%s\n" read readonly readarray | grep ^read /dev/stdin
>>> read
>>> readonly
>>> readarray
>>
>> I must admit I personally dislike getting three pages of help output I
>> don't care about when doing `help read`.  If I wanted to learn about
>> `readonly`, I'd do `help readonly`.  I'm not sure the current behavior
>> has any real merits over treating the pattern like glob pattern matching
>> usually works (anchored to beginning and end).
> 
>   I totally agree.

This is certainly something I will consider changing for the next bash
release (after bash-4.2).

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: set -e, braces and compound commands

2011-02-11 Thread Chet Ramey
On 2/10/11 11:08 PM, Daniel Villeneuve wrote:
> I'm using GNU bash, version 4.1.2(1)-release (i386-redhat-linux-gnu).
> 
> Following the change of semantics of "set -e" in bash 4,"man bash" seems to
> imply that the following script should exit after the for command (from the
> text "or one of the commands executed as part of a command list enclosed
> by  braces" where "one of the commands" should match a "for" command) . 
> However it does not.
> 
> 
> set -e
> {
>   for i in a b c; do
> [ -z "$i" ] && echo "null"
>   done
>   echo "'for' return code = $?"
> }
> echo "brace return code = $?"
> 
> 
> For reference, I've consulted
> http://thread.gmane.org/gmane.comp.standards.posix.austin.general/282,
> http://thread.gmane.org/gmane.comp.shells.bash.bugs/13465 and
> the current public POSIX spec I have access to which still says:
> 
> *-e*
>When this option is on, if a simple command fails for any of the
>reasons listed in Consequences of Shell Errors
>
>or returns an exit status value >0, and is not part of the compound
>list following a *while*, *until*, or *if* keyword, and is not a
>part of an AND or OR list, and is not a pipeline preceded by the *!*
>reserved word, then the shell shall immediately exit.
> 
> 
> Question 1: Is it the case that the bash 4 behavior is as intended here and
> that it's the documention of "set -e" in bash 4 that is imprecise
> ("commands" being too broad)?

I think the key is that the (new and as yet unpublished) Posix description
includes this sentence:

 Additionally if the
 failed command is a compound command whose exit status was
 derived from a command that is one of the aforementioned
 exceptions, the shell shall not exit.

That appears to cover this case.

> 
> Also, note that the man page section on "trap ERR" says that the trap is
> triggered if a "simple command" returns >0 (sharing exceptions with "set
> -e").  It seems however that the trigger is the same as for "set -e", as in
> 
> trap 'echo "error caught ($?), exiting"; exit 1' ERR
> (exit 2)
> echo done
> 
> Question 2: Are "set -e" and "trap ... ERR" triggered by the same events?

Yes, that's the intent.

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] Bash not reacting to Ctrl-C

2011-02-11 Thread Illia Bobyr
On 2/9/2011 3:57 PM, Linus Torvalds wrote:
> [...]
> The problem is that
> 'set_job_status_and_cleanup()' does that
>
> if (wait_sigint_received&&  (WTERMSIG (child->status) == SIGINT)&&  ..
>
> which just looks totally buggy and racy. There's even a comment about
> it in the bash source code, for chrissake!
>
> Here's the scenario:
>
>   - wait_for() sets wait_sigint_received to zero (look for the comment
> here!), and installs the sigint handler
>   - it does other things too, but it does waitchld() that does the
> actual waitpid() system call
>   - now, imagine the following scenario: the ^C happens just as the
> child already exited successfully!
>   - so bash itself gets the sigint, and sets wait_sigint_received to 1
>
> So what happens? child->status will be successful (the child was not
> interrupted by the signal, it exited at just the right time), but bash
> saw the SIGINT. But because it thinks it needs to see *both* the
> sigint _and_ the WTERMSIG(child->status)==SIGINT, bash essentially
> ignores the ^C.

Do we really need to check wait_sigint_received here?
If the child exits because of SIGINT was indeed received all the 
processes on the same terminal will also receive it.  At least according 
to "Proper handling of SIGINT/SIGQUIT" (*).

Maybe the patch should be

--- bash-4.1/jobs.c~ctrlc_exit_race 2011-02-07 13:52:48.0 +0100
+++ bash-4.1/jobs.c 2011-02-07 13:55:30.0 +0100
@@ -3299,7 +3299,7 @@ set_job_status_and_cleanup (job)
 signals are sent to process groups) or via kill(2) to the foreground
 process by another process (or itself).  If the shell did receive the
 SIGINT, it needs to perform normal SIGINT processing. */
-  else if (wait_sigint_received&&  (WTERMSIG (child->status) == SIGINT)&&
+  else if ((WTERMSIG (child->status) == SIGINT)&&
IS_FOREGROUND (job)&&  IS_JOBCONTROL (job) == 0)
{
  int old_frozen;

And then wait_sigint_received may not be needed altogether.

> [...]
>
> Now, it does look like the problem is at least partly because bash has
> a horrible time trying to figure out a truly ambigious case: did the
> child process explicitly ignore the ^C or not? It looks like bash is
> trying to basically ignore the ^C in the case the child ignored it. I
> think that's misguided, but that does seem to be what bash is trying
> to do. It's misguided exactly because there is absolutely no way to
> know whether the child returned successfully because it just happened
> to exit just before the ^C came in, or whether it blocked ^C and
> ignored it. So even _trying_ to make that judgement call seems to be a
> bad idea.

I'm not an expert on Unix signals, but it seems that it is possible to 
tell. Via WTERMSIG (child->status).  Again according to the "Proper 
handling of SIGINT/SIGQUIT" (*) the child is supposed to "rekill" itself 
if it wishes to do any cleanup upon receiving SIGINT or SIGQUIT and this 
way the parent will know that the termination was initiated by a signal.

> And no, I don't know bash sources all that well. I played around with
> them a long time ago, and for this I only glanced at it quickly to get
> more of a view into what bash is trying to do (all thanks should go to
> Oleg who already pinpointed the line that breaks). Maybe there are
> subtle issues, maybe there are broken historical shell semantics here.

This "Proper handling of SIGINT/SIGQUIT" article (that Chet Ramey 
 noted in a reply to the very first mail in this 
thread) contains a very nice explanation of why the shell is supposed to 
do this guessing.  Article talks about 3 possible behaviors and bash 
goes the best called "wait and cooperative exit".  It should not exit if 
child ignored the signal as some programs use SIGINT for their own 
purposes, not for termination and in this case the parent shell should 
just go on.  Any way, the article explains it all really nice and with 
all the details :)

> [...]

(*) "Proper handling of SIGINT/SIGQUIT" 
http://www.cons.org/cracauer/sigint.html



Re: PS1 expansion of \W incorrect for short paths

2011-02-11 Thread oe6tkt
On 18 Jan., 04:41, Cameron Hutchison  wrote:
> Configuration Information [Automatically generated, do not change]:
> Machine: x86_64
> OS: linux-gnu
> Compiler: gcc
> Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
> -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' 
> -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
> -DHAVE_CONFIG_H   -I.  -I../bash -I../bash/include -I../bash/lib   -g -O2 
> -Wall
> uname output: Linux balrog 2.6.37-balrog-1-2-gaf41dc2 #2 SMP PREEMPT Tue 
> Jan 18 11:16:08 EST 2011 x86_64 GNU/Linux
> Machine Type: x86_64-pc-linux-gnu
>
> Bash Version: 4.1
> Patch Level: 5
> Release Status: release
>
> Description:
>         Prompt expansion of \W sometimes produces garbage prompts.
>
> Repeat-By:
>         $ PS1='\W$ '
>         ~$ cd /home
>         hmee$ cd /proc
>         pocc$ cd /lib32
>         li332$
>
> Fix:
>         In parse.y : decode_prompt_string() in the 'W' case, it uses strcpy
>         to copy the basename of the path to the beginning of the string.
>         For short strings, the src and dest args to strcpy may overlap
>         which is not supported by strcpy.
>
>         memmove should be used instead.
>
>         change
>                 strcpy (t_string, t + 1);
>         to
>                 memmove (t_string, t + 1, strlen(t + 1) + 1);
>
>         (untested)

Hello Cameron,

you are right, but you'd copy to many characters, here is my tested
version and patch:

To: bug-bash@gnu.org
Subject: Corrupt prompt string using '\W' within PS1

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -
DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -
DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/share/locale' -
DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./
lib   -g -O2
uname output: Linux gold 2.6.32-5-amd64 #1 SMP Fri Dec 10 15:35:08 UTC
2010 x86_64 GNU/Linux
Machine Type: x86_64-unknown-linux-gnu

Bash Version: 4.1
Patch Level: 9
Release Status: release

Description:
Corrupt prompt string using the backslash-escaped special character
'\W'

Repeat-By:
When executing interactively bash displays the following sequence:
  bash-4.1$ cd /
  bash-4.1$ PS1="\W \$ "
  / $ cd home
  hmee $ cd /media
  meiia $

Fix:
Inside 'y.tab.c' the use of strcpy is in undefined behavior.
The 't_string' and 't' objects overlaps. Using the memmove,
copying takes place as if an intermediate buffer was used,
allowing the destination and source to overlap.
Regards,
Thomas Kuschel, oe6tkt

--- old/y.tab.c 2009-12-30 18:52:02.0 +0100
+++ y.tab.c 2011-02-11 12:36:45.682266575 +0100
@@ -7481,7 +7481,10 @@ decode_prompt_string (string)
  {
t = strrchr (t_string, '/');
if (t)
- strcpy (t_string, t + 1);
+ /* strcpy: If copying takes place between objects 
that overlap,
+the behavior is undefined.
+   strcpy (t_string, t + 1); so changed to: */
+ memmove (t_string; t + 1, strlen (t));
  }
  }
 #undef ROOT_PATH


Re: set -e, braces and compound commands

2011-02-11 Thread Andreas Schwab
Daniel Villeneuve  writes:

> For reference, I've consulted
> http://thread.gmane.org/gmane.comp.standards.posix.austin.general/282,
> http://thread.gmane.org/gmane.comp.shells.bash.bugs/13465 and
> the current public POSIX spec I have access to which still says:
>
> *-e*
>When this option is on, if a simple command fails for any of the

A compound command is not a simple command.  Only failing simple
commands cause the shell to exit.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."