]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20071206 snapshot
authorChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:16:10 +0000 (09:16 -0500)
committerChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:16:10 +0000 (09:16 -0500)
21 files changed:
CWRU/CWRU.chlog
CWRU/CWRU.chlog~
config-top.h
config-top.h~
doc/bash.1
doc/bashref.texi
doc/version.texi
eval.c
execute_cmd.c
include/shtty.h
include/shtty.h~ [new file with mode: 0644]
jobs.c
jobs.c~
lib/readline/display.c
lib/sh/shtty.c
lib/sh/shtty.c~ [new file with mode: 0644]
sig.c
subst.c
subst.c~
support/shobj-conf
support/shobj-conf~

index 4e479eb3a53c8190b7e23dbf3a4bfb232b8f4d5a..53e640173e9fbba040f14a0d903d43a91ba4ec2d 100644 (file)
@@ -15049,3 +15049,55 @@ configure.in
 doc/{bash.1,bashref.texi}
        - slight change to the text describing the effect of set -e when
          in a || or && list
+
+                                  12/5
+                                  ----
+jobs.c
+       - fix raw_job_exit_status to correct mixing of int/WAIT values (need
+         to return a WAIT)
+       - arrange so that children run as part of command substitutions also
+         set the SIGINT handler to wait_sigint_handler, since they effectively
+         don't do job control
+       - in wait_for, if a child run as part of a command substitution exits
+         due to SIGINT, resend the SIGINT to the waiting shell with kill(2).
+         This makes sure the exit status propagates 
+
+doc/{bash.1,bashref.texi}
+       - tighten up the language describing when bash tries to see if its
+         stdin is a socket, so it can run the startup files.  Suggested by
+         Vincent Lefevre <vincent@vinc17.org>
+
+eval.c
+       - in the DISCARD case of a longjmp to top_level, make sure
+         last_command_exit_value is set to EXECUTION_FAILURE if it's 0,
+         but leave existing non-zero values alone
+
+subst.c
+       - in command_substitute, don't reset pipeline_pgrp in the child
+         process -- this means that second and subsequent children spawned by
+         this comsub shell get put into the wrong process group, not the
+         shell's.  Fix for bug reported by Ingo Molnar <mingo@elte.hu>
+
+                                  12/6
+                                  ----
+support/shobj-conf
+       - make sure the cases for darwin8.x (Mac OS X 10.4.x) are extended to
+         darwin9.x (Mac OS X 10.5.x).  Fixes problem originally reported
+         against readline-5.2 by schneecrash@gmail.com
+
+                                  12/8
+                                  ----
+subst.c
+       - make sure to add the results of (successful) tilde expansion as a
+         quoted string, to inhibit pathname expansion and word splitting.
+         From recent Austin Group interpretation.
+
+include/shtty.h, lib/sh/shtty.c
+       - add ttfd_onechar, ttfd_noecho, ttfd_eightbit, ttfd_nocanon, and
+         ttfd_cbreak to set tty attributes associated with a particular
+         file descriptor (which is presumed to point to a terminal)
+
+lib/readline/display.c
+       - make sure we only use rl_invis_chars_first_line when the number of
+         physical characters exceeds the screen width, since that's the
+         only time expand_prompt sets it to a valid value
index 79ae7d8d2ae356d3d21608624cfd55de88b6e72e..0dd356aea2d33f9d0c1d83f8d9dd4105ffcecab6 100644 (file)
@@ -14999,7 +14999,7 @@ execute_cmd.c
                                   ----
 builtins/read.def
        - make sure the return value from get_word_from_string is freed if
-         non-null.  Fixes bug reported by Lars Ellenberg
+         non-null.  Fixes memory leak bug reported by Lars Ellenberg
          <lars.ellenberg@linbit.com>
 
                                   11/10
@@ -15049,3 +15049,55 @@ configure.in
 doc/{bash.1,bashref.texi}
        - slight change to the text describing the effect of set -e when
          in a || or && list
+
+                                  12/5
+                                  ----
+jobs.c
+       - fix raw_job_exit_status to correct mixing of int/WAIT values (need
+         to return a WAIT)
+       - arrange so that children run as part of command substitutions also
+         set the SIGINT handler to wait_sigint_handler, since they effectively
+         don't do job control
+       - in wait_for, if a child run as part of a command substitution exits
+         due to SIGINT, resend the SIGINT to the waiting shell with kill(2).
+         This makes sure the exit status propagates 
+
+doc/{bash.1,bashref.texi}
+       - tighten up the language describing when bash tries to see if its
+         stdin is a socket, so it can run the startup files.  Suggested by
+         Vincent Lefevre <vincent@vinc17.org>
+
+eval.c
+       - in the DISCARD case of a longjmp to top_level, make sure
+         last_command_exit_value is set to EXECUTION_FAILURE if it's 0,
+         but leave existing non-zero values alone
+
+subst.c
+       - in command_substitute, don't reset pipeline_pgrp in the child
+         process -- this means that second and subsequent children spawned by
+         this comsub shell get put into the wrong process group, not the
+         shell's.  Fix for bug reported by Ingo Molnar <mingo@elte.hu>
+
+                                  12/6
+                                  ----
+support/shobj-conf
+       - make sure the cases for darwin8.x (Mac OS X 10.4.x) are extended to
+         darwin9.x (Mac OS X 10.5.x).  Fixes problem originally reported
+         against readline-5.2 by schneecrash@gmail.com
+
+                                  12/8
+                                  ----
+subst.c
+       - make sure to add the results of (successful) tilde expansion as a
+         quoted string, to inhibit pathname expansion and word splitting.
+         From recent Austin Group interpretation.
+
+include/shtty.h, lib/sh/shtty.c
+       - add ttfd_onechar, ttfd_noecho, ttfd_eightbit, ttfd_nocanon, and
+         ttfd_cbreak to set tty attributes associated with a particular
+         file descriptor (which is presumed to point to the terminal)
+
+lib/readline/display.c
+       - make sure we only use rl_invis_chars_first_line when the number of
+         physical characters exceeds the screen width, since that's the
+         only time expand_prompt sets it to a valid value
index 26ea040367f088f441084153c94e931fb30acf0c..fe7edde3e3a1b56ec7748ceff94d89ee6de3caef 100644 (file)
@@ -88,5 +88,7 @@
 /* #define NON_INTERACTIVE_LOGIN_SHELLS */
 
 /* Define this if you want bash to try to check whether it's being run by
-   sshd and source the .bashrc if so (like the rshd behavior). */
+   sshd and source the .bashrc if so (like the rshd behavior).  This checks
+   for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
+   which can be fooled under certain not-uncommon circumstances. */
 /* #define SSH_SOURCE_BASHRC */
