Imported from ../bash-3.2.48.tar.gz.
[platform/upstream/bash.git] / builtins / evalstring.c
index 88d6a9e..511ce86 100644 (file)
@@ -1,4 +1,6 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Evaluate a string as one or more shell commands.
+
+   Copyright (C) 1996-2005 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -54,16 +56,25 @@ extern int errno;
 
 #define IS_BUILTIN(s)  (builtin_address_internal(s, 0) != (struct builtin *)NULL)
 
-extern int indirection_level, startup_state, subshell_environment;
+extern int indirection_level, subshell_environment;
 extern int line_number;
 extern int last_command_exit_value;
 extern int running_trap;
+extern int loop_level;
 extern int posixly_correct;
 
 int parse_and_execute_level = 0;
 
 static int cat_file __P((REDIRECT *));
 
+#if defined (HISTORY)
+static void
+set_history_remembering ()
+{
+  remember_on_history = enable_history_list;
+}
+#endif
+
 /* How to force parse_and_execute () to clean up after itself. */
 void
 parse_and_execute_cleanup ()
@@ -105,13 +116,17 @@ parse_and_execute (string, from_file, flags)
   unwind_protect_jmp_buf (top_level);
   unwind_protect_int (indirection_level);
   unwind_protect_int (line_number);
+  unwind_protect_int (loop_level);
   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 (parse_and_execute_level == 0)
+    add_unwind_protect (set_history_remembering, (char *)NULL);
+  else
+    unwind_protect_int (remember_on_history);  /* can be used in scripts */
 #  if defined (BANG_HISTORY)
   if (interactive_shell)
     {
@@ -231,17 +246,23 @@ parse_and_execute (string, from_file, flags)
               * IF
               *   we were invoked as `bash -c' (startup_state == 2) AND
               *   parse_and_execute has not been called recursively AND
+              *   we're not running a trap AND
               *   we have parsed the full command (string == '\0') AND
+              *   we're not going to run the exit trap 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
               */
              if (startup_state == 2 && parse_and_execute_level == 1 &&
+                 running_trap == 0 &&
                  *bash_input.location.string == '\0' &&
                  command->type == cm_simple &&
-                 !command->redirects && !command->value.Simple->redirects &&
-                 ((command->flags & CMD_TIME_PIPELINE) == 0))
+                 signal_is_trapped (EXIT_TRAP) == 0 &&
+                 command->redirects == 0 && command->value.Simple->redirects == 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;
@@ -308,9 +329,8 @@ static int
 cat_file (r)
      REDIRECT *r;
 {
-  char lbuf[128], *fn;
+  char *fn;
   int fd, rval;
-  ssize_t nr;
 
   if (r->instruction != r_input_direction)
     return -1;