]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20050310 snapshot
authorChet Ramey <chet.ramey@case.edu>
Sat, 3 Dec 2011 18:44:37 +0000 (13:44 -0500)
committerChet Ramey <chet.ramey@case.edu>
Sat, 3 Dec 2011 18:44:37 +0000 (13:44 -0500)
CWRU/CWRU.chlog
CWRU/CWRU.chlog~
builtins/evalstring.c
builtins/evalstring.c~ [new file with mode: 0644]
builtins/read.def
lib/sh/zread.c
tests/run-intl
tests/run-intl~
tests/run-read
tests/run-read~ [new file with mode: 0644]

index 439c0420a773c433b4db74e302dd1e20703652ad..18732f80ecc631be0971af5f153ea0e47920bd98 100644 (file)
@@ -11166,3 +11166,20 @@ configure.in
 bashline.c
        - make bash_directory_expansion a void function, since it doesn't have
          any return value
+
+                                   3/9
+                                   ---
+builtins/read.def
+       - when testing for a pipe, use `fd' instead of hard-coding 0, since we
+         can read from other file descriptors now
+
+lib/sh/zread.c
+       - in zsyncfd, only set lind and lused to 0 if the lseek succeeds.
+         If the lseek fails, we might steal input from other programs, but
+         a failed lseek won't cause us to erroneously discard input
+
+                                  3/11
+                                  ----
+builtins/evalstring.c
+       - don't allow parse_and_execute to short-circuit and call exec() if
+         the command's return value is being inverted
index ae6ca9cd98a0e921d0c278e539201fc195bcdae3..92ad7d5cc1b7781bc3e9d2d87aaf07bb3e327b2a 100644 (file)
@@ -11151,5 +11151,29 @@ builtins/read.def
          the input (including any trailing field delimiters), falling back
          to the previous behavior if it does not.  This is what POSIX.2
          specifies, I believe (and the consensus of the austin-group list).
-         This requires a few tests in read.tests to be changed
+         This requires a few tests in read.tests to be changed: backslashes
+         escaping IFS whitespace characters at the end of input cause the
+         whitespace characters to be preserved in the value assigned to the
+         variable, and the trailing non-whitespace field delimiter issue
 
+                                   3/7
+                                   ---
+configure.in
+       - add -D_POSIX_SOURCE to the LOCAL_CFLAGS for Interix
+
+                                   3/8
+                                   ---
+bashline.c
+       - make bash_directory_expansion a void function, since it doesn't have
+         any return value
+
+                                   3/9
+                                   ---
+builtins/read.def
+       - when testing for a pipe, use `fd' instead of hard-coding 0, since we
+         can read from other file descriptors now
+
+lib/sh/zread.c
+       - in zsyncfd, only set lind and lused to 0 if the lseek succeeds.
+         If the lseek fails, we might steal input from other programs, but
+         a failed lseek won't cause us to erroneously discard input
index 88d6a9e5b6da1d39eab46181bc9583ea0ff18579..f9e161343ae1c445643a6012a9516ec0bd1f9842 100644 (file)
@@ -233,7 +233,8 @@ parse_and_execute (string, from_file, flags)
               *   parse_and_execute has not been called recursively AND
               *   we have parsed the full command (string == '\0') AND
               *   we have a simple command without redirections AND
-              *   the command is not being timed
+              *   the command is not being timed AND
+              *   the command's return status is not being inverted
               * THEN
               *   tell the execution code that we don't need to fork
               */
@@ -241,7 +242,8 @@ parse_and_execute (string, from_file, flags)
                  *bash_input.location.string == '\0' &&
                  command->type == cm_simple &&
                  !command->redirects && !command->value.Simple->redirects &&
