mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-26 23:33:08 +02:00
commit bash-20200417 snapshot
This commit is contained in:
@@ -8009,3 +8009,70 @@ examples/loadables/cut.c
|
||||
- lcut: new builtin that does what cut does but on a string supplied
|
||||
as an argument (only one string for now)
|
||||
|
||||
4/17
|
||||
----
|
||||
jobs.h
|
||||
- FORK_SYNC,FORK_ASYNC,FORK_NOJOB: new flag values for the second
|
||||
argument to make_child
|
||||
|
||||
jobs.c
|
||||
- make_child: now takes a set of flags as the second argument
|
||||
|
||||
execute_cmd.c
|
||||
- make_child: change callers to pass FORK_ASYNC instead of a non-zero
|
||||
value as the second argument
|
||||
|
||||
subst.c
|
||||
- make_child: change callers to pass FORK_ASYNC instead of a non-zero
|
||||
value as the second argument
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- document that the words in a compound array assignment undergo all
|
||||
the shell word expansions, including filename generation and word
|
||||
splitting. From a report from E. Choroba <choroba@matfyz.cz>
|
||||
|
||||
4/18
|
||||
----
|
||||
subst.c
|
||||
- command_substitute: use JOB_CONTROL instead of INTERACTIVE in the
|
||||
test to determine whether or not to give the terminal back to
|
||||
pipeline_pgrp
|
||||
|
||||
jobs.c
|
||||
- make_child: if FORK_NOTERM is set in the flags argument, don't call
|
||||
give_terminal_to
|
||||
|
||||
{jobs,nojobs}.c,jobs.h
|
||||
- wait_for: now takes a second argument, a flags word
|
||||
|
||||
{execute_cmd,subst}.c
|
||||
- wait_for: change all callers to add second argument to wait_for
|
||||
|
||||
jobs.c
|
||||
- wait_for: if JWAIT_NOTERM is set in the flags argument, don't call
|
||||
give_terminal_to
|
||||
|
||||
4/19
|
||||
----
|
||||
subst.c
|
||||
- command_substitute: block SIGINT around call to read_comsub, so we
|
||||
let any interrupts affect the command substitution. Fixes issue
|
||||
reported by DALECKI Léo <leo.dalecki@ntymail.com>
|
||||
|
||||
hashcmd.h
|
||||
- FILENAME_HASH_BUCKETS: increase to 256
|
||||
|
||||
assoc.h
|
||||
- ASSOC_HASH_BUCKETS: new define, set to 1024
|
||||
|
||||
variables.c
|
||||
- make_new_assoc_variable,make_local_assoc_variable: call assoc_create
|
||||
with ASSOC_HASH_BUCKETS as argument. This changes the hash function
|
||||
and how the array keys are ordered (which is not guaranteed)
|
||||
|
||||
builtins/read.def
|
||||
- read_builtin: in posix mode, or if the read call returns -1/EINTR,
|
||||
don't call run_pending_traps until the read command returns. This
|
||||
allows a trap action to see the same exit status that the read
|
||||
builtin would return when it exits on a signal (e.g., SIGINT == 130).
|
||||
From a suggestion by <gentoo_eshoes@tutanota.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* assoc.h -- definitions for the interface exported by assoc.c that allows
|
||||
the rest of the shell to manipulate associative array variables. */
|
||||
|
||||
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "stdc.h"
|
||||
#include "hashlib.h"
|
||||
|
||||
#define ASSOC_HASH_BUCKETS 1024
|
||||
|
||||
#define assoc_empty(h) ((h)->nentries == 0)
|
||||
#define assoc_num_elements(h) ((h)->nentries)
|
||||
|
||||
@@ -34,30 +36,30 @@
|
||||
|
||||
#define assoc_walk(h, f) (hash_walk((h), (f))
|
||||
|
||||
extern void assoc_dispose __P((HASH_TABLE *));
|
||||
extern void assoc_flush __P((HASH_TABLE *));
|
||||
extern void assoc_dispose PARAMS((HASH_TABLE *));
|
||||
extern void assoc_flush PARAMS((HASH_TABLE *));
|
||||
|
||||
extern int assoc_insert __P((HASH_TABLE *, char *, char *));
|
||||
extern PTR_T assoc_replace __P((HASH_TABLE *, char *, char *));
|
||||
extern void assoc_remove __P((HASH_TABLE *, char *));
|
||||
extern int assoc_insert PARAMS((HASH_TABLE *, char *, char *));
|
||||
extern PTR_T assoc_replace PARAMS((HASH_TABLE *, char *, char *));
|
||||
extern void assoc_remove PARAMS((HASH_TABLE *, char *));
|
||||
|
||||
extern char *assoc_reference __P((HASH_TABLE *, char *));
|
||||
extern char *assoc_reference PARAMS((HASH_TABLE *, char *));
|
||||
|
||||
extern char *assoc_subrange __P((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int));
|
||||
extern char *assoc_patsub __P((HASH_TABLE *, char *, char *, int));
|
||||
extern char *assoc_modcase __P((HASH_TABLE *, char *, int, int));
|
||||
extern char *assoc_subrange PARAMS((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int));
|
||||
extern char *assoc_patsub PARAMS((HASH_TABLE *, char *, char *, int));
|
||||
extern char *assoc_modcase PARAMS((HASH_TABLE *, char *, int, int));
|
||||
|
||||
extern HASH_TABLE *assoc_quote __P((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_quote_escapes __P((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_dequote __P((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_dequote_escapes __P((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_remove_quoted_nulls __P((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_quote PARAMS((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_quote_escapes PARAMS((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_dequote PARAMS((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_dequote_escapes PARAMS((HASH_TABLE *));
|
||||
extern HASH_TABLE *assoc_remove_quoted_nulls PARAMS((HASH_TABLE *));
|
||||
|
||||
extern char *assoc_to_kvpair __P((HASH_TABLE *, int));
|
||||
extern char *assoc_to_assign __P((HASH_TABLE *, int));
|
||||
extern char *assoc_to_kvpair PARAMS((HASH_TABLE *, int));
|
||||
extern char *assoc_to_assign PARAMS((HASH_TABLE *, int));
|
||||
|
||||
extern WORD_LIST *assoc_to_word_list __P((HASH_TABLE *));
|
||||
extern WORD_LIST *assoc_keys_to_word_list __P((HASH_TABLE *));
|
||||
extern WORD_LIST *assoc_to_word_list PARAMS((HASH_TABLE *));
|
||||
extern WORD_LIST *assoc_keys_to_word_list PARAMS((HASH_TABLE *));
|
||||
|
||||
extern char *assoc_to_string __P((HASH_TABLE *, char *, int));
|
||||
extern char *assoc_to_string PARAMS((HASH_TABLE *, char *, int));
|
||||
#endif /* _ASSOC_H_ */
|
||||
|
||||
@@ -624,7 +624,9 @@ read_builtin (list)
|
||||
lastsig = LASTSIG();
|
||||
if (lastsig == 0)
|
||||
lastsig = trapped_signal_received;
|
||||
#if 0
|
||||
run_pending_traps (); /* because interrupt_immediately is not set */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
lastsig = 0;
|
||||
|
||||
+6
-2
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Thu Apr 9 11:50:30 EDT 2020
|
||||
.\" Last Change: Fri Apr 17 16:30:01 EDT 2020
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2020 April 9" "GNU Bash 5.0"
|
||||
.TH BASH 1 "2020 April 17" "GNU Bash 5.0"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -2682,6 +2682,10 @@ Arrays are assigned to using compound assignments of the form
|
||||
\fIname\fP=\fB(\fPvalue\fI1\fP ... value\fIn\fP\fB)\fP, where each
|
||||
\fIvalue\fP may be of the form [\fIsubscript\fP]=\fIstring\fP.
|
||||
Indexed array assignments do not require anything but \fIstring\fP.
|
||||
Each \fIvalue\fP in the list is expanded using all the shell expansions
|
||||
described below under
|
||||
.SM
|
||||
.BR EXPANSION .
|
||||
When assigning to indexed arrays, if the optional brackets and subscript
|
||||
are supplied, that index is assigned to;
|
||||
otherwise the index of the element assigned is the last index assigned
|
||||
|
||||
@@ -7312,6 +7312,9 @@ the optional subscript is supplied, that index is assigned to;
|
||||
otherwise the index of the element assigned is the last index assigned
|
||||
to by the statement plus one. Indexing starts at zero.
|
||||
|
||||
Each @var{value} in the list undergoes all the shell expansions
|
||||
described above (@pxref{Shell Expansions}).
|
||||
|
||||
When assigning to an associative array, the words in a compound assignment
|
||||
may be either assignment statements, for which the subscript is required,
|
||||
or a list of words that is interpreted as a sequence of alternating keys
|
||||
|
||||
+2
-2
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Thu Apr 9 11:58:06 EDT 2020
|
||||
@set LASTCHANGE Fri Apr 17 16:30:16 EDT 2020
|
||||
|
||||
@set EDITION 5.0
|
||||
@set VERSION 5.0
|
||||
|
||||
@set UPDATED 9 April 2020
|
||||
@set UPDATED 17 April 2020
|
||||
@set UPDATED-MONTH April 2020
|
||||
|
||||
+20
-16
@@ -556,7 +556,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
int pipe_in, pipe_out;
|
||||
struct fd_bitmap *fds_to_close;
|
||||
{
|
||||
int exec_result, user_subshell, invert, ignore_return, was_error_trap;
|
||||
int exec_result, user_subshell, invert, ignore_return, was_error_trap, fork_flags;
|
||||
REDIRECT *my_undo_list, *exec_undo_list;
|
||||
char *tcmd;
|
||||
volatile int save_line_number;
|
||||
@@ -627,7 +627,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
line_number_for_err_trap = line_number = command->value.Subshell->line; /* XXX - save value? */
|
||||
/* Otherwise we defer setting line_number */
|
||||
tcmd = make_command_string (command);
|
||||
paren_pid = make_child (p = savestring (tcmd), asynchronous);
|
||||
fork_flags = asynchronous ? FORK_ASYNC : 0;
|
||||
paren_pid = make_child (p = savestring (tcmd), fork_flags);
|
||||
|
||||
if (user_subshell && signal_is_trapped (ERROR_TRAP) &&
|
||||
signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
|
||||
@@ -684,7 +685,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
invert = (command->flags & CMD_INVERT_RETURN) != 0;
|
||||
ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
|
||||
|
||||
exec_result = wait_for (paren_pid);
|
||||
exec_result = wait_for (paren_pid, 0);
|
||||
|
||||
/* If we have to, invert the return value. */
|
||||
if (invert)
|
||||
@@ -865,7 +866,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
the function to be waited for twice. This also causes
|
||||
subshells forked to execute builtin commands (e.g., in
|
||||
pipelines) to be waited for twice. */
|
||||
exec_result = wait_for (last_made_pid);
|
||||
exec_result = wait_for (last_made_pid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,10 +1104,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
|
||||
last_command_exit_value = exec_result;
|
||||
run_pending_traps ();
|
||||
#if 0
|
||||
if (running_trap == 0)
|
||||
#endif
|
||||
currently_executing_command = (COMMAND *)NULL;
|
||||
currently_executing_command = (COMMAND *)NULL;
|
||||
|
||||
return (last_command_exit_value);
|
||||
}
|
||||
@@ -2367,7 +2365,7 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
|
||||
|
||||
BLOCK_SIGNAL (SIGCHLD, set, oset);
|
||||
|
||||
coproc_pid = make_child (p = savestring (tcmd), 1);
|
||||
coproc_pid = make_child (p = savestring (tcmd), FORK_ASYNC);
|
||||
|
||||
if (coproc_pid == 0)
|
||||
{
|
||||
@@ -2590,12 +2588,12 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||
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);
|
||||
lstdin = wait_for (lastpid, 0);
|
||||
}
|
||||
else
|
||||
lstdin = wait_for_single_pid (lastpid, 0); /* checks bgpids list */
|
||||
#else
|
||||
lstdin = wait_for (lastpid);
|
||||
lstdin = wait_for (lastpid, 0);
|
||||
#endif
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
@@ -3986,7 +3984,7 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
|
||||
int pipe_in, pipe_out, async;
|
||||
{
|
||||
int r;
|
||||
int forcefork;
|
||||
int forcefork, fork_flags;
|
||||
REDIRECT *rd;
|
||||
|
||||
for (forcefork = 0, rd = redirects; rd; rd = rd->next)
|
||||
@@ -4000,7 +3998,8 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
|
||||
{
|
||||
/* We have a null command, but we really want a subshell to take
|
||||
care of it. Just fork, do piping and redirections, and exit. */
|
||||
if (make_child ((char *)NULL, async) == 0)
|
||||
fork_flags = async ? FORK_ASYNC : 0;
|
||||
if (make_child ((char *)NULL, fork_flags) == 0)
|
||||
{
|
||||
/* Cancel traps, in trap.c. */
|
||||
restore_original_signals (); /* XXX */
|
||||
@@ -4168,6 +4167,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
|
||||
WORD_LIST *words, *lastword;
|
||||
char *command_line, *lastarg, *temp;
|
||||
int first_word_quoted, result, builtin_is_special, already_forked, dofork;
|
||||
int fork_flags;
|
||||
pid_t old_last_async_pid;
|
||||
sh_builtin_func_t *builtin;
|
||||
SHELL_VAR *func;
|
||||
@@ -4244,7 +4244,8 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
|
||||
|
||||
/* Don't let a DEBUG trap overwrite the command string to be saved with
|
||||
the process/job associated with this child. */
|
||||
if (make_child (p = savestring (the_printed_command_except_trap), async) == 0)
|
||||
fork_flags = async ? FORK_ASYNC : 0;
|
||||
if (make_child (p = savestring (the_printed_command_except_trap), fork_flags) == 0)
|
||||
{
|
||||
already_forked = 1;
|
||||
simple_command->flags |= CMD_NO_FORK;
|
||||
@@ -5331,7 +5332,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
|
||||
int cmdflags;
|
||||
{
|
||||
char *pathname, *command, **args, *p;
|
||||
int nofork, stdpath, result;
|
||||
int nofork, stdpath, result, fork_flags;
|
||||
pid_t pid;
|
||||
SHELL_VAR *hookf;
|
||||
WORD_LIST *wl;
|
||||
@@ -5380,7 +5381,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
|
||||
if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
|
||||
pid = 0;
|
||||
else
|
||||
pid = make_child (p = savestring (command_line), async);
|
||||
{
|
||||
fork_flags = async ? FORK_ASYNC : 0;
|
||||
pid = make_child (p = savestring (command_line), fork_flags);
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* hashcmd.h - Common defines for hashing filenames. */
|
||||
|
||||
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "stdc.h"
|
||||
#include "hashlib.h"
|
||||
|
||||
#define FILENAME_HASH_BUCKETS 64 /* must be power of two */
|
||||
#define FILENAME_HASH_BUCKETS 256 /* must be power of two */
|
||||
|
||||
extern HASH_TABLE *hashed_filenames;
|
||||
|
||||
@@ -35,9 +35,9 @@ typedef struct _pathdata {
|
||||
|
||||
#define pathdata(x) ((PATH_DATA *)(x)->data)
|
||||
|
||||
extern void phash_create __P((void));
|
||||
extern void phash_flush __P((void));
|
||||
extern void phash_create PARAMS((void));
|
||||
extern void phash_flush PARAMS((void));
|
||||
|
||||
extern void phash_insert __P((char *, char *, int, int));
|
||||
extern int phash_remove __P((const char *));
|
||||
extern char *phash_search __P((const char *));
|
||||
extern void phash_insert PARAMS((char *, char *, int, int));
|
||||
extern int phash_remove PARAMS((const char *));
|
||||
extern char *phash_search PARAMS((const char *));
|
||||
|
||||
@@ -1079,7 +1079,7 @@ procsub_waitpid (pid)
|
||||
return -1;
|
||||
if (p->running == PS_DONE)
|
||||
return (p->status);
|
||||
r = wait_for (p->pid);
|
||||
r = wait_for (p->pid, 0);
|
||||
return (r); /* defer removing until later */
|
||||
}
|
||||
|
||||
@@ -1093,7 +1093,7 @@ procsub_waitall ()
|
||||
{
|
||||
if (p->running == PS_DONE)
|
||||
continue;
|
||||
r = wait_for (p->pid);
|
||||
r = wait_for (p->pid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2252,7 +2252,7 @@ make_child (command, flags)
|
||||
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|SUBSHELL_PIPE)) == 0) && running_in_background == 0)
|
||||
if ((flags & FORK_NOTERM) == 0 && async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&(SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0) && running_in_background == 0)
|
||||
give_terminal_to (pipeline_pgrp, 0);
|
||||
|
||||
#if defined (PGRP_PIPE)
|
||||
@@ -2609,7 +2609,7 @@ wait_for_single_pid (pid, flags)
|
||||
alive = 0;
|
||||
do
|
||||
{
|
||||
r = wait_for (pid);
|
||||
r = wait_for (pid, 0);
|
||||
if ((flags & JWAIT_FORCE) == 0)
|
||||
break;
|
||||
|
||||
@@ -2899,8 +2899,9 @@ job_exit_signal (job)
|
||||
the jobs table. Returns -1 if waitchld() returns -1, indicating
|
||||
that there are no unwaited-for child processes. */
|
||||
int
|
||||
wait_for (pid)
|
||||
wait_for (pid, flags)
|
||||
pid_t pid;
|
||||
int flags;
|
||||
{
|
||||
int job, termination_state, r;
|
||||
WAIT s;
|
||||
@@ -3235,7 +3236,7 @@ wait_for_job (job, flags, ps)
|
||||
|
||||
do
|
||||
{
|
||||
r = wait_for (pid);
|
||||
r = wait_for (pid, 0);
|
||||
if (r == -1 && errno == ECHILD)
|
||||
mark_all_jobs_as_dead ();
|
||||
|
||||
@@ -3331,7 +3332,7 @@ return_job:
|
||||
CHECK_WAIT_INTR;
|
||||
|
||||
errno = 0;
|
||||
r = wait_for (ANY_PID); /* special sentinel value for wait_for */
|
||||
r = wait_for (ANY_PID, 0); /* special sentinel value for wait_for */
|
||||
if (r == -1 && errno == ECHILD)
|
||||
mark_all_jobs_as_dead ();
|
||||
|
||||
@@ -3642,7 +3643,7 @@ start_job (job, foreground)
|
||||
|
||||
pid = find_last_pid (job, 0);
|
||||
UNBLOCK_CHILD (oset);
|
||||
st = wait_for (pid);
|
||||
st = wait_for (pid, 0);
|
||||
shell_tty_info = save_stty;
|
||||
set_tty_state ();
|
||||
return (st);
|
||||
|
||||
@@ -38,11 +38,14 @@
|
||||
/* I looked it up. For pretty_print_job (). The real answer is 24. */
|
||||
#define LONGEST_SIGNAL_DESC 24
|
||||
|
||||
/* Defines for the wait_for functions and for the wait builtin to use */
|
||||
#define JWAIT_PERROR 0x01
|
||||
#define JWAIT_FORCE 0x02
|
||||
#define JWAIT_NOWAIT 0x04 /* don't waitpid(), just return status if already exited */
|
||||
#define JWAIT_WAITING 0x08 /* wait for jobs marked J_WAITING only */
|
||||
/* Defines for the wait_for_* functions and for the wait builtin to use */
|
||||
#define JWAIT_PERROR (1 << 0)
|
||||
#define JWAIT_FORCE (1 << 1)
|
||||
#define JWAIT_NOWAIT (1 << 2) /* don't waitpid(), just return status if already exited */
|
||||
#define JWAIT_WAITING (1 << 3) /* wait for jobs marked J_WAITING only */
|
||||
|
||||
/* flags for wait_for */
|
||||
#define JWAIT_NOTERM (1 << 8) /* wait_for doesn't give terminal away */
|
||||
|
||||
/* The max time to sleep while retrying fork() on EAGAIN failure */
|
||||
#define FORKSLEEP_MAX 16
|
||||
@@ -197,9 +200,10 @@ struct procchain {
|
||||
#define ANY_PID (pid_t)-1
|
||||
|
||||
/* flags for make_child () */
|
||||
#define FORK_SYNC 0
|
||||
#define FORK_ASYNC 1
|
||||
#define FORK_NOJOB 2
|
||||
#define FORK_SYNC 0 /* normal synchronous process */
|
||||
#define FORK_ASYNC 1 /* background process */
|
||||
#define FORK_NOJOB 2 /* don't put process in separate pgrp */
|
||||
#define FORK_NOTERM 4 /* don't give terminal to any pgrp */
|
||||
|
||||
/* System calls. */
|
||||
#if !defined (HAVE_UNISTD_H)
|
||||
@@ -276,7 +280,7 @@ extern int job_exit_signal PARAMS((int));
|
||||
|
||||
extern int wait_for_single_pid PARAMS((pid_t, int));
|
||||
extern void wait_for_background_pids PARAMS((struct procstat *));
|
||||
extern int wait_for PARAMS((pid_t));
|
||||
extern int wait_for PARAMS((pid_t, int));
|
||||
extern int wait_for_job PARAMS((int, int, struct procstat *));
|
||||
extern int wait_for_any_job PARAMS((int, struct procstat *));
|
||||
|
||||
|
||||
@@ -823,8 +823,9 @@ j_strsignal (s)
|
||||
/* Wait for pid (one of our children) to terminate. This is called only
|
||||
by the execution code in execute_cmd.c. */
|
||||
int
|
||||
wait_for (pid)
|
||||
wait_for (pid, flags)
|
||||
pid_t pid;
|
||||
int flags;
|
||||
{
|
||||
int return_val, pstatus;
|
||||
pid_t got_pid;
|
||||
|
||||
@@ -5555,7 +5555,7 @@ wait_procsubs ()
|
||||
{
|
||||
if (fifo_list[i].proc != (pid_t)-1 && fifo_list[i].proc > 0)
|
||||
{
|
||||
r = wait_for (fifo_list[i].proc);
|
||||
r = wait_for (fifo_list[i].proc, 0);
|
||||
save_proc_status (fifo_list[i].proc, r);
|
||||
fifo_list[i].proc = (pid_t)-1;
|
||||
}
|
||||
@@ -5793,7 +5793,7 @@ wait_procsubs ()
|
||||
{
|
||||
if (dev_fd_list[i] != (pid_t)-1 && dev_fd_list[i] > 0)
|
||||
{
|
||||
r = wait_for (dev_fd_list[i]);
|
||||
r = wait_for (dev_fd_list[i], 0);
|
||||
save_proc_status (dev_fd_list[i], r);
|
||||
dev_fd_list[i] = (pid_t)-1;
|
||||
}
|
||||
@@ -5901,7 +5901,7 @@ process_substitute (string, open_for_read_in_child)
|
||||
save_pipeline (1);
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
pid = make_child ((char *)NULL, 1);
|
||||
pid = make_child ((char *)NULL, FORK_ASYNC);
|
||||
if (pid == 0)
|
||||
{
|
||||
interactive = 0;
|
||||
@@ -6141,8 +6141,7 @@ read_comsub (fd, quoted, flags, rflag)
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
nullbyte = 0;
|
||||
|
||||
/* Read the output of the command through the pipe. This may need to be
|
||||
changed to understand multibyte characters in the future. */
|
||||
/* Read the output of the command through the pipe. */
|
||||
while (1)
|
||||
{
|
||||
if (fd < 0)
|
||||
@@ -6206,16 +6205,6 @@ read_comsub (fd, quoted, flags, rflag)
|
||||
#endif
|
||||
|
||||
istring[istring_index++] = c;
|
||||
|
||||
#if 0
|
||||
#if defined (__CYGWIN__)
|
||||
if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
|
||||
{
|
||||
istring_index--;
|
||||
istring[istring_index - 1] = '\n';
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (istring)
|
||||
@@ -6267,8 +6256,9 @@ command_substitute (string, quoted, flags)
|
||||
{
|
||||
pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
|
||||
char *istring, *s;
|
||||
int result, fildes[2], function_value, pflags, rc, tflag;
|
||||
int result, fildes[2], function_value, pflags, rc, tflag, fork_flags;
|
||||
WORD_DESC *ret;
|
||||
sigset_t set, oset;
|
||||
|
||||
istring = (char *)NULL;
|
||||
|
||||
@@ -6323,7 +6313,8 @@ command_substitute (string, quoted, flags)
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
old_async_pid = last_asynchronous_pid;
|
||||
pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
|
||||
fork_flags = (subshell_environment&SUBSHELL_ASYNC) ? FORK_ASYNC : 0;
|
||||
pid = make_child ((char *)NULL, fork_flags);
|
||||
last_asynchronous_pid = old_async_pid;
|
||||
|
||||
if (pid == 0)
|
||||
@@ -6486,14 +6477,19 @@ command_substitute (string, quoted, flags)
|
||||
dummyfd = fildes[0];
|
||||
add_unwind_protect (close, dummyfd);
|
||||
|
||||
/* Block SIGINT while we're reading from the pipe. If the child
|
||||
process gets a SIGINT, it will either handle it or die, and the
|
||||
read will return. */
|
||||
BLOCK_SIGNAL (SIGINT, set, oset);
|
||||
tflag = 0;
|
||||
istring = read_comsub (fildes[0], quoted, flags, &tflag);
|
||||
|
||||
close (fildes[0]);
|
||||
discard_unwind_frame ("read-comsub");
|
||||
UNBLOCK_SIGNAL (oset);
|
||||
|
||||
current_command_subst_pid = pid;
|
||||
last_command_exit_value = wait_for (pid);
|
||||
last_command_exit_value = wait_for (pid, 0);
|
||||
last_command_subst_pid = pid;
|
||||
last_made_pid = old_pid;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
16
|
||||
./appendop.tests: line 97: x: readonly variable
|
||||
declare -A foo=([two]="baz" [three]="quux" [one]="bar" )
|
||||
declare -A foo=([two]="baz" [0]="zero" [three]="quux" [one]="bar" )
|
||||
declare -A foo=([two]="baz" [0]="zero" [three]="quux" [four]="four" [one]="bar" )
|
||||
declare -A foo=([0]="zero" [two]="baz" [three]="quux" [one]="bar" )
|
||||
declare -A foo=([four]="four" [0]="zero" [two]="baz" [three]="quux" [one]="bar" )
|
||||
declare -ai iarr=([0]="3" [1]="2" [2]="3")
|
||||
declare -ai iarr=([0]="3" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")
|
||||
25 25
|
||||
|
||||
+4
-4
@@ -349,10 +349,10 @@ version[agent]
|
||||
version.agent
|
||||
version[agent]
|
||||
version.agent
|
||||
version[agent] foo[bar]
|
||||
version.agent bowl
|
||||
foo foobar] foo[bar]
|
||||
bbb bleh bleh
|
||||
foo[bar] version[agent]
|
||||
bowl version.agent
|
||||
foobar] foo foo[bar]
|
||||
bleh bbb bleh
|
||||
ab]
|
||||
bar
|
||||
1
|
||||
|
||||
+36
-36
@@ -6,14 +6,14 @@ declare -A BASH_CMDS=()
|
||||
declare -A fluff=([foo]="one" [bar]="two" )
|
||||
declare -A fluff=([foo]="one" [bar]="two" )
|
||||
declare -A fluff=([bar]="two" )
|
||||
declare -A fluff=([bar]="newval" [qux]="assigned" )
|
||||
declare -A fluff=([qux]="assigned" [bar]="newval" )
|
||||
./assoc.tests: line 39: chaff: four: must use subscript when assigning associative array
|
||||
declare -A BASH_ALIASES=()
|
||||
declare -A BASH_CMDS=()
|
||||
declare -Ai chaff=([zero]="5" [one]="10" )
|
||||
declare -Ar waste=([lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" [pid]="42134" )
|
||||
declare -A wheat=([two]="b" [three]="c" [zero]="0" [one]="a" )
|
||||
declare -A chaff=(["hello world"]="flip" [zero]="5" [one]="10" )
|
||||
declare -Ai chaff=([one]="10" [zero]="5" )
|
||||
declare -Ar waste=([pid]="42134" [lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" )
|
||||
declare -A wheat=([two]="b" [three]="c" [one]="a" [zero]="0" )
|
||||
declare -A chaff=(["hello world"]="flip" [one]="10" [zero]="5" )
|
||||
./assoc.tests: line 51: waste: readonly variable
|
||||
./assoc.tests: line 52: unset: waste: cannot unset: readonly variable
|
||||
./assoc.tests: line 53: chaff[*]: bad array subscript
|
||||
@@ -35,11 +35,11 @@ argv[1] = <multiple words flip a>
|
||||
./assoc.tests: line 71: declare: chaff: cannot destroy array variables in this way
|
||||
./assoc.tests: line 73: chaff[*]: bad array subscript
|
||||
./assoc.tests: line 74: [*]=12: invalid associative array key
|
||||
declare -A wheat=(["foo bar"]="qux qix" [six]="6" )
|
||||
declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
|
||||
argv[1] = <qux>
|
||||
argv[2] = <qix>
|
||||
argv[1] = <qux qix>
|
||||
declare -A wheat=(["foo bar"]="qux qix" [six]="6" )
|
||||
declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
|
||||
argv[1] = <2>
|
||||
argv[1] = <7>
|
||||
argv[1] = <qux>
|
||||
@@ -48,16 +48,16 @@ argv[3] = <blat>
|
||||
argv[1] = <qux qix blat>
|
||||
argv[1] = <16>
|
||||
argv[1] = <16>
|
||||
argv[1] = <flix>
|
||||
argv[2] = <6>
|
||||
argv[1] = <foo>
|
||||
argv[2] = <bar>
|
||||
argv[3] = <six>
|
||||
argv[1] = <foo bar>
|
||||
argv[2] = <six>
|
||||
argv[1] = <6>
|
||||
argv[2] = <flix>
|
||||
argv[1] = <six>
|
||||
argv[2] = <foo>
|
||||
argv[3] = <bar>
|
||||
argv[1] = <six>
|
||||
argv[2] = <foo bar>
|
||||
8
|
||||
/sbin /usr/bin /bin /usr/ucb /usr/local/bin . /usr/sbin /bin
|
||||
sbin bin bin ucb bin . sbin bin
|
||||
/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
|
||||
bin bin . bin ucb sbin bin sbin
|
||||
bin
|
||||
/ / / / / / /
|
||||
/
|
||||
@@ -66,27 +66,27 @@ argv[1] = </>
|
||||
argv[1] = <sbin>
|
||||
argv[1] = </>
|
||||
8
|
||||
/sbin /usr/bin /bin /usr/ucb /usr/local/bin . /usr/sbin /bin
|
||||
sbin bin bin ucb bin . sbin bin
|
||||
/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
|
||||
bin bin . bin ucb sbin bin sbin
|
||||
/ / / / / / /
|
||||
8
|
||||
4 -- /bin
|
||||
^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin . ^usr^sbin ^bin
|
||||
^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin . ^usr^sbin ^bin
|
||||
\sbin \usr/bin \bin \usr/ucb \usr/local/bin . \usr/sbin \bin
|
||||
\sbin \usr\bin \bin \usr\ucb \usr\local\bin . \usr\sbin \bin
|
||||
\sbin \usr\bin \bin \usr\ucb \usr\local\bin . \usr\sbin \bin
|
||||
^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
|
||||
^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
|
||||
\usr/local/bin \bin . \usr/bin \usr/ucb \usr/sbin \bin \sbin
|
||||
\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
|
||||
\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
|
||||
([a]=1)
|
||||
|
||||
foo qux
|
||||
/usr/sbin/foo /usr/local/bin/qux
|
||||
hits command
|
||||
0 /sbin/blat
|
||||
0 /usr/sbin/foo
|
||||
0 /bin/sh
|
||||
0 /sbin/blat
|
||||
0 /usr/local/bin/qux
|
||||
blat foo sh qux
|
||||
/sbin/blat /usr/sbin/foo /bin/sh /usr/local/bin/qux
|
||||
foo sh blat qux
|
||||
/usr/sbin/foo /bin/sh /sbin/blat /usr/local/bin/qux
|
||||
|
||||
foo qux
|
||||
argv[1] = </usr/sbin/foo>
|
||||
@@ -104,10 +104,10 @@ argv[4] = </usr/local/bin/qux -l>
|
||||
outside: outside
|
||||
declare -A BASH_ALIASES=()
|
||||
declare -A BASH_CMDS=()
|
||||
declare -A afoo=(["foo bar"]="foo quux" [six]="six" )
|
||||
declare -A afoo=([six]="six" ["foo bar"]="foo quux" )
|
||||
argv[1] = <inside:>
|
||||
argv[2] = <foo quux>
|
||||
argv[3] = <six>
|
||||
argv[2] = <six>
|
||||
argv[3] = <foo quux>
|
||||
outside 2: outside
|
||||
argv[1] = </barq//fooq>
|
||||
argv[1] = <>
|
||||
@@ -138,11 +138,11 @@ abc
|
||||
def
|
||||
def
|
||||
./assoc5.sub: line 26: declare: `myarray[foo[bar]=bleh': not a valid identifier
|
||||
bleh def abc
|
||||
myarray=([foo]="bleh" ["]"]="def" ["a]=test1;#a"]="123" ["a]a"]="abc" )
|
||||
def bleh abc
|
||||
myarray=(["]"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
|
||||
|
||||
123
|
||||
myarray=([foo]="bleh" ["]"]="def" ["a]=test2;#a"]="def" ["a]=test1;#a"]="123" ["a]a"]="abc" )
|
||||
myarray=(["]"]="def" ["a]=test2;#a"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
|
||||
bar"bie
|
||||
doll
|
||||
declare -A foo=(["bar\"bie"]="doll" )
|
||||
@@ -234,11 +234,11 @@ main: declare -- a="42"
|
||||
declare -A a=([3]="" [1]="2" )
|
||||
declare -A foo=([d]="4" [c]="3" [b]="2" [a]="1" )
|
||||
foo=( d "4" c "3" b "2" a "1" )
|
||||
declare -A foo=(["spa ces"]="2" ["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" )
|
||||
foo=( echo "spa ces" "2" "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" )
|
||||
declare -A foo=(["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" ["spa ces"]="2" )
|
||||
foo=( echo "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" "spa ces" "2" )
|
||||
./assoc11.sub: line 34: "": bad array subscript
|
||||
declare -A foo=(["foo[bar"]="bleh" [";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" )
|
||||
foo=( "foo[bar" "bleh" ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" )
|
||||
declare -A foo=([";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" ["foo[bar"]="bleh" )
|
||||
foo=( ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" "foo[bar" "bleh" )
|
||||
declare -A foo=(["'"]="squote" ["\""]="dquote" ["\\"]="bslash" ["\`"]="backquote" )
|
||||
foo=( "'" "squote" "\"" "dquote" "\\" "bslash" "\`" "backquote" )
|
||||
declare -A foo=(["bar]bie"]="doll" ["a]=test1;#a"]="123" ["bar\"bie"]="doll" )
|
||||
|
||||
+1
-1
@@ -635,7 +635,7 @@ declare -r x='ab '\''cd'\'' ef'
|
||||
set -- 'ab' 'cd ef' '' 'gh'
|
||||
declare -a A=([0]="ab" [1]="cd ef" [2]="" [3]="gh")
|
||||
declare -a B=()
|
||||
declare -A A=([two]="b c" [three]="" [four]="de" [one]="1" )
|
||||
declare -A A=([four]="de" [two]="b c" [three]="" [one]="1" )
|
||||
r
|
||||
a
|
||||
A
|
||||
|
||||
+1
-1
@@ -44,8 +44,8 @@ builtin is a shell builtin
|
||||
bash is hashed (/tmp/bash)
|
||||
file
|
||||
hits command
|
||||
3 /tmp/bash
|
||||
1 /bin/sh
|
||||
3 /tmp/bash
|
||||
f is a function
|
||||
f ()
|
||||
{
|
||||
|
||||
+1
-1
@@ -133,7 +133,7 @@ after func: x = outside
|
||||
./varenv11.sub: line 18: qux: readonly variable
|
||||
declare -A foo=([zero]="zero" [one]="one" )
|
||||
declare -a bar=([0]="zero" [1]="one")
|
||||
declare -A foo=([zero]="zero" [one]="one" )
|
||||
declare -A foo=([one]="one" [zero]="zero" )
|
||||
declare -a bar=([0]="zero" [1]="one")
|
||||
./varenv11.sub: line 42: a: readonly variable
|
||||
foo=abc
|
||||
|
||||
+3
-3
@@ -3015,7 +3015,7 @@ make_new_assoc_variable (name)
|
||||
HASH_TABLE *hash;
|
||||
|
||||
entry = make_new_variable (name, global_variables->table);
|
||||
hash = assoc_create (0);
|
||||
hash = assoc_create (ASSOC_HASH_BUCKETS);
|
||||
|
||||
var_setassoc (entry, hash);
|
||||
VSETATTR (entry, att_assoc);
|
||||
@@ -3047,7 +3047,7 @@ make_local_assoc_variable (name, flags)
|
||||
internal_warning ("%s: cannot inherit value from incompatible type", name);
|
||||
VUNSETATTR (var, att_array);
|
||||
dispose_variable_value (var);
|
||||
hash = assoc_create (0);
|
||||
hash = assoc_create (ASSOC_HASH_BUCKETS);
|
||||
var_setassoc (var, hash);
|
||||
}
|
||||
else if (localvar_inherit)
|
||||
@@ -3055,7 +3055,7 @@ make_local_assoc_variable (name, flags)
|
||||
else
|
||||
{
|
||||
dispose_variable_value (var);
|
||||
hash = assoc_create (0);
|
||||
hash = assoc_create (ASSOC_HASH_BUCKETS);
|
||||
var_setassoc (var, hash);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user