index 524d4fb9cead20b451658b1162bbf6e7f85d721e..26ea040367f088f441084153c94e931fb30acf0c 100644 (file)
@@ -3,7 +3,7 @@
 /* This contains various user-settable options not under the control of
    autoconf. */
 
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
index 556c8c5fa63ac65dded7bca461af4bc06a89b7e4..c64d70f13ee2e13e4120f8c3456d2ef19f54ab21 100644 (file)
@@ -5,13 +5,12 @@
 .\"    Case Western Reserve University
 .\"    chet@po.cwru.edu
 .\"
-.\"    Last Change: Wed Nov 21 22:39:33 EST 2007
-
+.\"    Last Change: Wed Dec  5 22:08:48 EST 2007
 .\"
 .\" bash_builtins, strip all but Built-Ins section
 .if \n(zZ=1 .ig zZ
 .if \n(zY=1 .ig zY
-.TH BASH 1 "2007 November 21" "GNU Bash-3.2"
+.TH BASH 1 "2007 December 5" "GNU Bash-3.2"
 .\"
 .\" There's some problem with having a `@'
 .\" in a tagged paragraph with the BSD man macros.
@@ -410,11 +409,12 @@ whose name is the expanded value.
 No other startup files are read.
 .PP
 .B Bash
-attempts to determine when it is being run by the remote shell
-daemon, usually \fIrshd\fP.
+attempts to determine when it is being run with its standard input
+connected to a a network connection, as if by the remote shell
+daemon, usually \fIrshd\fP, or the secure shell daemon \fIsshd\fP.
 If
 .B bash
-determines it is being run by \fIrshd\fP, it reads and executes
+determines it is being run in this fashion, it reads and executes
 commands from \fI~/.bashrc\fP, if that file exists and is readable.
 It will not do this if invoked as \fBsh\fP.
 The
index fbf22a57bc613c6142b26304d97d0860a531237f..797740d9dfd4c752c8dc91368a2baf302842632c 100644 (file)
@@ -5158,9 +5158,11 @@ No other startup files are read.
 
 @subsubheading Invoked by remote shell daemon
 
-Bash attempts to determine when it is being run by the remote shell
-daemon, usually @code{rshd}.  If Bash determines it is being run by
-rshd, it reads and executes commands from @file{~/.bashrc}, if that
+Bash attempts to determine when it is being run with its standard input
+connected to a a network connection, as if by the remote shell
+daemon, usually @code{rshd}, or the secure shell daemon @code{sshd}.
+If Bash determines it is being run in
+this fashion, it reads and executes commands from @file{~/.bashrc}, if that
 file exists and is readable.
 It will not do this if invoked as @code{sh}.
 The @option{--norc} option may be used to inhibit this behavior, and the
index 6d23fe9564ffe8c1eac35a2e77d1bd3f81ea0c25..77b9671179d7a70ea6390f08110b9caeeed95e2f 100644 (file)
@@ -2,9 +2,9 @@
 Copyright (C) 1988-2007 Free Software Foundation, Inc.
 @end ignore
 
-@set LASTCHANGE Wed Nov 21 22:41:34 EST 2007
+@set LASTCHANGE Wed Dec  5 22:08:02 EST 2007
 
 @set EDITION 3.2
 @set VERSION 3.2
-@set UPDATED 21 November 2007
-@set UPDATED-MONTH November 2007
+@set UPDATED 5 December 2007
+@set UPDATED-MONTH December 2007
diff --git a/eval.c b/eval.c
index a1c80b24bd9445aaa768bd59a251212ef5bb60d0..f77b76c8728d0881820e23efb5f39f5fa56f4734 100644 (file)
--- a/eval.c
+++ b/eval.c
@@ -100,7 +100,11 @@ reader_loop ()
              goto exec_done;
 
            case DISCARD:
-             last_command_exit_value = 1;
+             /* Make sure the exit status is reset to a non-zero value, but
+                leave existing non-zero values (e.g., > 128 on signal)
+                alone. */
+             if (last_command_exit_value == 0)
+               last_command_exit_value = EXECUTION_FAILURE;
              if (subshell_environment)
                {
                  current_command = (COMMAND *)NULL;
index 4a04920c54d5795f9afd372493acf9caddc7b758..be51a3334225c4c4ced7cf584c2889d74840f41b 100644 (file)
@@ -714,7 +714,6 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
               subshells forked to execute builtin commands (e.g., in
               pipelines) to be waited for twice. */
              exec_result = wait_for (last_made_pid);
-itrace("execute_command_internal: wait_for (%d) = %d", last_made_pid, exec_result);
          }
       }
 
@@ -894,7 +893,6 @@ itrace("execute_command_internal: wait_for (%d) = %d", last_made_pid, exec_resul
 #endif
 
   last_command_exit_value = exec_result;
-itrace("execute_command_internal: last_command_exit_value -> %d last_command_exit_signal = %d", last_command_exit_value, last_command_exit_signal);
   run_pending_traps ();
 #if 0
   if (running_trap == 0)
index e3e52e3667de856f4ad01fb55ab528063ae20649..9d755ec43b227a859a159d5d292796815440628e 100644 (file)
@@ -91,6 +91,17 @@ extern int tt_setcbreak __P((TTYSTRUCT *));
    course), the right thing will happen, but more system calls will be
    executed than absolutely necessary.  You can do all of this yourself
    with the other functions; these are only conveniences. */
+
+/* These functions work with a given file descriptor and set terminal
+   attributes */
+extern int ttfd_onechar __P((int, TTYSTRUCT *));
+extern int ttfd_noecho __P((int, TTYSTRUCT *));
+extern int ttfd_eightbit __P((int, TTYSTRUCT *));
+extern int ttfd_nocanon __P((int, TTYSTRUCT *));
+
+extern int ttfd_cbreak __P((int, TTYSTRUCT *));
+
+/* These functions work with fd 0 and the TTYSTRUCT saved with ttsave () */
 extern int ttonechar __P((void));
 extern int ttnoecho __P((void));
 extern int tteightbit __P((void));
diff --git a/include/shtty.h~ b/include/shtty.h~
new file mode 100644 (file)
index 0000000..d3a0b0c
--- /dev/null
@@ -0,0 +1,112 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc. */
+
+/* This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Bash; see the file COPYING.  If not, write to the Free Software
+   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+/*
+ * shtty.h -- include the correct system-dependent files to manipulate the
+ *           tty
+ */
+
+#ifndef __SH_TTY_H_
+#define __SH_TTY_H_
+
+#include "stdc.h"
+
+#if defined (_POSIX_VERSION) && defined (HAVE_TERMIOS_H) && defined (HAVE_TCGETATTR) && !defined (TERMIOS_MISSING)
+#  define TERMIOS_TTY_DRIVER
+#else
+#  if defined (HAVE_TERMIO_H)
+#    define TERMIO_TTY_DRIVER
+#  else
+#    define NEW_TTY_DRIVER
+#  endif
+#endif
+
+/*
+ * The _POSIX_SOURCE define is to avoid multiple symbol definitions
+ * between sys/ioctl.h and termios.h.  Ditto for the test against SunOS4
+ * and the undefining of several symbols.
+ */
+      
+#ifdef TERMIOS_TTY_DRIVER
+#  if (defined (SunOS4) || defined (SunOS5)) && !defined (_POSIX_SOURCE)
+#    define _POSIX_SOURCE
+#  endif
+#  if defined (SunOS4)
+#    undef ECHO
+#    undef NOFLSH
+#    undef TOSTOP
+#  endif /* SunOS4 */
+#  include <termios.h>
+#  define TTYSTRUCT struct termios
+#else
+#  ifdef TERMIO_TTY_DRIVER
+#    include <termio.h>
+#    define TTYSTRUCT struct termio
+#  else        /* NEW_TTY_DRIVER */
+#    include <sgtty.h>
+#    define TTYSTRUCT struct sgttyb
+#  endif
+#endif
+
+/* Functions imported from lib/sh/shtty.c */
+
+/* Get and set terminal attributes for the file descriptor passed as
+   an argument. */
+extern int ttgetattr __P((int, TTYSTRUCT *));
+extern int ttsetattr __P((int, TTYSTRUCT *));
+
+/* Save and restore the terminal's attributes from static storage. */
+extern void ttsave __P((void));
+extern void ttrestore __P((void));
+
+/* Return the attributes corresponding to the file descriptor (0 or 1)
+   passed as an argument. */
+extern TTYSTRUCT *ttattr __P((int));
+
+/* These functions only operate on the passed TTYSTRUCT; they don't
+   actually change anything with the kernel's current tty settings. */
+extern int tt_setonechar __P((TTYSTRUCT *));
+extern int tt_setnoecho __P((TTYSTRUCT *));
+extern int tt_seteightbit __P((TTYSTRUCT *));
+extern int tt_setnocanon __P((TTYSTRUCT *));
+extern int tt_setcbreak __P((TTYSTRUCT *));
+
+/* These functions are all generally mutually exclusive.  If you call
+   more than one (bracketed with calls to ttsave and ttrestore, of
+   course), the right thing will happen, but more system calls will be
+   executed than absolutely necessary.  You can do all of this yourself
+   with the other functions; these are only conveniences. */
+
+/* These functions work with a given file descriptor and set terminal
+   attributes */
+extern int ttfd_onechar __P((int, TTYSTRUCT *));
+extern int ttfd_noecho __P((int, TTYSTRUCT *));
+extern int ttfd_eightbit __P((int, TTYSTRUCT *));
+extern int ttfd_nocanon __P((int, TTYSTRUCT *));
+
+extern int ttcbreak __P((int, TTYSTRUCT *));
+
+/* These functions work with fd 0 and the TTYSTRUCT saved with ttsave () */
+extern int ttonechar __P((void));
+extern int ttnoecho __P((void));
+extern int tteightbit __P((void));
+extern int ttnocanon __P((void));
+
+extern int ttcbreak __P((void));
+
+#endif
diff --git a/jobs.c b/jobs.c
index 6c0dff1a64ebaadc0f6cf1250ac0290b390eefc2..df2ef7595f39f538f4bce86258ee394822b0960a 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -250,6 +250,7 @@ static int job_exit_status __P((int));
 static int job_exit_signal __P((int));
 static int set_job_status_and_cleanup __P((int));
 
+static WAIT job_signal_status __P((int));
 static WAIT raw_job_exit_status __P((int));
 
 static void notify_of_job_status __P((void));
@@ -453,7 +454,6 @@ start_pipeline ()
     {
       cleanup_the_pipeline ();
       pipeline_pgrp = 0;
-itrace("start_pipeline: set pipeline_pgrp = 0");
 #if defined (PGRP_PIPE)
       pipe_close (pgrp_pipe);
 #endif
@@ -567,7 +567,6 @@ stop_pipeline (async, deferred)
       the_pipeline = (PROCESS *)NULL;
       newjob->pgrp = pipeline_pgrp;
       pipeline_pgrp = 0;
-itrace("stop_pipeline: set pipeline_pgrp = 0");
 
       newjob->flags = 0;
 
@@ -1686,8 +1685,6 @@ make_child (command, async_p)
   sigemptyset (&oset);
   sigprocmask (SIG_BLOCK, &set, &oset);
 
-itrace("make_child start: pipeline_pgrp = %d", pipeline_pgrp);
-
   making_children ();
 
 #if defined (BUFFERED_INPUT)
@@ -1746,10 +1743,7 @@ itrace("make_child start: pipeline_pgrp = %d", pipeline_pgrp);
             process group. */
 
          if (pipeline_pgrp == 0)       /* This is the first child. */
-{
            pipeline_pgrp = mypid;
-itrace("make_child: child proc: set pipeline_pgrp = %d (mypid)", pipeline_pgrp);
-}
 
          /* Check for running command in backquotes. */
          if (pipeline_pgrp == shell_pgrp)
@@ -1775,10 +1769,7 @@ itrace("make_child: child proc: set pipeline_pgrp = %d (mypid)", pipeline_pgrp);
             shell's process group (we could be in the middle of a
             pipeline, for example). */
          if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&SUBSHELL_ASYNC) == 0))
-{
-itrace("make_child: give terminal to %d shell_pgrp = %d subshell_environment = %d", pipeline_pgrp, shell_pgrp, subshell_environment);
            give_terminal_to (pipeline_pgrp, 0);
-}
 
 #if defined (PGRP_PIPE)
          if (pipeline_pgrp == mypid)
@@ -1788,10 +1779,7 @@ itrace("make_child: give terminal to %d shell_pgrp = %d subshell_environment = %
       else                     /* Without job control... */
        {
          if (pipeline_pgrp == 0)
-{
            pipeline_pgrp = shell_pgrp;
-itrace("make_child: child proc: set pipeline_pgrp = %d (shell_pgrp)", pipeline_pgrp);
-}
 
          /* If these signals are set to SIG_DFL, we encounter the curious
             situation of an interactive ^Z to a running process *working*
@@ -1836,7 +1824,6 @@ itrace("make_child: child proc: set pipeline_pgrp = %d (shell_pgrp)", pipeline_p
          if (pipeline_pgrp == 0)
            {
              pipeline_pgrp = pid;
-itrace("make_child: parent proc: set pipeline_pgrp = %d (pid)", pipeline_pgrp);
              /* Don't twiddle terminal pgrps in the parent!  This is the bug,
                 not the good thing of twiddling them in the child! */
              /* give_terminal_to (pipeline_pgrp, 0); */
@@ -1850,11 +1837,7 @@ itrace("make_child: parent proc: set pipeline_pgrp = %d (pid)", pipeline_pgrp);
       else
        {
          if (pipeline_pgrp == 0)
-{
            pipeline_pgrp = shell_pgrp;
-itrace("make_child: parent proc: set pipeline_pgrp = %d (shell_pgrp)", pipeline_pgrp);
-}
-          
        }
 
       /* Place all processes into the jobs array regardless of the
@@ -2230,7 +2213,6 @@ wait_sigint_handler (sig)
   /* XXX - should this be interrupt_state?  If it is, the shell will act
      as if it got the SIGINT interrupt. */
   wait_sigint_received = 1;
-itrace("wait_sigint_handler: wait_sigint_received -> 1");
   /* Otherwise effectively ignore the SIGINT and allow the running job to
      be killed. */
   SIGRETURN (0);
@@ -2255,6 +2237,26 @@ process_exit_status (status)
     return (EXECUTION_SUCCESS);
 }
 
+static WAIT
+job_signal_status (job)
+     int job;
+{
+  register PROCESS *p;
+  WAIT s;
+
+  p = jobs[job]->pipe;
+  do
+    {
+      s = p->status;
+      if (WIFSIGNALED(s) || WIFSTOPPED(s))
+       break;
+      p = p->next;
+    }
+  while (p != jobs[job]->pipe);
+
+  return s;
+}
+  
 /* Return the exit status of the last process in the pipeline for job JOB.
    This is the exit status of the entire job. */
 static WAIT
@@ -2263,6 +2265,7 @@ raw_job_exit_status (job)
 {
   register PROCESS *p;
   int fail;
+  WAIT ret;
 
   if (pipefail_opt)
     {
@@ -2270,11 +2273,13 @@ raw_job_exit_status (job)
       p = jobs[job]->pipe;
       do
        {
-         if (WSTATUS (p->status) != EXECUTION_SUCCESS) fail = WSTATUS(p->status);
+         if (WSTATUS (p->status) != EXECUTION_SUCCESS)
+           fail = WSTATUS(p->status);
          p = p->next;
        }
       while (p != jobs[job]->pipe);
-      return fail;
+      WSTATUS (ret) = fail;
+      return ret;
     }
 
   for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next)
@@ -2448,7 +2453,6 @@ wait_for (pid)
   /* XXX */
   if ((job != NO_JOB && JOBSTATE (job) == JSTOPPED) || WIFSTOPPED (child->status))
     termination_state = 128 + WSTOPSIG (child->status);
-itrace("wait_for (%d): termination_state = %d last_command_exit_signal = %d", pid, termination_state, last_command_exit_signal);
 
   if (job == NO_JOB || IS_JOBCONTROL (job))
     {
@@ -2491,15 +2495,7 @@ if (job == NO_JOB)
             to a signal.  We might want to change this later to just check
             the last process in the pipeline.  If no process exits due to a
             signal, S is left as the status of the last job in the pipeline. */
-         p = jobs[job]->pipe;
-         do
-           {
-             s = p->status;
-             if (WIFSIGNALED(s) || WIFSTOPPED(s))
-               break;
-             p = p->next;
-           }
-         while (p != jobs[job]->pipe);
+         s = job_signal_status (job);
 
          if (WIFSIGNALED (s) || WIFSTOPPED (s))
            {
@@ -2533,6 +2529,24 @@ if (job == NO_JOB)
                }
            }
        }
