]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20140815 snapshot
authorChet Ramey <chet.ramey@case.edu>
Fri, 29 Aug 2014 13:15:21 +0000 (09:15 -0400)
committerChet Ramey <chet.ramey@case.edu>
Fri, 29 Aug 2014 13:15:21 +0000 (09:15 -0400)
CWRU/CWRU.chlog
execute_cmd.c
jobs.c
lib/sh/unicode.c
nojobs.c
patchlevel.h
shell.c

index 4748c6331efece8f8bd28294560776ae57eb274a..a419df9882afba724648e9fa1a3f639a81609e93 100644 (file)
@@ -6515,3 +6515,40 @@ parse.y
          token. This lets the higher layers deal with quoted newlines after
          the command substitution. Fixes bug reported by EmanueL Czirai
          <amanual@riseup.net>
+
+                                  8/11
+                                  ----
+execute_cmd.c
+       - execute_pipeline: check whether lastpipe_jid corresponds to a valid
+         job before calling append_process, for the same reason as fix from
+         6/19.  Fixes bug reported by <lolilolicon@gmail.com>
+
+                                  8/12
+                                  ----
+lib/sh/unicode.c
+       - stub_charset: use strncpy instead of strcpy because we are copying
+         into a local fixed-length buffer.  Fixes vulnerability reported by
+         <romerox.adrian@gmail.com>
+
+execute_cmd.c
+       - execute_pipeline: if we don't call append_process, call
+         wait_for_single_pid to get the status of `lastpid', since that will
+         check the status of already-reaped processes.  Fixes spurious error
+         message about non-existent process from fix of 8/11
+
+                                  8/15
+                                  ----
+jobs.c
+       - running_in_background: new variable, keeps track of whether or not we
+         are running in the background (not perfect yet)
+       - initialize_job_control: even if we are not turning on job control,
+         get the terminal pgrp so we can use it later
+       - {set_job_control,initialize_job_control}: set running_in_background
+         to 1 if terminal pgrp != shell pgrp
+       - {stop_pipeline,make_child,wait_for}: if we are running in the
+         background, don't mess with the terminal's process group; assume that
+         the parent shell will do that.  Fixes bug reprted by Greg Wooledge
+         <wooledg@eeg.ccf.org>
+
+shell.c
+       - shell_reinitialize: reset running_in_background back to 0
index f0f115b85d03e6c41e881c7d8d743e68b9a4621a..1f5c9e2e0bd65f6b824183cdd99db45642490800 100644 (file)
@@ -1469,7 +1469,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
   login_shell = interactive = 0;
 
   if (user_subshell)
-    subshell_environment = SUBSHELL_PAREN;
+    subshell_environment = SUBSHELL_PAREN;     /* XXX */
   else
     {
       subshell_environment = 0;                        /* XXX */
@@ -2432,9 +2432,17 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
   if (lastpipe_flag)
     {
 #if defined (JOB_CONTROL)
-      append_process (savestring (the_printed_command), dollar_dollar_pid, exec_result, lastpipe_jid);
-#endif
+      if (INVALID_JOB (lastpipe_jid) == 0)
+        {
+          append_process (savestring (the_printed_command_except_trap), dollar_dollar_pid, exec_result, lastpipe_jid);
+          lstdin = wait_for (lastpid);
+        }
+      else
+        lstdin = wait_for_single_pid (lastpid);                /* checks bgpids list */
+#else
       lstdin = wait_for (lastpid);
+#endif
+
 #if defined (JOB_CONTROL)
       /* If wait_for removes the job from the jobs table, use result of last
         command as pipeline's exit status as usual.  The jobs list can get
@@ -3973,7 +3981,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
          already_forked = 1;
          simple_command->flags |= CMD_NO_FORK;
 
-         subshell_environment = SUBSHELL_FORK;
+         subshell_environment = SUBSHELL_FORK;         /* XXX */
          if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
            subshell_environment |= SUBSHELL_PIPE;
          if (async)
@@ -5000,7 +5008,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
       if (async)
        interactive = 0;
 
-      subshell_environment = SUBSHELL_FORK;
+      subshell_environment = SUBSHELL_FORK;    /* XXX */
 
       if (redirects && (do_redirections (redirects, RX_ACTIVE) != 0))
        {
diff --git a/jobs.c b/jobs.c
index c45f43c0612fc5c1fcb0baa579b3685a59e62dee..5ab779bbad321efc0c60ffced4cee853caeefd71 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -223,6 +223,9 @@ PROCESS *the_pipeline = (PROCESS *)NULL;
 /* If this is non-zero, do job control. */
 int job_control = 1;
 
+/* Are we running in background? (terminal_pgrp != shell_pgrp) */
+int running_in_background = 0;
+
 /* Call this when you start making children. */
 int already_making_children = 0;
 
@@ -640,10 +643,11 @@ stop_pipeline (async, deferred)
           * the parent gives it away.
           *
           * Don't give the terminal away if this shell is an asynchronous
-          * subshell.
+          * subshell or if we're a (presumably non-interactive) shell running
+          * in the background.
           *
           */
-         if (job_control && newjob->pgrp && (subshell_environment&SUBSHELL_ASYNC) == 0)
+         if (job_control && newjob->pgrp && (subshell_environment&SUBSHELL_ASYNC) == 0 && running_in_background == 0)
            maybe_give_terminal_to (shell_pgrp, newjob->pgrp, 0);
        }
     }
@@ -1824,7 +1828,7 @@ make_child (command, async_p)
             In this case, we don't want to give the terminal to the
             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))
+         if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&SUBSHELL_ASYNC) == 0) && running_in_background == 0)
            give_terminal_to (pipeline_pgrp, 0);
 
 #if defined (PGRP_PIPE)
@@ -2580,7 +2584,9 @@ itrace("wait_for: blocking wait for %d returns %d child = %p", (int)pid, r, chil
 if (job == NO_JOB)
   itrace("wait_for: job == NO_JOB, giving the terminal to shell_pgrp (%ld)", (long)shell_pgrp);
 #endif
-      give_terminal_to (shell_pgrp, 0);
+      /* Don't modify terminal pgrp if we are running in the background */
+      if (running_in_background == 0)
+       give_terminal_to (shell_pgrp, 0);
     }
 
   /* If the command did not exit cleanly, or the job is just
@@ -3790,6 +3796,7 @@ initialize_job_control (force)
       job_control = 0;
       original_pgrp = NO_PID;
       shell_tty = fileno (stderr);
+      terminal_pgrp = tcgetpgrp (shell_tty);   /* for checking later */
     }
   else
     {
@@ -3890,6 +3897,8 @@ initialize_job_control (force)
        internal_error (_("no job control in this shell"));
     }
 
+  running_in_background = terminal_pgrp != shell_pgrp;
+
   if (shell_tty != fileno (stderr))
     SET_CLOSE_ON_EXEC (shell_tty);
 
@@ -4088,7 +4097,7 @@ maybe_give_terminal_to (opgrp, npgrp, flags)
   else if (tpgrp != opgrp)
     {
 #if defined (DEBUG)
-      internal_warning ("maybe_give_terminal_to: terminal pgrp == %d shell pgrp = %d new pgrp = %d", tpgrp, opgrp, npgrp);
+      internal_warning ("%d: maybe_give_terminal_to: terminal pgrp == %d shell pgrp = %d new pgrp = %d in_background = %d", (int)getpid(), tpgrp, opgrp, npgrp, running_in_background);
 #endif
       return -1;
     }
@@ -4352,6 +4361,21 @@ set_job_control (arg)
   old = job_control;
   job_control = arg;
 
+  if (terminal_pgrp == NO_PID)
+    terminal_pgrp = tcgetpgrp (shell_tty);
+  
+  running_in_background = (terminal_pgrp != shell_pgrp);
+
+#if 0
+  if (interactive_shell == 0 && running_in_background == 0 && job_control != old)
+    {
+      if (job_control)
+       initialize_job_signals ();
+      else
+       default_tty_job_signals ();
+    }
+#endif
+
   /* 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)
index 9ee7147d7e33705ba2cb41dd062c7e7b8285abdc..798260ecdeae03259db3a5eed3ba6294237e5c7b 100644 (file)
@@ -78,13 +78,15 @@ stub_charset ()
   s = strrchr (locale, '.');
   if (s)
     {
-      strcpy (charsetbuf, s+1);
+      strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1);
+      charsetbuf[sizeof (charsetbuf) - 1] = '\0';
       t = strchr (charsetbuf, '@');
       if (t)
        *t = 0;
       return charsetbuf;
     }
-  strcpy (charsetbuf, locale);
+  strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1);
+  charsetbuf[sizeof (charsetbuf) - 1] = '\0';
   return charsetbuf;
 }
 #endif
index 0c9bd751bb80752dfff194812fb1f432fab61bc4..28519c5db5865f0ba1063f6f586e1d0cfe8d0976 100644 (file)
--- a/nojobs.c
+++ b/nojobs.c
@@ -99,6 +99,8 @@ int check_window_size = CHECKWINSIZE_DEFAULT;
 /* We don't have job control. */
 int job_control = 0;
 
+int running_in_background = 0; /* can't tell without job control */
+
 /* STATUS and FLAGS are only valid if pid != NO_PID
    STATUS is only valid if (flags & PROC_RUNNING) == 0 */
 struct proc_status {
index c8605ba6f8528d1b8bf0508534c31840766d2c62..9f74b87bb11b9153ebb430304a1c4b1fb747014d 100644 (file)
@@ -25,6 +25,6 @@
    regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
    looks for to find the patch level (for the sccs version string). */
 
-#define PATCHLEVEL 22
+#define PATCHLEVEL 24
 
 #endif /* _PATCHLEVEL_H_ */
diff --git a/shell.c b/shell.c
index cf929dc5ecc59eb54becb474d0781bf5169f7959..b743d149b588bf0eed972b2bf631c031543b07a9 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -100,6 +100,7 @@ extern char *dist_version, *release_status;
 extern int patch_level, build_version;
 extern int shell_level;
 extern int subshell_environment;
+extern int running_in_background;
 extern int last_command_exit_value;
 extern int line_number;
 extern int expand_aliases;
@@ -1804,7 +1805,8 @@ shell_reinitialize ()
   /* Things that get 0. */
   login_shell = make_login_shell = interactive = executing = 0;
   debugging = do_version = line_number = last_command_exit_value = 0;
-  forced_interactive = interactive_shell = subshell_environment = 0;
+  forced_interactive = interactive_shell = 0;
+  subshell_environment = running_in_background = 0;
   expand_aliases = 0;
 
   /* XXX - should we set jobs_m_flag to 0 here? */