Imported from ../bash-4.0.tar.gz.
This commit is contained in:
parent
3185942a52
commit
17345e5ad2
134 changed files with 74214 additions and 4584 deletions
109
execute_cmd.c
109
execute_cmd.c
|
|
@ -513,7 +513,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
|||
int pipe_in, pipe_out;
|
||||
struct fd_bitmap *fds_to_close;
|
||||
{
|
||||
int exec_result, invert, ignore_return, was_error_trap;
|
||||
int exec_result, user_subshell, invert, ignore_return, was_error_trap;
|
||||
REDIRECT *my_undo_list, *exec_undo_list;
|
||||
volatile int last_pid;
|
||||
volatile int save_line_number;
|
||||
|
|
@ -557,6 +557,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
|||
return (execute_coproc (command, pipe_in, pipe_out, fds_to_close));
|
||||
#endif
|
||||
|
||||
user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0);
|
||||
|
||||
if (command->type == cm_subshell ||
|
||||
(command->flags & (CMD_WANT_SUBSHELL|CMD_FORCE_SUBSHELL)) ||
|
||||
(shell_control_structure (command->type) &&
|
||||
|
|
@ -590,6 +592,10 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
|||
|
||||
if (asynchronous == 0)
|
||||
{
|
||||
was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
|
||||
invert = (command->flags & CMD_INVERT_RETURN) != 0;
|
||||
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
|
||||
|
||||
last_command_exit_value = wait_for (paren_pid);
|
||||
|
||||
/* If we have to, invert the return value. */
|
||||
|
|
@ -600,6 +606,20 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
|||
else
|
||||
exec_result = last_command_exit_value;
|
||||
|
||||
|
||||
if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
|
||||
{
|
||||
last_command_exit_value = exec_result;
|
||||
run_error_trap ();
|
||||
}
|
||||
|
||||
if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
|
||||
{
|
||||
last_command_exit_value = exec_result;
|
||||
run_pending_traps ();
|
||||
jump_to_top_level (ERREXIT);
|
||||
}
|
||||
|
||||
return (last_command_exit_value = exec_result);
|
||||
}
|
||||
else
|
||||
|
|
@ -741,10 +761,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
|||
}
|
||||
}
|
||||
|
||||
/* 10/6/2008 -- added test for pipe_in and pipe_out because they indicate
|
||||
the presence of a pipeline, and (until Posix changes things), a
|
||||
pipeline failure should not cause the parent shell to exit on an
|
||||
unsuccessful return status, even in the presence of errexit.. */
|
||||
/* 2009/02/13 -- pipeline failure is processed elsewhere. This handles
|
||||
only the failure of a simple command. */
|
||||
if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
|
||||
{
|
||||
last_command_exit_value = exec_result;
|
||||
|
|
@ -1056,8 +1074,11 @@ print_formatted_time (fp, format, rs, rsf, us, usf, ss, ssf, cpu)
|
|||
else if (s[1] == 'P')
|
||||
{
|
||||
s++;
|
||||
#if 0
|
||||
/* clamp CPU usage at 100% */
|
||||
if (cpu > 10000)
|
||||
cpu = 10000;
|
||||
#endif
|
||||
sum = cpu / 100;
|
||||
sum_frac = (cpu % 100) * 10;
|
||||
len = mkfmt (ts, 2, 0, sum, sum_frac);
|
||||
|
|
@ -1438,6 +1459,7 @@ static struct cpelement *cpe_alloc __P((struct coproc *));
|
|||
static void cpe_dispose __P((struct cpelement *));
|
||||
static struct cpelement *cpl_add __P((struct coproc *));
|
||||
static struct cpelement *cpl_delete __P((pid_t));
|
||||
static void cpl_reap __P((void));
|
||||
static void cpl_flush __P((void));
|
||||
static struct cpelement *cpl_search __P((pid_t));
|
||||
static struct cpelement *cpl_searchbyname __P((char *));
|
||||
|
|
@ -1447,8 +1469,7 @@ Coproc sh_coproc = { 0, NO_PID, -1, -1, 0, 0 };
|
|||
|
||||
cplist_t coproc_list = {0, 0, 0};
|
||||
|
||||
/* Functions to manage the list of exited background pids whose status has
|
||||
been saved. */
|
||||
/* Functions to manage the list of coprocs */
|
||||
|
||||
static struct cpelement *
|
||||
cpe_alloc (cp)
|
||||
|
|
@ -1527,6 +1548,37 @@ cpl_delete (pid)
|
|||
return (p);
|
||||
}
|
||||
|
||||
static void
|
||||
cpl_reap ()
|
||||
{
|
||||
struct cpelement *prev, *p;
|
||||
|
||||
for (prev = p = coproc_list.head; p; prev = p, p = p->next)
|
||||
if (p->coproc->c_flags & COPROC_DEAD)
|
||||
{
|
||||
prev->next = p->next; /* remove from list */
|
||||
|
||||
/* Housekeeping in the border cases. */
|
||||
if (p == coproc_list.head)
|
||||
coproc_list.head = coproc_list.head->next;
|
||||
else if (p == coproc_list.tail)
|
||||
coproc_list.tail = prev;
|
||||
|
||||
coproc_list.ncoproc--;
|
||||
if (coproc_list.ncoproc == 0)
|
||||
coproc_list.head = coproc_list.tail = 0;
|
||||
else if (coproc_list.ncoproc == 1)
|
||||
coproc_list.tail = coproc_list.head; /* just to make sure */
|
||||
|
||||
#if defined (DEBUG)
|
||||
itrace("cpl_reap: deleting %d", p->coproc->c_pid);
|
||||
#endif
|
||||
|
||||
coproc_dispose (p->coproc);
|
||||
cpe_dispose (p);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear out the list of saved statuses */
|
||||
static void
|
||||
cpl_flush ()
|
||||
|
|
@ -1679,6 +1731,16 @@ coproc_closeall ()
|
|||
coproc_close (&sh_coproc);
|
||||
}
|
||||
|
||||
void
|
||||
coproc_reap ()
|
||||
{
|
||||
struct coproc *cp;
|
||||
|
||||
cp = &sh_coproc;
|
||||
if (cp && (cp->c_flags & COPROC_DEAD))
|
||||
coproc_dispose (cp);
|
||||
}
|
||||
|
||||
void
|
||||
coproc_rclose (cp, fd)
|
||||
struct coproc *cp;
|
||||
|
|
@ -1751,9 +1813,9 @@ coproc_fdrestore (cp)
|
|||
cp->c_rfd = cp->c_rsave;
|
||||
cp->c_wfd = cp->c_wsave;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
coproc_pidchk (pid)
|
||||
coproc_pidchk (pid, status)
|
||||
pid_t pid;
|
||||
{
|
||||
struct coproc *cp;
|
||||
|
|
@ -1764,7 +1826,14 @@ coproc_pidchk (pid)
|
|||
itrace("coproc_pidchk: pid %d has died", pid);
|
||||
#endif
|
||||
if (cp)
|
||||
coproc_dispose (cp);
|
||||
{
|
||||
cp->c_status = status;
|
||||
cp->c_flags |= COPROC_DEAD;
|
||||
cp->c_flags &= ~COPROC_RUNNING;
|
||||
#if 0
|
||||
coproc_dispose (cp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2035,7 +2104,7 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
|||
{
|
||||
REDIRECT *rp;
|
||||
COMMAND *tc, *second;
|
||||
int ignore_return, exec_result;
|
||||
int ignore_return, exec_result, was_error_trap, invert;
|
||||
|
||||
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
|
||||
|
||||
|
|
@ -2101,7 +2170,25 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
|||
break;
|
||||
|
||||
case '|':
|
||||
was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
|
||||
invert = (command->flags & CMD_INVERT_RETURN) != 0;
|
||||
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
|
||||
|
||||
exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
|
||||
|
||||
if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
|
||||
{
|
||||
last_command_exit_value = exec_result;
|
||||
run_error_trap ();
|
||||
}
|
||||
|
||||
if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
|
||||
{
|
||||
last_command_exit_value = exec_result;
|
||||
run_pending_traps ();
|
||||
jump_to_top_level (ERREXIT);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AND_AND:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue