commit bash-20140815 snapshot

This commit is contained in:
Chet Ramey
2014-08-29 09:15:21 -04:00
parent e7fd1ab607
commit 581fe5894c
7 changed files with 89 additions and 14 deletions
+37
View 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
+13 -5
View 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))
{
+29 -5
View File
@@ -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)
+4 -2
View 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
+2
View File
@@ -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 {
+1 -1
View 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_ */
+3 -1
View File
@@ -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? */