+      else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received)
+       {
+         /* If waiting for a job in a subshell started to do command
+            substitution, simulate getting and being killed by the SIGINT to
+            pass the status back to our parent. */
+         s = job_signal_status (job);
+       
+         if (WIFSIGNALED (s) && WTERMSIG (s) == 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 ();
+             else
+               kill (getpid (), SIGINT);
+           }
+       }
 
       /* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
          signal handler path */
@@ -3026,7 +3040,6 @@ waitchld (wpid, block)
          wcontinued = 0;
          continue;     /* jump back to the test and retry without WCONTINUED */
        }
-itrace("waitchld: waitpid returns %d (status %d)", pid, status);
 
       /* The check for WNOHANG is to make sure we decrement sigchld only
         if it was non-zero before we called waitpid. */
@@ -4047,10 +4060,7 @@ set_job_control (arg)
   /* If we're turning on job control, reset pipeline_pgrp so make_child will
      put new child processes into the right pgrp */
   if (job_control != old && job_control)
-{
     pipeline_pgrp = 0;
-itrace("set_job_control: set pipeline_pgrp = 0");
-}
 
   return (old);
 }
diff --git a/jobs.c~ b/jobs.c~
index a5ac4221166490a84e0f57db9db48487e27fa17d..eb328a0c174cddcbd5bfb022dfefcfa6e4b2558a 100644 (file)
--- a/jobs.c~
+++ b/jobs.c~
@@ -137,8 +137,6 @@ extern int errno;
 /* The number of additional slots to allocate when we run out. */
 #define JOB_SLOTS 8
 