-                 ((command->flags & CMD_TIME_PIPELINE) == 0))
+                 ((command->flags & CMD_TIME_PIPELINE) == 0) &&
+                 ((command->flags & CMD_INVERT_RETURN) == 0))
                {
                  command->flags |= CMD_NO_FORK;
                  command->value.Simple->flags |= CMD_NO_FORK;
diff --git a/builtins/evalstring.c~ b/builtins/evalstring.c~
new file mode 100644 (file)
index 0000000..9c8a4a2
--- /dev/null
@@ -0,0 +1,346 @@
+/* Copyright (C) 1996 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. */
+
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+#  ifdef _MINIX
+#    include <sys/types.h>
+#  endif
+#  include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+
+#include <errno.h>
+
+#include "filecntl.h"
+#include "../bashansi.h"
+
+#include "../shell.h"
+#include "../jobs.h"
+#include "../builtins.h"
+#include "../flags.h"
+#include "../input.h"
+#include "../execute_cmd.h"
+#include "../redir.h"
+#include "../trap.h"
+
+#if defined (HISTORY)
+#  include "../bashhist.h"
+#endif
+
+#include "common.h"
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#define IS_BUILTIN(s)  (builtin_address_internal(s, 0) != (struct builtin *)NULL)
+
+extern int indirection_level, startup_state, subshell_environment;
+extern int line_number;
+extern int last_command_exit_value;
+extern int running_trap;
+extern int posixly_correct;
+
+int parse_and_execute_level = 0;
+
+static int cat_file __P((REDIRECT *));
+
+/* How to force parse_and_execute () to clean up after itself. */
+void
+parse_and_execute_cleanup ()
+{
+  if (running_trap)
+    {
+      run_trap_cleanup (running_trap - 1);
+      unfreeze_jobs_list ();
+    }
+  run_unwind_frame ("parse_and_execute_top");
+}
+
+/* Parse and execute the commands in STRING.  Returns whatever
+   execute_command () returns.  This frees STRING.  FLAGS is a
+   flags word; look in common.h for the possible values.  Actions
+   are:
+       (flags & SEVAL_NONINT) -> interactive = 0;
+       (flags & SEVAL_INTERACT) -> interactive = 1;
+       (flags & SEVAL_NOHIST) -> call bash_history_disable ()
+       (flags & SEVAL_NOFREE) -> don't free STRING when finished
+       (flags & SEVAL_RESETLINE) -> reset line_number to 1
+*/
+
+int
+parse_and_execute (string, from_file, flags)
+     char *string;
+     const char *from_file;
+     int flags;
+{
+  int code, x, lreset;
+  volatile int should_jump_to_top_level, last_result;
+  char *orig_string;
+  COMMAND *volatile command;
+
+  orig_string = string;
+  /* Unwind protect this invocation of parse_and_execute (). */
+  begin_unwind_frame ("parse_and_execute_top");
+  unwind_protect_int (parse_and_execute_level);
+  unwind_protect_jmp_buf (top_level);
+  unwind_protect_int (indirection_level);
+  unwind_protect_int (line_number);
+  if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
+    unwind_protect_int (interactive);
+
+  lreset = flags & SEVAL_RESETLINE;
+
+#if defined (HISTORY)
+  unwind_protect_int (remember_on_history);    /* can be used in scripts */
+#  if defined (BANG_HISTORY)
+  if (interactive_shell)
+    {
+      unwind_protect_int (history_expansion_inhibited);
+    }
+#  endif /* BANG_HISTORY */
+#endif /* HISTORY */
+
+  if (interactive_shell)
+    {
+      x = get_current_prompt_level ();
+      add_unwind_protect (set_current_prompt_level, x);
+    }
+  
+  add_unwind_protect (pop_stream, (char *)NULL);
+  if (orig_string && ((flags & SEVAL_NOFREE) == 0))
+    add_unwind_protect (xfree, orig_string);
+  end_unwind_frame ();
+
+  parse_and_execute_level++;
+
+  /* Reset the line number if the caller wants us to.  If we don't reset the
+     line number, we have to subtract one, because we will add one just
+     before executing the next command (resetting the line number sets it to
+     0; the first line number is 1). */
+  push_stream (lreset);
+  if (lreset == 0)
+    line_number--;
+    
+  indirection_level++;
+  if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
+    interactive = (flags & SEVAL_NONINT) ? 0 : 1;
+
+#if defined (HISTORY)
+  if (flags & SEVAL_NOHIST)
+    bash_history_disable ();
+#endif /* HISTORY */
+
+  code = should_jump_to_top_level = 0;
+  last_result = EXECUTION_SUCCESS;
+
+  with_input_from_string (string, from_file);
+  while (*(bash_input.location.string))
+    {
+      command = (COMMAND *)NULL;
+
+      if (interrupt_state)
+       {
+         last_result = EXECUTION_FAILURE;
+         break;
+       }
+
+      /* Provide a location for functions which `longjmp (top_level)' to
+        jump to.  This prevents errors in substitution from restarting
+        the reader loop directly, for example. */
+      code = setjmp (top_level);
+
+      if (code)
+       {
+         should_jump_to_top_level = 0;
+         switch (code)
+           {
+           case FORCE_EOF:
+           case ERREXIT:
+           case EXITPROG:
+             if (command)
+               run_unwind_frame ("pe_dispose");
+             /* Remember to call longjmp (top_level) after the old
+                value for it is restored. */
+             should_jump_to_top_level = 1;
+             goto out;
+
+           case DISCARD:
+             if (command)
+               run_unwind_frame ("pe_dispose");
+             last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
+             if (subshell_environment)
+               {
+                 should_jump_to_top_level = 1;
+                 goto out;
+               }
+             else
+               {
+#if 0
+                 dispose_command (command);    /* pe_dispose does this */
+#endif
+                 continue;
+               }
+
+           default:
+             command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
+             break;
+           }
+       }
+         
+      if (parse_command () == 0)
+       {
+         if (interactive_shell == 0 && read_but_dont_execute)
+           {
+             last_result = EXECUTION_SUCCESS;
+             dispose_command (global_command);
+             global_command = (COMMAND *)NULL;
+           }
+         else if (command = global_command)
+           {
+             struct fd_bitmap *bitmap;
+
+             bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
+             begin_unwind_frame ("pe_dispose");
+             add_unwind_protect (dispose_fd_bitmap, bitmap);
+             add_unwind_protect (dispose_command, command);    /* XXX */
+
+             global_command = (COMMAND *)NULL;
+
+#if defined (ONESHOT)
+             /*
+              * IF
+              *   we were invoked as `bash -c' (startup_state == 2) AND
+              *   parse_and_execute has not been called recursively AND
+              *   we have parsed the full command (string == '\0') AND
+              *   we have a simple command without redirections AND
+              *   the command is not being timed
+              * THEN
+              *   tell the execution code that we don't need to fork
+              */
+             if (startup_state == 2 && parse_and_execute_level == 1 &&
+                 *bash_input.location.string == '\0' &&
+                 command->type == cm_simple &&
+                 !command->redirects && !command->value.Simple->redirects &&
+                 ((command->flags & CMD_TIME_PIPELINE) == 0) &&
+                 ((command->flags & CMD_INVERT_RETURN) == 0))
+               {
+                 command->flags |= CMD_NO_FORK;
+                 command->value.Simple->flags |= CMD_NO_FORK;
+               }
+#endif /* ONESHOT */
+
+             /* See if this is a candidate for $( <file ). */
+             if (startup_state == 2 &&
+                 (subshell_environment & SUBSHELL_COMSUB) &&
+                 *bash_input.location.string == '\0' &&
+                 command->type == cm_simple && !command->redirects &&
+                 (command->flags & CMD_TIME_PIPELINE) == 0 &&
+                 command->value.Simple->words == 0 &&
+                 command->value.Simple->redirects &&
+                 command->value.Simple->redirects->next == 0 &&
+                 command->value.Simple->redirects->instruction == r_input_direction)
+               {
+                 int r;
+                 r = cat_file (command->value.Simple->redirects);
+                 last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
+               }
+             else
+               last_result = execute_command_internal
+                               (command, 0, NO_PIPE, NO_PIPE, bitmap);
+
+             dispose_command (command);
+             dispose_fd_bitmap (bitmap);
+             discard_unwind_frame ("pe_dispose");
+           }
+       }
+      else
+       {
+         last_result = EXECUTION_FAILURE;
+
+         /* Since we are shell compatible, syntax errors in a script
+            abort the execution of the script.  Right? */
+         break;
+       }
+    }
+
+ out:
+
+  run_unwind_frame ("parse_and_execute_top");
+
+  if (interrupt_state && parse_and_execute_level == 0)
+    {
+      /* An interrupt during non-interactive execution in an
+        interactive shell (e.g. via $PROMPT_COMMAND) should
+        not cause the shell to exit. */
+      interactive = interactive_shell;
+      throw_to_top_level ();
+    }
+
+  if (should_jump_to_top_level)
+    jump_to_top_level (code);
+
+  return (last_result);
+}
+
+/* Handle a $( < file ) command substitution.  This expands the filename,
+   returning errors as appropriate, then just cats the file to the standard
+   output. */
+static int
+cat_file (r)
+     REDIRECT *r;
+{
+  char lbuf[128], *fn;
+  int fd, rval;
+  ssize_t nr;
+
+  if (r->instruction != r_input_direction)
+    return -1;
+
+  /* Get the filename. */
+  if (posixly_correct && !interactive_shell)
+    disallow_filename_globbing++;
+  fn = redirection_expand (r->redirectee.filename);
+  if (posixly_correct && !interactive_shell)
+    disallow_filename_globbing--;
+
+  if (fn == 0)
+    {
+      redirection_error (r, AMBIGUOUS_REDIRECT);
+      return -1;
+    }
+
+  fd = open(fn, O_RDONLY);
+  if (fd < 0)
+    {
+      file_error (fn);
+      free (fn);
+      return -1;
+    }
+
+  rval = zcatfd (fd, 1, fn);
+
+  free (fn);
+  close (fd);
+
+  return (rval);
+}
index 05e69e853a79654696922b3872f8dffea30be4e4..c5f658e940d692ce562696d645ef98d312a8076e 100644 (file)
@@ -276,7 +276,7 @@ read_builtin (list)
   input_is_tty = isatty (fd);
   if (input_is_tty == 0)
 #ifndef __CYGWIN__
-    input_is_pipe = (lseek (0, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
+    input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
 #else
     input_is_pipe = 1;
 #endif
index b5155488f1545b84a4019929a055223dfe3fe7bb..460234b999b35a913b203a4a063750e671b7ba5d 100644 (file)
@@ -124,9 +124,13 @@ zsyncfd (fd)
      int fd;
 {
   off_t off;
+  int r;
 
   off = lused - lind;
+  r = 0;
   if (off > 0)
-    lseek (fd, -off, SEEK_CUR);
-  lused = lind = 0;
+    r = lseek (fd, -off, SEEK_CUR);
+
+  if (r >= 0)
+    lused = lind = 0;
 }
index 48b1c83126147ad6fd7e09ef6bc55237a4fa5e22..6a9234a3ba971bfe422c0637291b6bba6be5062e 100644 (file)
@@ -3,5 +3,6 @@
 
 echo "warning: some of these tests will fail if you do not have UTF-8" >&2
 echo "warning: locales installed on your system." >&2
+echo "warning: please ignore any differences consisting only of white space" >&2
 ${THIS_SH} ./intl.tests > /tmp/xx
 diff $AFLAG /tmp/xx intl.right && rm -f /tmp/xx
index c31a3793323854faa3e52abcc5f6be6cfa27516e..48b1c83126147ad6fd7e09ef6bc55237a4fa5e22 100644 (file)
@@ -1,4 +1,7 @@
+# See whether or not we can use `diff -a'
+( diff -a ./intl.right ./intl.right >/dev/null 2>&1 ) && AFLAG=-a
+
 echo "warning: some of these tests will fail if you do not have UTF-8" >&2
 echo "warning: locales installed on your system." >&2
 ${THIS_SH} ./intl.tests > /tmp/xx
-diff /tmp/xx intl.right && rm -f /tmp/xx
+diff $AFLAG /tmp/xx intl.right && rm -f /tmp/xx
index b7a4268132d55bcfdd741f6bcdc672bd01cc48d2..47e4188b9977ab277b321f478fc06ba6b253a5b9 100644 (file)
@@ -1,4 +1,4 @@
-echo "warning: different versions of wc put differing amounts of whitespace" >&2
-echo "warning: before their output.  Please do not consider this an error." >&2
+echo "warning: please do not consider output differing only in the amount of" >&2
+echo "warning: white space to be an error." >&2
 ${THIS_SH} ./read.tests > /tmp/xx 2>&1
 diff /tmp/xx read.right && rm -f /tmp/xx
diff --git a/tests/run-read~ b/tests/run-read~
new file mode 100644 (file)
index 0000000..b7a4268
--- /dev/null
@@ -0,0 +1,4 @@
+echo "warning: different versions of wc put differing amounts of whitespace" >&2
+echo "warning: before their output.  Please do not consider this an error." >&2
+${THIS_SH} ./read.tests > /tmp/xx 2>&1
+diff /tmp/xx read.right && rm -f /tmp/xx