-#define CTTYFD 2
-
 typedef int sh_job_map_func_t __P((JOB *, int, int, int));
 
 /* Variables used here but defined in other files. */
@@ -252,6 +250,7 @@ static int job_exit_status __P((int));
 static int job_exit_signal __P((int));
 static int set_job_status_and_cleanup __P((int));
 
+static WAIT job_signal_status __P((int));
 static WAIT raw_job_exit_status __P((int));
 
 static void notify_of_job_status __P((void));
@@ -1676,6 +1675,7 @@ make_child (command, async_p)
      char *command;
      int async_p;
 {
+  int forksleep;
   sigset_t set, oset;
   pid_t pid;
 
@@ -1697,8 +1697,16 @@ make_child (command, async_p)
     sync_buffered_stream (default_buffered_input);
 #endif /* BUFFERED_INPUT */
 
-  /* Create the child, handle severe errors. */
-  if ((pid = fork ()) < 0)
+  /* Create the child, handle severe errors.  Retry on EAGAIN. */
+  while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
+    {
+      sys_error ("fork: retry");
+      if (sleep (forksleep) != 0)
+       break;
+      forksleep <<= 1;
+    }
+
+  if (pid < 0)
     {
       sys_error ("fork");
 
@@ -2205,7 +2213,6 @@ wait_sigint_handler (sig)
   /* XXX - should this be interrupt_state?  If it is, the shell will act
      as if it got the SIGINT interrupt. */
   wait_sigint_received = 1;
-
   /* Otherwise effectively ignore the SIGINT and allow the running job to
      be killed. */
   SIGRETURN (0);
@@ -2230,6 +2237,26 @@ process_exit_status (status)
     return (EXECUTION_SUCCESS);
 }
 
+static WAIT
+job_signal_status (job)
+     int job;
+{
+  register PROCESS *p;
+  WAIT s;
+
+  p = jobs[job]->pipe;
+  do
+    {
+      s = p->status;
+      if (WIFSIGNALED(s) || WIFSTOPPED(s))
+       break;
+      p = p->next;
+    }
+  while (p != jobs[job]->pipe);
+
+  return s;
+}
+  
 /* Return the exit status of the last process in the pipeline for job JOB.
    This is the exit status of the entire job. */
 static WAIT
@@ -2238,6 +2265,7 @@ raw_job_exit_status (job)
 {
   register PROCESS *p;
   int fail;
+  WAIT ret;
 
   if (pipefail_opt)
     {
@@ -2245,11 +2273,13 @@ raw_job_exit_status (job)
       p = jobs[job]->pipe;
       do
        {
-         if (WSTATUS (p->status) != EXECUTION_SUCCESS) fail = WSTATUS(p->status);
+         if (WSTATUS (p->status) != EXECUTION_SUCCESS)
+           fail = WSTATUS(p->status);
          p = p->next;
        }
       while (p != jobs[job]->pipe);
-      return fail;
+      WSTATUS (ret) = fail;
+      return ret;
     }
 
   for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next)
@@ -2312,11 +2342,14 @@ wait_for (pid)
      to finish.  We don't want the shell to exit if an interrupt is
      received, only if one of the jobs run is killed via SIGINT.  If
      job control is not set, the job will be run in the same pgrp as
-     the shell, and the shell will see any signals the job gets. */
+     the shell, and the shell will see any signals the job gets.  In
+     fact, we want this set every time the waiting shell and the waited-
+     for process are in the same process group, including command
+     substitution. */
 
   /* This is possibly a race condition -- should it go in stop_pipeline? */
   wait_sigint_received = 0;
-  if (job_control == 0)
+  if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
     {
       old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
       if (old_sigint_handler == SIG_IGN)
@@ -2462,15 +2495,7 @@ if (job == NO_JOB)
             to a signal.  We might want to change this later to just check
             the last process in the pipeline.  If no process exits due to a
             signal, S is left as the status of the last job in the pipeline. */
-         p = jobs[job]->pipe;
-         do
-           {
-             s = p->status;
-             if (WIFSIGNALED(s) || WIFSTOPPED(s))
-               break;
-             p = p->next;
-           }
-         while (p != jobs[job]->pipe);
+         s = job_signal_status (job);
 
          if (WIFSIGNALED (s) || WIFSTOPPED (s))
            {
@@ -2504,6 +2529,24 @@ if (job == NO_JOB)
                }
            }
        }
+      else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received)
+       {
+         /* If waiting for a job in a subshell started to do command
+            substitution, simulate getting and being killed by the SIGINT to
+            pass the status back to our parent. */
+         s = job_signal_status (job);
+       
+         if (WIFSIGNALED (s) && WTERMSIG (s) == 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 ();
+             else
+               kill (getpid (), SIGINT);
+           }
+       }
 
       /* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
          signal handler path */
@@ -3501,6 +3544,12 @@ initialize_job_control (force)
   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)
        shell_tty = open ("/dev/tty", O_RDWR|O_NONBLOCK);
 
@@ -3844,7 +3893,7 @@ count_all_jobs ()
     {
 #if defined (DEBUG)
       if (i < js.j_firstj && jobs[i])
-       itrace("count_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
+       itrace<("count_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
       if (i > js.j_lastj && jobs[i])
        itrace("count_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
 #endif
index c0532ca05439f4b44424d2120769472b3d82fac9..8cfd693bac509d28d1eba892c2a7399360f276a8 100644 (file)
@@ -938,8 +938,9 @@ rl_redisplay ()
             second and subsequent lines start at inv_lbreaks[N], offset by
             OFFSET (which has already been calculated above).  */
 
+#define INVIS_FIRST()  (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
 #define WRAP_OFFSET(line, offset)  ((line == 0) \
-                                       ? (offset ? prompt_invis_chars_first_line : 0) \
+                                       ? (offset ? INVIS_FIRST() : 0) \
                                        : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
 #define VIS_LLEN(l)    ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
index 15cc82f8033ec920b36826358abae69c5d9e08d7..73394672bc2aea2b422a3c3cdef59df1461984fa 100644 (file)
@@ -85,7 +85,7 @@ ttrestore()
   ttsaved = 0;
 }
 
-/* Retrieve the attributes associated with tty fd FD. */
+/* Retrieve the internally-saved attributes associated with tty fd FD. */
 TTYSTRUCT *
 ttattr (fd)
      int fd;
@@ -149,6 +149,17 @@ tt_setonechar(ttp)
   return 0;
 }
 
+/* Set the tty associated with FD and TTP into one-character-at-a-time mode */
+int
+ttfd_onechar (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setonechar(ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
 /* Set the terminal into one-character-at-a-time mode */
 int
 ttonechar ()
@@ -158,9 +169,7 @@ ttonechar ()
   if (ttsaved == 0)
     return -1;
   tt = ttin;
-  if (tt_setonechar(&tt) < 0)
-    return -1;
-  return (ttsetattr (0, &tt));
+  return (ttfd_onechar (0, &tt));
 }
 
 /*
@@ -180,6 +189,17 @@ tt_setnoecho(ttp)
   return 0;
 }
 
+/* Set the tty associated with FD and TTP into no-echo mode */
+int
+ttfd_noecho (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setnoecho (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
 /* Set the terminal into no-echo mode */
 int
 ttnoecho ()
@@ -189,9 +209,7 @@ ttnoecho ()
   if (ttsaved == 0)
     return -1;
   tt = ttin;
-  if (tt_setnoecho (&tt) < 0)
-    return -1;
-  return (ttsetattr (0, &tt));
+  return (ttfd_noecho (0, &tt));
 }
 
 /*
@@ -213,6 +231,17 @@ tt_seteightbit (ttp)
   return 0;
 }
 
+/* Set the tty associated with FD and TTP into eight-bit mode */
+int
+ttfd_eightbit (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_seteightbit (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
 /* Set the terminal into eight-bit mode */
 int
 tteightbit ()
@@ -222,9 +251,7 @@ tteightbit ()
   if (ttsaved == 0)
     return -1;
   tt = ttin;
-  if (tt_seteightbit (&tt) < 0)
-    return -1;
-  return (ttsetattr (0, &tt));
+  return (ttfd_eightbit (0, &tt));
 }
 
 /*
@@ -242,6 +269,17 @@ tt_setnocanon (ttp)
   return 0;
 }
 
+/* Set the tty associated with FD and TTP into non-canonical mode */
+int
+ttfd_nocanon (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setnocanon (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
 /* Set the terminal into non-canonical mode */
 int
 ttnocanon ()
@@ -251,9 +289,7 @@ ttnocanon ()
   if (ttsaved == 0)
     return -1;
   tt = ttin;
-  if (tt_setnocanon (&tt) < 0)
-    return -1;
-  return (ttsetattr (0, &tt));
+  return (ttfd_nocanon (0, &tt));
 }
 
 /*
@@ -269,6 +305,18 @@ tt_setcbreak(ttp)
   return (tt_setnoecho (ttp));
 }
 
+/* Set the tty associated with FD and TTP into cbreak (no-echo,
+   one-character-at-a-time) mode */
+int
+ttfd_cbreak (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setcbreak (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
 /* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
 int
 ttcbreak ()
@@ -278,7 +326,5 @@ ttcbreak ()
   if (ttsaved == 0)
     return -1;
   tt = ttin;
-  if (tt_setcbreak (&tt) < 0)
-    return -1;
-  return (ttsetattr (0, &tt));
+  return (ttfd_cbreak (0, &tt));
 }
diff --git a/lib/sh/shtty.c~ b/lib/sh/shtty.c~
new file mode 100644 (file)
index 0000000..2381ee2
--- /dev/null
@@ -0,0 +1,329 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Bash; see the file COPYING.  If not, write to the Free Software
+   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+/*
+ * shtty.c -- abstract interface to the terminal, focusing on capabilities.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+
+#include <shtty.h>
+
+static TTYSTRUCT ttin, ttout;
+static int ttsaved = 0;
+
+int
+ttgetattr(fd, ttp)
+int    fd;
+TTYSTRUCT *ttp;
+{
+#ifdef TERMIOS_TTY_DRIVER
+  return tcgetattr(fd, ttp);
+#else
+#  ifdef TERMIO_TTY_DRIVER
+  return ioctl(fd, TCGETA, ttp);
+#  else
+  return ioctl(fd, TIOCGETP, ttp);
+#  endif
+#endif
+}
+
+int
+ttsetattr(fd, ttp)
+int    fd;
+TTYSTRUCT *ttp;
+{
+#ifdef TERMIOS_TTY_DRIVER
+  return tcsetattr(fd, TCSADRAIN, ttp);
+#else
+#  ifdef TERMIO_TTY_DRIVER
+  return ioctl(fd, TCSETAW, ttp);
+#  else
+  return ioctl(fd, TIOCSETN, ttp);
+#  endif
+#endif
+}
+
+void
+ttsave()
+{
+  if (ttsaved)
+   return;
+  ttgetattr (0, &ttin);
+  ttgetattr (1, &ttout);
+  ttsaved = 1;
+}
+
+void
+ttrestore()
+{
+  if (ttsaved == 0)
+    return;
+  ttsetattr (0, &ttin);
+  ttsetattr (1, &ttout);
+  ttsaved = 0;
+}
+
+/* Retrieve the internally-saved attributes associated with tty fd FD. */
+TTYSTRUCT *
+ttattr (fd)
+     int fd;
+{
+  if (ttsaved == 0)
+    return ((TTYSTRUCT *)0);
+  if (fd == 0)
+    return &ttin;
+  else if (fd == 1)
+    return &ttout;
+  else
+    return ((TTYSTRUCT *)0);
+}
+
+/*
+ * Change attributes in ttp so that when it is installed using
+ * ttsetattr, the terminal will be in one-char-at-a-time mode.
+ */
+int
+tt_setonechar(ttp)
+     TTYSTRUCT *ttp;
+{
+#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
+
+  /* XXX - might not want this -- it disables erase and kill processing. */
+  ttp->c_lflag &= ~ICANON;
+
+  ttp->c_lflag |= ISIG;
+#  ifdef IEXTEN
+  ttp->c_lflag |= IEXTEN;
+#  endif
+
+  ttp->c_iflag |= ICRNL;       /* make sure we get CR->NL on input */
+  ttp->c_iflag &= ~INLCR;      /* but no NL->CR */
+
+#  ifdef OPOST
+  ttp->c_oflag |= OPOST;
+#  endif
+#  ifdef ONLCR
+  ttp->c_oflag |= ONLCR;
+#  endif
+#  ifdef OCRNL
+  ttp->c_oflag &= ~OCRNL;
+#  endif
+#  ifdef ONOCR
+  ttp->c_oflag &= ~ONOCR;
+#  endif
+#  ifdef ONLRET
+  ttp->c_oflag &= ~ONLRET;
+#  endif
+
+  ttp->c_cc[VMIN] = 1;
+  ttp->c_cc[VTIME] = 0;
+
+#else
+
+  ttp->sg_flags |= CBREAK;
+
+#endif
+
+  return 0;
+}
+
+/* Set the tty associated with FD and TTP into one-character-at-a-time mode */
+int
+ttfd_onechar (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setonechar(ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
+/* Set the terminal into one-character-at-a-time mode */
+int
+ttonechar ()
+{
+  TTYSTRUCT tt;
+
+  if (ttsaved == 0)
+    return -1;
+  tt = ttin;
+  return (ttfd_onechar (0, &tt));
+}
+
+/*
+ * Change attributes in ttp so that when it is installed using
+ * ttsetattr, the terminal will be in no-echo mode.
+ */
+int
+tt_setnoecho(ttp)
+     TTYSTRUCT *ttp;
+{
+#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
+  ttp->c_lflag &= ~(ECHO|ECHOK|ECHONL);
+#else
+  ttp->sg_flags &= ~ECHO;
+#endif
+
+  return 0;
+}
+
+/* Set the tty associated with FD and TTP into no-echo mode */
+int
+ttfd_noecho (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setnoecho (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
+/* Set the terminal into no-echo mode */
+int
+ttnoecho ()
+{
+  TTYSTRUCT tt;
+
+  if (ttsaved == 0)
+    return -1;
+  tt = ttin;
+  return (ttfd_noecho (0, &tt));
+}
+
+/*
+ * Change attributes in ttp so that when it is installed using
+ * ttsetattr, the terminal will be in eight-bit mode (pass8).
+ */
+int
+tt_seteightbit (ttp)
+     TTYSTRUCT *ttp;
+{
+#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
+  ttp->c_iflag &= ~ISTRIP;
+  ttp->c_cflag |= CS8;
+  ttp->c_cflag &= ~PARENB;
+#else
+  ttp->sg_flags |= ANYP;
+#endif
+
+  return 0;
+}
+
+/* Set the tty associated with FD and TTP into eight-bit mode */
+int
+ttfd_eightbit (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_seteightbit (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
+/* Set the terminal into eight-bit mode */
+int
+tteightbit ()
+{
+  TTYSTRUCT tt;
+
+  if (ttsaved == 0)
+    return -1;
+  tt = ttin;
+  return (ttfd_eightbit (0, &tt));
+}
+
+/*
+ * Change attributes in ttp so that when it is installed using
+ * ttsetattr, the terminal will be in non-canonical input mode.
+ */
+int
+tt_setnocanon (ttp)
+     TTYSTRUCT *ttp;
+{
+#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
+  ttp->c_lflag &= ~ICANON;
+#endif
+
+  return 0;
+}
+
+/* Set the tty associated with FD and TTP into non-canonical mode */
+int
+ttfd_nocanon (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setnocanon (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
+/* Set the terminal into non-canonical mode */
+int
+ttnocanon ()
+{
+  TTYSTRUCT tt;
+
+  if (ttsaved == 0)
+    return -1;
+  tt = ttin;
+  return (ttfd_nocanon (0, &tt));
+}
+
+/*
+ * Change attributes in ttp so that when it is installed using
+ * ttsetattr, the terminal will be in cbreak, no-echo mode.
+ */
+int
+tt_setcbreak(ttp)
+     TTYSTRUCT *ttp;
+{
+  if (tt_setonechar (ttp) < 0)
+    return -1;
+  return (tt_setnoecho (ttp));
+}
+
+/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
+int
+ttfd_cbreak (fd, ttp)
+     int fd;
+     TTYSTRUCT *ttp;
+{
+  if (tt_setcbreak (ttp) < 0)
+    return -1;
+  return (ttsetattr (fd, ttp));
+}
+
+/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
+int
+ttcbreak ()
+{
+  TTYSTRUCT tt;
+
+  if (ttsaved == 0)
+    return -1;
+  tt = ttin;
+  return (ttfd_cbreak (0, &tt));
+}
diff --git a/sig.c b/sig.c
index 5bb91e0b35820349dffa38b5d87a2ca45d6356a6..f6c4b42c94b2653e9521fb4b82d7834fa2e6a2cb 100644 (file)
--- a/sig.c
+++ b/sig.c
@@ -1,6 +1,6 @@
 /* sig.c - interface for shell signal handlers and signal initialization. */
 
-/* Copyright (C) 1994-2006 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2007 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -508,7 +508,7 @@ sigint_sighandler (sig)
      right.  Should it be set unconditionally? */
   if (interrupt_state == 0)
     ADDINTERRUPT;
-itrace("sigint_sighandler");
+
   if (interrupt_immediately)
     {
       interrupt_immediately = 0;
diff --git a/subst.c b/subst.c
index 306092e44bd105e798d176340e07f91237d7d6b9..0a74b9d08d98c096734dac419ac5345f840302b3 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -4391,6 +4391,7 @@ process_substitute (string, open_for_read_in_child)
 #if defined (JOB_CONTROL)
   set_sigchld_handler ();
   stop_making_children ();
+  /* XXX - should we only do this in the parent? (as in command subst) */
   pipeline_pgrp = old_pipeline_pgrp;
 #endif /* JOB_CONTROL */
 
@@ -4666,10 +4667,7 @@ command_substitute (string, quoted)
   old_pipeline_pgrp = pipeline_pgrp;
   /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
   if ((subshell_environment & SUBSHELL_PIPE) == 0)
-{
     pipeline_pgrp = shell_pgrp;
-itrace("command_substitute: set pipeline_pgrp = shell_pgrp = %d", pipeline_pgrp);
-}
   cleanup_the_pipeline ();
 #endif /* JOB_CONTROL */
 
@@ -4687,10 +4685,7 @@ itrace("command_substitute: set pipeline_pgrp = shell_pgrp = %d", pipeline_pgrp)
   set_sigchld_handler ();
   stop_making_children ();
   if (pid != 0)
-{
     pipeline_pgrp = old_pipeline_pgrp;
-itrace("command_substitute: set pipeline_pgrp = %d (old_pipeline_pgrp)", pipeline_pgrp);
-}
 #else
   stop_making_children ();
 #endif /* JOB_CONTROL */
@@ -4797,7 +4792,6 @@ itrace("command_substitute: set pipeline_pgrp = %d (old_pipeline_pgrp)", pipelin
 
       current_command_subst_pid = pid;
       last_command_exit_value = wait_for (pid);
-itrace("command_substitute: waited for pid %d: status %d", pid, last_command_exit_value);
       last_command_subst_pid = pid;
       last_made_pid = old_pid;
 
@@ -7040,7 +7034,7 @@ add_string:
              free (temp);
              temp = temp1;
              sindex += t_index;
-             goto add_string;
+             goto add_quoted_string;           /* XXX was add_string */
            }
          else
            {
index 56a6294fd994f7bbe49643f196b3c6aef6eebb74..c9171b1681a342feee6a4260e89e24a3254ba49b 100644 (file)
--- a/subst.c~
+++ b/subst.c~
@@ -2370,9 +2370,6 @@ do_assignment_internal (word, expand)
 
   stupidly_hack_special_variables (name);
 
-  if (entry)
-    VUNSETATTR (entry, att_invisible);
-
 #if 1
   /* Return 1 if the assignment seems to have been performed correctly. */
   if (entry == 0 || readonly_p (entry))
@@ -2385,7 +2382,13 @@ do_assignment_internal (word, expand)
   else
     retval = 1;
   ASSIGN_RETURN (retval);
+
+  if (entry && retval != 0)
+    VUNSETATTR (entry, att_invisible);
 #else
+  if (entry)
+    VUNSETATTR (entry, att_invisible);
+
   ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
 #endif
 }
@@ -4388,6 +4391,7 @@ process_substitute (string, open_for_read_in_child)
 #if defined (JOB_CONTROL)
   set_sigchld_handler ();
   stop_making_children ();
+  /* XXX - should we only do this in the parent? (as in command subst) */
   pipeline_pgrp = old_pipeline_pgrp;
 #endif /* JOB_CONTROL */
 
@@ -4677,9 +4681,11 @@ command_substitute (string, quoted)
     reset_signal_handlers ();
 
 #if defined (JOB_CONTROL)
+  /* XXX DO THIS ONLY IN PARENT ? XXX */
   set_sigchld_handler ();
   stop_making_children ();
-  pipeline_pgrp = old_pipeline_pgrp;
+  if (pid != 0)
+    pipeline_pgrp = old_pipeline_pgrp;
 #else
   stop_making_children ();
 #endif /* JOB_CONTROL */
@@ -6692,6 +6698,13 @@ comsub:
       t_index = zindex + 1;
       temp = extract_arithmetic_subst (string, &t_index);
       zindex = t_index;
+      if (temp == 0)
+       {
+         temp = savestring (string);
+         if (expanded_something)
+           *expanded_something = 0;
+         goto return0;
+       }         
 
        /* Do initial variable expansion. */
       temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
index e467dd9d051544e11305c0b3e8fc7d680f1d7050..358b27815cc7d3660c46293cdd13f6389a80a9c2 100755 (executable)
@@ -142,7 +142,7 @@ freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*|dragonfly*)
        ;;
 
 # Darwin/MacOS X
-darwin8*)
+darwin[89]*)
        SHOBJ_STATUS=supported
        SHLIB_STATUS=supported
        
@@ -171,7 +171,7 @@ darwin*|macosx*)
        SHLIB_LIBSUFF='dylib'
 
        case "${host_os}" in
-       darwin[78]*)    SHOBJ_LDFLAGS=''
+       darwin[789]*)   SHOBJ_LDFLAGS=''
                        SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
                        ;;
        *)              SHOBJ_LDFLAGS='-dynamic'
index 2f163913d18eccce4986b792f3729cfdd4a2a456..e467dd9d051544e11305c0b3e8fc7d680f1d7050 100755 (executable)
@@ -10,7 +10,7 @@
 # Chet Ramey
 # chet@po.cwru.edu
 
-# Copyright (C) 1996-2002 Free Software Foundation, Inc.
+# Copyright (C) 1996-2007 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -153,7 +153,7 @@ darwin8*)
        SHLIB_LIBVERSION='$(SHLIB_MAJOR)$(SHLIB_MINOR).$(SHLIB_LIBSUFF)'
        SHLIB_LIBSUFF='dylib'
 
-       SHOBJ_LDFLAGS='-dynamiclib -dynamic -undefined dynamic_lookup'
+       SHOBJ_LDFLAGS='-dynamiclib -dynamic -undefined dynamic_lookup -arch_only `/usr/bin/arch`'
        SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
 
        SHLIB_LIBS='-lncurses'  # see if -lcurses works on MacOS X 10.1 
@@ -247,7 +247,7 @@ osf*)
        SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
        ;;
 
-aix4.[2-9]*-*gcc*            # lightly tested by jik@cisco.com
+aix4.[2-9]*-*gcc*|aix[5-9].*-*gcc*)            # lightly tested by jik@cisco.com
        SHOBJ_CFLAGS=-fpic
        SHOBJ_LD='ld'
        SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall'
@@ -258,7 +258,7 @@ aix4.[2-9]*-*gcc*)          # lightly tested by jik@cisco.com
        SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
        ;;
 
-aix4.[2-9]*)
+aix4.[2-9]*|aix[5-9].*)
        SHOBJ_CFLAGS=-K
        SHOBJ_LD='ld'
        SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall'
@@ -329,7 +329,7 @@ hpux10*-*gcc*)
        SHOBJ_LD='${CC}'
        # if you have problems linking here, moving the `-Wl,+h,$@' from
        # SHLIB_XLDFLAGS to SHOBJ_LDFLAGS has been reported to work
-       SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s'
+       SHOBJ_LDFLAGS='-shared -fpic -Wl,-b -Wl,+s'
 
        SHLIB_XLDFLAGS='-Wl,+h,$@ -Wl,+b,$(libdir)'
        SHLIB_LIBSUFF='sl'