summaryrefslogtreecommitdiff
path: root/builtins
diff options
context:
space:
mode:
Diffstat (limited to 'builtins')
-rw-r--r--builtins/Makefile.in7
-rw-r--r--builtins/alias.def4
-rw-r--r--builtins/bashgetopt.h6
-rw-r--r--builtins/bind.def44
-rw-r--r--builtins/break.def4
-rw-r--r--builtins/caller.def6
-rw-r--r--builtins/cd.def15
-rw-r--r--builtins/colon.def15
-rw-r--r--builtins/command.def8
-rw-r--r--builtins/common.c113
-rw-r--r--builtins/common.h193
-rw-r--r--builtins/complete.def253
-rw-r--r--builtins/declare.def66
-rw-r--r--builtins/enable.def21
-rw-r--r--builtins/evalfile.c2
-rw-r--r--builtins/evalstring.c41
-rw-r--r--builtins/exec.def11
-rw-r--r--builtins/exit.def4
-rw-r--r--builtins/fc.def134
-rw-r--r--builtins/fg_bg.def4
-rw-r--r--builtins/gen-helpfiles.c6
-rw-r--r--builtins/getopt.h14
-rw-r--r--builtins/getopts.def19
-rw-r--r--builtins/hash.def19
-rw-r--r--builtins/help.def16
-rw-r--r--builtins/history.def21
-rw-r--r--builtins/jobs.def6
-rw-r--r--builtins/kill.def4
-rw-r--r--builtins/mapfile.def4
-rw-r--r--builtins/mkbuiltins.c22
-rw-r--r--builtins/printf.def66
-rw-r--r--builtins/pushd.def14
-rw-r--r--builtins/read.def72
-rw-r--r--builtins/reserved.def4
-rw-r--r--builtins/return.def2
-rw-r--r--builtins/set.def64
-rw-r--r--builtins/setattr.def54
-rw-r--r--builtins/shift.def32
-rw-r--r--builtins/shopt.def44
-rw-r--r--builtins/source.def6
-rw-r--r--builtins/suspend.def4
-rw-r--r--builtins/trap.def31
-rw-r--r--builtins/type.def4
-rw-r--r--builtins/ulimit.def32
-rw-r--r--builtins/umask.def6
-rw-r--r--builtins/wait.def162
46 files changed, 1061 insertions, 618 deletions
diff --git a/builtins/Makefile.in b/builtins/Makefile.in
index 388ca4eb..3f44f05e 100644
--- a/builtins/Makefile.in
+++ b/builtins/Makefile.in
@@ -410,6 +410,12 @@ cd.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
cd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
cd.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ../pathnames.h
cd.o: $(topdir)/sig.h
+colon.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
+colon.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
+colon.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/sig.h
+colon.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
+colon.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
+colon.o: $(srcdir)/common.h
command.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
command.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
command.o: $(topdir)/quit.h $(srcdir)/bashgetopt.h $(BASHINCDIR)/maxpath.h
@@ -429,6 +435,7 @@ echo.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/exte
echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/sig.h
echo.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
echo.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
+echo.o: $(srcdir)/common.h
enable.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
enable.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
enable.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
diff --git a/builtins/alias.def b/builtins/alias.def
index bf484f33..0ab90696 100644
--- a/builtins/alias.def
+++ b/builtins/alias.def
@@ -1,7 +1,7 @@
This file is alias.def, from which is created alias.c
It implements the builtins "alias" and "unalias" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -63,7 +63,7 @@ $END
/* Flags for print_alias */
#define AL_REUSABLE 0x01
-static void print_alias __P((alias_t *, int));
+static void print_alias PARAMS((alias_t *, int));
/* Hack the alias command in a Korn shell way. */
int
diff --git a/builtins/bashgetopt.h b/builtins/bashgetopt.h
index 6637b429..dcdaa48a 100644
--- a/builtins/bashgetopt.h
+++ b/builtins/bashgetopt.h
@@ -1,6 +1,6 @@
/* bashgetopt.h -- extern declarations for stuff defined in bashgetopt.c. */
-/* Copyright (C) 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -36,7 +36,7 @@ extern int list_opttype;
extern WORD_LIST *lcurrent;
extern WORD_LIST *loptend;
-extern int internal_getopt __P((WORD_LIST *, char *));
-extern void reset_internal_getopt __P((void));
+extern int internal_getopt PARAMS((WORD_LIST *, char *));
+extern void reset_internal_getopt PARAMS((void));
#endif /* !__BASH_GETOPT_H */
diff --git a/builtins/bind.def b/builtins/bind.def
index 2b18873c..ccfc08dc 100644
--- a/builtins/bind.def
+++ b/builtins/bind.def
@@ -1,7 +1,7 @@
This file is bind.def, from which is created bind.c.
It implements the builtin "bind" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -86,9 +86,9 @@ extern int errno;
#include "bashgetopt.h"
#include "common.h"
-static int query_bindings __P((char *));
-static int unbind_command __P((char *));
-static int unbind_keyseq __P((char *));
+static int query_bindings PARAMS((char *));
+static int unbind_command PARAMS((char *));
+static int unbind_keyseq PARAMS((char *));
#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
@@ -192,7 +192,7 @@ bind_builtin (list)
case 'X':
flags |= XXFLAG;
break;
- CASE_HELPOPT;
+ case GETOPT_HELP:
default:
builtin_usage ();
BIND_RETURN (EX_USAGE);
@@ -277,7 +277,28 @@ bind_builtin (list)
/* Process the rest of the arguments as binding specifications. */
while (list)
{
+ int olen, nlen, d, i;
+ char **obindings, **nbindings;
+
+ obindings = rl_invoking_keyseqs (bash_execute_unix_command);
+ olen = obindings ? strvec_len (obindings) : 0;
+
rl_parse_and_bind (list->word->word);
+
+ nbindings = rl_invoking_keyseqs (bash_execute_unix_command);
+ nlen = nbindings ? strvec_len (nbindings) : 0;
+
+ if (nlen < olen) /* fewer bind -x bindings */
+ for (d = olen - nlen, i = 0; i < olen && d > 0; i++)
+ if (nlen == 0 || strvec_search (nbindings, obindings[i]) >= 0)
+ {
+ unbind_unix_command (obindings[i]);
+ d--;
+ }
+
+ strvec_dispose (obindings);
+ strvec_dispose (nbindings);
+
list = list->next;
}
@@ -287,6 +308,9 @@ bind_builtin (list)
run_unwind_frame ("bind_builtin");
+ if (return_code < 0)
+ return_code = EXECUTION_FAILURE;
+
return (sh_chkwrite (return_code));
}
@@ -344,7 +368,8 @@ unbind_keyseq (seq)
char *seq;
{
char *kseq;
- int kslen;
+ int kslen, type;
+ rl_command_func_t *f;
kseq = (char *)xmalloc ((2 * strlen (seq)) + 1);
if (rl_translate_keyseq (seq, kseq, &kslen))
@@ -353,11 +378,13 @@ unbind_keyseq (seq)
builtin_error (_("`%s': cannot unbind"), seq);
return EXECUTION_FAILURE;
}
- if (rl_function_of_keyseq (kseq, (Keymap)0, (int *)0) == 0)
+ if ((f = rl_function_of_keyseq_len (kseq, kslen, (Keymap)0, &type)) == 0)
{
free (kseq);
return (EXECUTION_SUCCESS);
}
+ if (type == ISKMAP)
+ f = ((Keymap) f)[ANYOTHERKEY].function;
/* I wish this didn't have to translate the key sequence again, but readline
doesn't have a binding function that takes a translated key sequence as
@@ -369,6 +396,9 @@ unbind_keyseq (seq)
return (EXECUTION_FAILURE);
}
+ if (f == bash_execute_unix_command)
+ unbind_unix_command (seq);
+
free (kseq);
return (EXECUTION_SUCCESS);
}
diff --git a/builtins/break.def b/builtins/break.def
index 876d0635..b73ed5e5 100644
--- a/builtins/break.def
+++ b/builtins/break.def
@@ -1,7 +1,7 @@
This file is break.def, from which is created break.c.
It implements the builtins "break" and "continue" in Bash.
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -46,7 +46,7 @@ $END
#include "../execute_cmd.h"
#include "common.h"
-static int check_loop_level __P((void));
+static int check_loop_level PARAMS((void));
/* The depth of while's and until's. */
int loop_level = 0;
diff --git a/builtins/caller.def b/builtins/caller.def
index bf5eb96f..1000979d 100644
--- a/builtins/caller.def
+++ b/builtins/caller.def
@@ -2,7 +2,7 @@ This file is caller.def, from which is created caller.c. It implements the
builtin "caller" in Bash.
Copyright (C) 2002-2008 Rocky Bernstein for Free Software Foundation, Inc.
-Copyright (C) 2008-2013 Free Software Foundation, Inc.
+Copyright (C) 2008-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -135,8 +135,8 @@ caller_builtin (list)
static char *caller_doc[] = {
N_("Returns the context of the current subroutine call.\n\
\n\
- Without EXPR, returns "$line $filename". With EXPR, returns\n\
- "$line $subroutine $filename"; this extra information can be used to\n\
+ Without EXPR, returns \"$line $filename\". With EXPR, returns\n\
+ \"$line $subroutine $filename\"; this extra information can be used to\n\
provide a stack trace.\n\
\n\
The value of EXPR indicates how many call frames to go back before the\n\
diff --git a/builtins/cd.def b/builtins/cd.def
index fe75b57f..7205608c 100644
--- a/builtins/cd.def
+++ b/builtins/cd.def
@@ -1,7 +1,7 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" in Bash.
-Copyright (C) 1987-2016 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -56,13 +56,13 @@ extern int errno;
extern const char * const bash_getcwd_errstr;
-static int bindpwd __P((int));
-static int setpwd __P((char *));
-static char *resetpwd __P((char *));
-static int change_to_directory __P((char *, int, int));
+static int bindpwd PARAMS((int));
+static int setpwd PARAMS((char *));
+static char *resetpwd PARAMS((char *));
+static int change_to_directory PARAMS((char *, int, int));
-static int cdxattr __P((char *, char **));
-static void resetxattr __P((void));
+static int cdxattr PARAMS((char *, char **));
+static void resetxattr PARAMS((void));
/* Change this to 1 to get cd spelling correction by default. */
int cdspelling = 0;
@@ -149,6 +149,7 @@ bindpwd (no_symlinks)
#undef tcwd
/* If canonicalization fails, reset dirname to the_current_working_directory */
+ canon_failed = 0;
if (dirname == 0)
{
canon_failed = 1;
diff --git a/builtins/colon.def b/builtins/colon.def
index 4b78b30c..6891b079 100644
--- a/builtins/colon.def
+++ b/builtins/colon.def
@@ -1,7 +1,7 @@
This file is colon.def, from which is created colon.c.
It implements the builtin ":" in Bash.
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -50,10 +50,19 @@ Exit Status:
Always fails.
$END
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include "../bashansi.h"
+#include "../shell.h"
+
/* Return a successful result. */
int
colon_builtin (ignore)
- char *ignore;
+ WORD_LIST *ignore;
{
return (0);
}
@@ -61,7 +70,7 @@ colon_builtin (ignore)
/* Return an unsuccessful result. */
int
false_builtin (ignore)
- char *ignore;
+ WORD_LIST *ignore;
{
return (1);
}
diff --git a/builtins/command.def b/builtins/command.def
index d58c985b..acd46cc1 100644
--- a/builtins/command.def
+++ b/builtins/command.def
@@ -1,7 +1,7 @@
This file is command.def, from which is created command.c.
It implements the builtin "command" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -57,7 +57,7 @@ $END
#include "common.h"
#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR
-extern size_t confstr __P((int, char *, size_t));
+extern size_t confstr PARAMS((int, char *, size_t));
#endif
/* Run the commands mentioned in LIST without paying attention to shell
@@ -124,6 +124,10 @@ command_builtin (list)
#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN | (use_standard_path ? CMD_STDPATH : 0))
+#ifdef DEBUG
+ itrace("command_builtin: running execute_command for `%s'", list->word->word);
+#endif
+
/* We don't want this to be reparsed (consider command echo 'foo &'), so
just make a simple_command structure and call execute_command with it. */
command = make_bare_simple_command ();
diff --git a/builtins/common.c b/builtins/common.c
index 00be24ea..3c9ac49d 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -1,6 +1,6 @@
/* common.c - utility functions for all builtins */
-/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -373,7 +373,8 @@ make_builtin_argv (list, ip)
/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
non-zero, then discard whatever the existing arguments are, else
- only discard the ones that are to be replaced. */
+ only discard the ones that are to be replaced. Set POSPARAM_COUNT
+ to the number of args assigned (length of LIST). */
void
remember_args (list, destructive)
WORD_LIST *list;
@@ -381,6 +382,8 @@ remember_args (list, destructive)
{
register int i;
+ posparam_count = 0;
+
for (i = 1; i < 10; i++)
{
if ((destructive || list) && dollar_vars[i])
@@ -391,7 +394,7 @@ remember_args (list, destructive)
if (list)
{
- dollar_vars[i] = savestring (list->word->word);
+ dollar_vars[posparam_count = i] = savestring (list->word->word);
list = list->next;
}
}
@@ -403,6 +406,7 @@ remember_args (list, destructive)
{
dispose_words (rest_of_args);
rest_of_args = copy_word_list (list);
+ posparam_count += list_length (list);
}
if (destructive)
@@ -411,6 +415,58 @@ remember_args (list, destructive)
invalidate_cached_quoted_dollar_at ();
}
+void
+shift_args (times)
+ int times;
+{
+ WORD_LIST *temp;
+ int count;
+
+ if (times <= 0) /* caller should check */
+ return;
+
+ while (times-- > 0)
+ {
+ if (dollar_vars[1])
+ free (dollar_vars[1]);
+
+ for (count = 1; count < 9; count++)
+ dollar_vars[count] = dollar_vars[count + 1];
+
+ if (rest_of_args)
+ {
+ temp = rest_of_args;
+ dollar_vars[9] = savestring (temp->word->word);
+ rest_of_args = rest_of_args->next;
+ temp->next = (WORD_LIST *)NULL;
+ dispose_words (temp);
+ }
+ else
+ dollar_vars[9] = (char *)NULL;
+
+ posparam_count--;
+ }
+}
+
+int
+number_of_args ()
+{
+#ifdef DEBUG
+ register WORD_LIST *list;
+ int n;
+
+ for (n = 0; n < 9 && dollar_vars[n+1]; n++)
+ ;
+ for (list = rest_of_args; list; list = list->next)
+ n++;
+
+if (n != posparam_count)
+ itrace("number_of_args: n (%d) != posparam_count (%d)", n, posparam_count);
+#endif
+
+ return posparam_count;
+}
+
static int changed_dollar_vars;
/* Have the dollar variables been reset to new values since we last
@@ -908,3 +964,54 @@ builtin_help ()
printf ("%s: %s\n", this_command_name, _("help not available in this version"));
}
#endif
+
+/* **************************************************************** */
+/* */
+/* Variable assignments during builtin commands */
+/* */
+/* **************************************************************** */
+
+SHELL_VAR *
+builtin_bind_variable (name, value, flags)
+ char *name;
+ char *value;
+ int flags;
+{
+ SHELL_VAR *v;
+
+#if defined (ARRAY_VARS)
+ if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
+ v = bind_variable (name, value, flags);
+ else
+ v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0));
+#else /* !ARRAY_VARS */
+ v = bind_variable (name, value, flags);
+#endif /* !ARRAY_VARS */
+
+ if (v && readonly_p (v) == 0 && noassign_p (v) == 0)
+ VUNSETATTR (v, att_invisible);
+
+ return v;
+}
+
+/* Like check_unbind_variable, but for use by builtins (only matters for
+ error messages). */
+int
+builtin_unbind_variable (vname)
+ const char *vname;
+{
+ SHELL_VAR *v;
+
+ v = find_variable (vname);
+ if (v && readonly_p (v))
+ {
+ builtin_error (_("%s: cannot unset: readonly %s"), vname, "variable");
+ return -2;
+ }
+ else if (v && non_unsettable_p (v))
+ {
+ builtin_error (_("%s: cannot unset"), vname);
+ return -2;
+ }
+ return (unbind_variable (vname));
+}
diff --git a/builtins/common.h b/builtins/common.h
index f0687640..a4f9275d 100644
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -1,6 +1,6 @@
/* common.h -- extern declarations for functions defined in common.c. */
-/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -80,142 +80,151 @@ do { \
#define MAX_ATTRIBUTES 16
/* Functions from common.c */
-extern void builtin_error __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
-extern void builtin_warning __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
-extern void builtin_usage __P((void));
-extern void no_args __P((WORD_LIST *));
-extern int no_options __P((WORD_LIST *));
+extern void builtin_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
+extern void builtin_warning PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
+extern void builtin_usage PARAMS((void));
+extern void no_args PARAMS((WORD_LIST *));
+extern int no_options PARAMS((WORD_LIST *));
/* common error message functions */
-extern void sh_needarg __P((char *));
-extern void sh_neednumarg __P((char *));
-extern void sh_notfound __P((char *));
-extern void sh_invalidopt __P((char *));
-extern void sh_invalidoptname __P((char *));
-extern void sh_invalidid __P((char *));
-extern void sh_invalidnum __P((char *));
-extern void sh_invalidsig __P((char *));
-extern void sh_erange __P((char *, char *));
-extern void sh_badpid __P((char *));
-extern void sh_badjob __P((char *));
-extern void sh_readonly __P((const char *));
-extern void sh_nojobs __P((char *));
-extern void sh_restricted __P((char *));
-extern void sh_notbuiltin __P((char *));
-extern void sh_wrerror __P((void));
-extern void sh_ttyerror __P((int));
-extern int sh_chkwrite __P((int));
-
-extern char **make_builtin_argv __P((WORD_LIST *, int *));
-extern void remember_args __P((WORD_LIST *, int));
-
-extern int dollar_vars_changed __P((void));
-extern void set_dollar_vars_unchanged __P((void));
-extern void set_dollar_vars_changed __P((void));
-
-extern int get_numeric_arg __P((WORD_LIST *, int, intmax_t *));
-extern int get_exitstat __P((WORD_LIST *));
-extern int read_octal __P((char *));
+extern void sh_needarg PARAMS((char *));
+extern void sh_neednumarg PARAMS((char *));
+extern void sh_notfound PARAMS((char *));
+extern void sh_invalidopt PARAMS((char *));
+extern void sh_invalidoptname PARAMS((char *));
+extern void sh_invalidid PARAMS((char *));
+extern void sh_invalidnum PARAMS((char *));
+extern void sh_invalidsig PARAMS((char *));
+extern void sh_erange PARAMS((char *, char *));
+extern void sh_badpid PARAMS((char *));
+extern void sh_badjob PARAMS((char *));
+extern void sh_readonly PARAMS((const char *));
+extern void sh_nojobs PARAMS((char *));
+extern void sh_restricted PARAMS((char *));
+extern void sh_notbuiltin PARAMS((char *));
+extern void sh_wrerror PARAMS((void));
+extern void sh_ttyerror PARAMS((int));
+extern int sh_chkwrite PARAMS((int));
+
+extern char **make_builtin_argv PARAMS((WORD_LIST *, int *));
+extern void remember_args PARAMS((WORD_LIST *, int));
+extern void shift_args PARAMS((int));
+extern int number_of_args PARAMS((void));
+
+extern int dollar_vars_changed PARAMS((void));
+extern void set_dollar_vars_unchanged PARAMS((void));
+extern void set_dollar_vars_changed PARAMS((void));
+
+extern int get_numeric_arg PARAMS((WORD_LIST *, int, intmax_t *));
+extern int get_exitstat PARAMS((WORD_LIST *));
+extern int read_octal PARAMS((char *));
/* Keeps track of the current working directory. */
extern char *the_current_working_directory;
-extern char *get_working_directory __P((char *));
-extern void set_working_directory __P((char *));
+extern char *get_working_directory PARAMS((char *));
+extern void set_working_directory PARAMS((char *));
#if defined (JOB_CONTROL)
-extern int get_job_by_name __P((const char *, int));
-extern int get_job_spec __P((WORD_LIST *));
+extern int get_job_by_name PARAMS((const char *, int));
+extern int get_job_spec PARAMS((WORD_LIST *));
#endif
-extern int display_signal_list __P((WORD_LIST *, int));
+extern int display_signal_list PARAMS((WORD_LIST *, int));
/* It's OK to declare a function as returning a Function * without
providing a definition of what a `Function' is. */
-extern struct builtin *builtin_address_internal __P((char *, int));
-extern sh_builtin_func_t *find_shell_builtin __P((char *));
-extern sh_builtin_func_t *builtin_address __P((char *));
-extern sh_builtin_func_t *find_special_builtin __P((char *));
-extern void initialize_shell_builtins __P((void));
+extern struct builtin *builtin_address_internal PARAMS((char *, int));
+extern sh_builtin_func_t *find_shell_builtin PARAMS((char *));
+extern sh_builtin_func_t *builtin_address PARAMS((char *));
+extern sh_builtin_func_t *find_special_builtin PARAMS((char *));
+extern void initialize_shell_builtins PARAMS((void));
/* Functions from exit.def */
-extern void bash_logout __P((void));
+extern void bash_logout PARAMS((void));
/* Functions from getopts.def */
-extern void getopts_reset __P((int));
+extern void getopts_reset PARAMS((int));
/* Functions from help.def */
-extern void builtin_help __P((void));
+extern void builtin_help PARAMS((void));
/* Functions from read.def */
-extern void read_tty_cleanup __P((void));
-extern int read_tty_modified __P((void));
+extern void read_tty_cleanup PARAMS((void));
+extern int read_tty_modified PARAMS((void));
/* Functions from set.def */
-extern int minus_o_option_value __P((char *));
-extern void list_minus_o_opts __P((int, int));
-extern char **get_minus_o_opts __P((void));
-extern int set_minus_o_option __P((int, char *));
+extern int minus_o_option_value PARAMS((char *));
+extern void list_minus_o_opts PARAMS((int, int));
+extern char **get_minus_o_opts PARAMS((void));
+extern int set_minus_o_option PARAMS((int, char *));
-extern void set_shellopts __P((void));
-extern void parse_shellopts __P((char *));
-extern void initialize_shell_options __P((int));
+extern void set_shellopts PARAMS((void));
+extern void parse_shellopts PARAMS((char *));
+extern void initialize_shell_options PARAMS((int));
-extern void reset_shell_options __P((void));
+extern void reset_shell_options PARAMS((void));
-extern char *get_current_options __P((void));
-extern void set_current_options __P((const char *));
+extern char *get_current_options PARAMS((void));
+extern void set_current_options PARAMS((const char *));
/* Functions from shopt.def */
-extern void reset_shopt_options __P((void));
-extern char **get_shopt_options __P((void));
+extern void reset_shopt_options PARAMS((void));
+extern char **get_shopt_options PARAMS((void));
-extern int shopt_setopt __P((char *, int));
-extern int shopt_listopt __P((char *, int));
+extern int shopt_setopt PARAMS((char *, int));
+extern int shopt_listopt PARAMS((char *, int));
-extern int set_login_shell __P((char *, int));
+extern int set_login_shell PARAMS((char *, int));
-extern void set_bashopts __P((void));
-extern void parse_bashopts __P((char *));
-extern void initialize_bashopts __P((int));
+extern void set_bashopts PARAMS((void));
+extern void parse_bashopts PARAMS((char *));
+extern void initialize_bashopts PARAMS((int));
-extern void set_compatibility_opts __P((void));
+extern void set_compatibility_opts PARAMS((void));
/* Functions from type.def */
-extern int describe_command __P((char *, int));
+extern int describe_command PARAMS((char *, int));
/* Functions from setattr.def */
-extern int set_or_show_attributes __P((WORD_LIST *, int, int));
-extern int show_all_var_attributes __P((int, int));
-extern int show_var_attributes __P((SHELL_VAR *, int, int));
-extern int show_name_attributes __P((char *, int));
-extern int show_func_attributes __P((char *, int));
-extern void set_var_attribute __P((char *, int, int));
-extern int var_attribute_string __P((SHELL_VAR *, int, char *));
+extern int set_or_show_attributes PARAMS((WORD_LIST *, int, int));
+extern int show_all_var_attributes PARAMS((int, int));
+extern int show_local_var_attributes PARAMS((int, int));
+extern int show_var_attributes PARAMS((SHELL_VAR *, int, int));
+extern int show_name_attributes PARAMS((char *, int));
+extern int show_localname_attributes PARAMS((char *, int));
+extern int show_func_attributes PARAMS((char *, int));
+extern void set_var_attribute PARAMS((char *, int, int));
+extern int var_attribute_string PARAMS((SHELL_VAR *, int, char *));
/* Functions from pushd.def */
-extern char *get_dirstack_from_string __P((char *));
-extern char *get_dirstack_element __P((intmax_t, int));
-extern void set_dirstack_element __P((intmax_t, int, char *));
-extern WORD_LIST *get_directory_stack __P((int));
+extern char *get_dirstack_from_string PARAMS((char *));
+extern char *get_dirstack_element PARAMS((intmax_t, int));
+extern void set_dirstack_element PARAMS((intmax_t, int, char *));
+extern WORD_LIST *get_directory_stack PARAMS((int));
/* Functions from evalstring.c */
-extern int parse_and_execute __P((char *, const char *, int));
-extern int evalstring __P((char *, const char *, int));
-extern void parse_and_execute_cleanup __P((int));
-extern int parse_string __P((char *, const char *, int, char **));
-extern int should_suppress_fork __P((COMMAND *));
-extern void optimize_fork __P((COMMAND *));
-extern void optimize_subshell_command __P((COMMAND *));
+extern int parse_and_execute PARAMS((char *, const char *, int));
+extern int evalstring PARAMS((char *, const char *, int));
+extern void parse_and_execute_cleanup PARAMS((int));
+extern int parse_string PARAMS((char *, const char *, int, char **));
+extern int should_suppress_fork PARAMS((COMMAND *));
+extern int can_optimize_connection PARAMS((COMMAND *));
+extern void optimize_fork PARAMS((COMMAND *));
+extern void optimize_subshell_command PARAMS((COMMAND *));
+extern void optimize_shell_function PARAMS((COMMAND *));
/* Functions from evalfile.c */
-extern int maybe_execute_file __P((const char *, int));
-extern int force_execute_file __P((const char *, int));
-extern int source_file __P((const char *, int));
-extern int fc_execute_file __P((const char *));
+extern int maybe_execute_file PARAMS((const char *, int));
+extern int force_execute_file PARAMS((const char *, int));
+extern int source_file PARAMS((const char *, int));
+extern int fc_execute_file PARAMS((const char *));
/* variables from common.c */
extern sh_builtin_func_t *this_shell_builtin;
extern sh_builtin_func_t *last_shell_builtin;
+extern SHELL_VAR *builtin_bind_variable PARAMS((char *, char *, int));
+extern int builtin_unbind_variable PARAMS((const char *));
+
/* variables from evalfile.c */
extern int sourcelevel;
diff --git a/builtins/complete.def b/builtins/complete.def
index 76b3eedd..28a9ec2f 100644
--- a/builtins/complete.def
+++ b/builtins/complete.def
@@ -1,7 +1,7 @@
This file is complete.def, from which is created complete.c.
It implements the builtins "complete", "compgen", and "compopt" in Bash.
-Copyright (C) 1999-2015 Free Software Foundation, Inc.
+Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,7 +23,7 @@ $PRODUCES complete.c
$BUILTIN complete
$DEPENDS_ON PROGRAMMABLE_COMPLETION
$FUNCTION complete_builtin
-$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
+$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
Specify how arguments are to be completed by Readline.
For each NAME, specify how arguments are to be completed. If no options
@@ -42,7 +42,7 @@ Options:
command) word
When completion is attempted, the actions are applied in the order the
-uppercase-letter options are listed above. If multiple options are supplied,
+uppercase-letter options are listed above. If multiple options are supplied,
the -D option takes precedence over -E, and both take precedence over -I.
Exit Status:
@@ -84,24 +84,29 @@ struct _optflags {
int Iflag;
};
-static int find_compact __P((char *));
-static int find_compopt __P((char *));
+static int find_compact PARAMS((char *));
+static int find_compopt PARAMS((char *));
-static int build_actions __P((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *));
+static int build_actions PARAMS((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *));
-static int remove_cmd_completions __P((WORD_LIST *));
+static int remove_cmd_completions PARAMS((WORD_LIST *));
-static int print_one_completion __P((char *, COMPSPEC *));
-static int print_compitem __P((BUCKET_CONTENTS *));
-static void print_compopts __P((const char *, COMPSPEC *, int));
-static void print_all_completions __P((void));
-static int print_cmd_completions __P((WORD_LIST *));
+static int print_one_completion PARAMS((char *, COMPSPEC *));
+static int print_compitem PARAMS((BUCKET_CONTENTS *));
+static void print_compopts PARAMS((const char *, COMPSPEC *, int));
+static void print_all_completions PARAMS((void));
+static int print_cmd_completions PARAMS((WORD_LIST *));
+
+static void print_compoptions PARAMS((unsigned long, int));
+static void print_compactions PARAMS((unsigned long));
+static void print_arg PARAMS((const char *, const char *, int));
+static void print_cmd_name PARAMS((const char *));
static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
static const struct _compacts {
const char * const actname;
- int actflag;
+ unsigned long actflag;
int actopt;
} compacts[] = {
{ "alias", CA_ALIAS, 'a' },
@@ -134,7 +139,7 @@ static const struct _compacts {
/* This should be a STRING_INT_ALIST */
static const struct _compopt {
const char * const optname;
- int optflag;
+ unsigned long optflag;
} compopts[] = {
{ "bashdefault", COPT_BASHDEFAULT },
{ "default", COPT_DEFAULT },
@@ -193,6 +198,7 @@ build_actions (list, flagp, actp, optp)
{
int opt, ind, opt_given;
unsigned long acts, copts;
+ WORD_DESC w;
acts = copts = (unsigned long)0L;
opt_given = 0;
@@ -323,7 +329,13 @@ build_actions (list, flagp, actp, optp)
return (EX_USAGE);
}
case 'F':
- Farg = list_optarg;
+ w.word = Farg = list_optarg;
+ w.flags = 0;
+ if (check_identifier (&w, posixly_correct) == 0 || strpbrk (Farg, shell_break_chars) != 0)
+ {
+ sh_invalidid (Farg);
+ return (EX_USAGE);
+ }
break;
case 'G':
Garg = list_optarg;
@@ -478,122 +490,95 @@ remove_cmd_completions (list)
return ret;
}
-#define SQPRINTARG(a, f) \
- do { \
- if (a) \
- { \
- x = sh_single_quote (a); \
- printf ("%s %s ", f, x); \
- free (x); \
- } \
- } while (0)
-
-#define PRINTARG(a, f) \
- do { \
- if (a) \
- printf ("%s %s ", f, a); \
- } while (0)
-
-#define PRINTOPT(a, f) \
- do { \
- if (acts & a) \
- printf ("%s ", f); \
- } while (0)
-
-#define PRINTACT(a, f) \
- do { \
- if (acts & a) \
- printf ("-A %s ", f); \
- } while (0)
-
-#define PRINTCOMPOPT(a, f) \
- do { \
- if (copts & a) \
- printf ("-o %s ", f); \
- } while (0)
-
-#define XPRINTCOMPOPT(a, f) \
- do { \
- if (copts & a) \
- printf ("-o %s ", f); \
- else \
- printf ("+o %s ", f); \
- } while (0)
+static void
+print_compoptions (copts, full)
+ unsigned long copts;
+ int full;
+{
+ const struct _compopt *co;
+
+ for (co = compopts; co->optname; co++)
+ if (copts & co->optflag)
+ printf ("-o %s ", co->optname);
+ else if (full)
+ printf ("+o %s ", co->optname);
+}
+
+static void
+print_compactions (acts)
+ unsigned long acts;
+{
+ const struct _compacts *ca;
+
+ /* simple flags first */
+ for (ca = compacts; ca->actname; ca++)
+ if (ca->actopt && (acts & ca->actflag))
+ printf ("-%c ", ca->actopt);
+
+ /* then the rest of the actions */
+ for (ca = compacts; ca->actname; ca++)
+ if (ca->actopt == 0 && (acts & ca->actflag))
+ printf ("-A %s ", ca->actname);
+}
+
+static void
+print_arg (arg, flag, quote)
+ const char *arg, *flag;
+ int quote;
+{
+ char *x;
+
+ if (arg)
+ {
+ x = quote ? sh_single_quote (arg) : (char *)arg;
+ printf ("%s %s ", flag, x);
+ if (x != arg)
+ free (x);
+ }
+}
+
+static void
+print_cmd_name (cmd)
+ const char *cmd;
+{
+ if (STREQ (cmd, DEFAULTCMD))
+ printf ("-D");
+ else if (STREQ (cmd, EMPTYCMD))
+ printf ("-E");
+ else if (STREQ (cmd, INITIALWORD))
+ printf ("-I");
+ else if (*cmd == 0) /* XXX - can this happen? */
+ printf ("''");
+ else
+ printf ("%s", cmd);
+}
static int
print_one_completion (cmd, cs)
char *cmd;
COMPSPEC *cs;
{
- unsigned long acts, copts;
- char *x;
-
printf ("complete ");
- copts = cs->options;
-
- /* First, print the -o options. */
- PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
- PRINTCOMPOPT (COPT_DEFAULT, "default");
- PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
- PRINTCOMPOPT (COPT_FILENAMES, "filenames");
- PRINTCOMPOPT (COPT_NOQUOTE, "noquote");
- PRINTCOMPOPT (COPT_NOSORT, "nosort");
- PRINTCOMPOPT (COPT_NOSPACE, "nospace");
- PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
-
- acts = cs->actions;
-
- /* simple flags next */
- PRINTOPT (CA_ALIAS, "-a");
- PRINTOPT (CA_BUILTIN, "-b");
- PRINTOPT (CA_COMMAND, "-c");
- PRINTOPT (CA_DIRECTORY, "-d");
- PRINTOPT (CA_EXPORT, "-e");
- PRINTOPT (CA_FILE, "-f");
- PRINTOPT (CA_GROUP, "-g");
- PRINTOPT (CA_JOB, "-j");
- PRINTOPT (CA_KEYWORD, "-k");
- PRINTOPT (CA_SERVICE, "-s");
- PRINTOPT (CA_USER, "-u");
- PRINTOPT (CA_VARIABLE, "-v");
-
- /* now the rest of the actions */
- PRINTACT (CA_ARRAYVAR, "arrayvar");
- PRINTACT (CA_BINDING, "binding");
- PRINTACT (CA_DISABLED, "disabled");
- PRINTACT (CA_ENABLED, "enabled");
- PRINTACT (CA_FUNCTION, "function");
- PRINTACT (CA_HELPTOPIC, "helptopic");
- PRINTACT (CA_HOSTNAME, "hostname");
- PRINTACT (CA_RUNNING, "running");
- PRINTACT (CA_SETOPT, "setopt");
- PRINTACT (CA_SHOPT, "shopt");
- PRINTACT (CA_SIGNAL, "signal");
- PRINTACT (CA_STOPPED, "stopped");
+ print_compoptions (cs->options, 0);
+ print_compactions (cs->actions);
/* now the rest of the arguments */
/* arguments that require quoting */
- SQPRINTARG (cs->globpat, "-G");
- SQPRINTARG (cs->words, "-W");
- SQPRINTARG (cs->prefix, "-P");
- SQPRINTARG (cs->suffix, "-S");
- SQPRINTARG (cs->filterpat, "-X");
+ print_arg (cs->globpat, "-G", 1);
+ print_arg (cs->words, "-W", 1);
+ print_arg (cs->prefix, "-P", 1);
+ print_arg (cs->suffix, "-S", 1);
+ print_arg (cs->filterpat, "-X", 1);
- SQPRINTARG (cs->command, "-C");
+ print_arg (cs->command, "-C", 1);
/* simple arguments that don't require quoting */
- PRINTARG (cs->funcname, "-F");
+ print_arg (cs->funcname, "-F", 0);
- if (STREQ (cmd, DEFAULTCMD))
- printf ("-D\n");
- else if (STREQ (cmd, EMPTYCMD))
- printf ("-E\n");
- else if (STREQ (cmd, INITIALWORD))
- printf ("-I\n");
- else
- printf ("%s\n", cmd);
+ print_cmd_name (cmd);
+ printf ("\n");
return (0);
}
@@ -604,42 +589,12 @@ print_compopts (cmd, cs, full)
COMPSPEC *cs;
int full;
{
- int copts;
-
printf ("compopt ");
- copts = cs->options;
- if (full)
- {
- XPRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
- XPRINTCOMPOPT (COPT_DEFAULT, "default");
- XPRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
- XPRINTCOMPOPT (COPT_FILENAMES, "filenames");
- XPRINTCOMPOPT (COPT_NOQUOTE, "noquote");
- XPRINTCOMPOPT (COPT_NOSORT, "nosort");
- XPRINTCOMPOPT (COPT_NOSPACE, "nospace");
- XPRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
- }
- else
- {
- PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
- PRINTCOMPOPT (COPT_DEFAULT, "default");
- PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
- PRINTCOMPOPT (COPT_FILENAMES, "filenames");
- PRINTCOMPOPT (COPT_NOQUOTE, "noquote");
- PRINTCOMPOPT (COPT_NOSORT, "nosort");
- PRINTCOMPOPT (COPT_NOSPACE, "nospace");
- PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
- }
+ print_compoptions (cs->options, full);
+ print_cmd_name (cmd);
- if (STREQ (cmd, DEFAULTCMD))
- printf ("-D\n");
- else if (STREQ (cmd, EMPTYCMD))
- printf ("-E\n");
- else if (STREQ (cmd, INITIALWORD))
- printf ("-I\n");
- else
- printf ("%s\n", cmd);
+ printf ("\n");
}
static int
@@ -687,7 +642,7 @@ print_cmd_completions (list)
$BUILTIN compgen
$DEPENDS_ON PROGRAMMABLE_COMPLETION
$FUNCTION compgen_builtin
-$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
+$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
Display possible completions depending on the options.
Intended to be used from within a shell function generating possible
diff --git a/builtins/declare.def b/builtins/declare.def
index 7eac6f58..21e4516d 100644
--- a/builtins/declare.def
+++ b/builtins/declare.def
@@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
-Copyright (C) 1987-2016 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,7 +22,7 @@ $PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
-$SHORT_DOC declare [-aAfFgilnrtux] [-p] [name[=value] ...]
+$SHORT_DOC declare [-aAfFgiIlnrtux] [-p] [name[=value] ...]
Set variable values and attributes.
Declare variables and give them attributes. If no NAMEs are given,
@@ -34,6 +34,8 @@ Options:
source file when debugging)
-g create global variables when used in a shell function; otherwise
ignored
+ -I if creating a local variable, inherit the attributes and value
+ of a variable with the same name at a previous scope
-p display the attributes and value of each NAME
Options which set attributes:
@@ -62,7 +64,7 @@ $END
$BUILTIN typeset
$FUNCTION declare_builtin
-$SHORT_DOC typeset [-aAfFgilnrtux] [-p] name[=value] ...
+$SHORT_DOC typeset [-aAfFgiIlnrtux] [-p] name[=value] ...
Set variable values and attributes.
A synonym for `declare'. See `help declare'.
@@ -88,8 +90,8 @@ $END
#include "builtext.h"
#include "bashgetopt.h"
-static SHELL_VAR *declare_find_variable __P((const char *, int, int));
-static int declare_internal __P((register WORD_LIST *, int));
+static SHELL_VAR *declare_find_variable PARAMS((const char *, int, int));
+static int declare_internal PARAMS((register WORD_LIST *, int));
/* Declare or change variable attributes. */
int
@@ -135,9 +137,9 @@ local_builtin (list)
}
#if defined (ARRAY_VARS)
-# define DECLARE_OPTS "+acfgilnprtuxAFG"
+# define DECLARE_OPTS "+acfgilnprtuxAFGI"
#else
-# define DECLARE_OPTS "+cfgilnprtuxFG"
+# define DECLARE_OPTS "+cfgilnprtuxFGI"
#endif
static SHELL_VAR *
@@ -168,13 +170,13 @@ declare_internal (list, local_var)
{
int flags_on, flags_off, *flags;
int any_failed, assign_error, pflag, nodefs, opt, onref, offref;
- int mkglobal, chklocal;
+ int mkglobal, chklocal, inherit_flag;
char *t, *subscript_start;
SHELL_VAR *var, *refvar, *v;
FUNCTION_DEF *shell_fn;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
- mkglobal = chklocal = 0;
+ mkglobal = chklocal = inherit_flag = 0;
refvar = (SHELL_VAR *)NULL;
reset_internal_getopt ();
while ((opt = internal_getopt (list, DECLARE_OPTS)) != -1)
@@ -202,7 +204,7 @@ declare_internal (list, local_var)
return (EX_USAGE);
#endif
case 'p':
- if (local_var == 0)
+/* if (local_var == 0) */
pflag++;
break;
case 'F':
@@ -255,6 +257,9 @@ declare_internal (list, local_var)
flags_off |= att_capcase|att_lowercase;
break;
#endif /* CASEMOD_ATTRS */
+ case 'I':
+ inherit_flag = MKLOC_INHERIT;
+ break;
CASE_HELPOPT;
default:
builtin_usage ();
@@ -271,20 +276,7 @@ declare_internal (list, local_var)
/* Show local variables defined at this context level if this is
the `local' builtin. */
if (local_var)
- {
- register SHELL_VAR **vlist;
- register int i;
-
- vlist = all_local_variables ();
-
- if (vlist)
- {
- for (i = 0; vlist[i]; i++)
- print_assignment (vlist[i]);
-
- free (vlist);
- }
- }
+ show_local_var_attributes (0, nodefs); /* XXX - fix up args later */
else if (pflag && (flags_on == 0 || flags_on == att_function))
show_all_var_attributes (flags_on == 0, nodefs);
else if (flags_on == 0)
@@ -301,6 +293,8 @@ declare_internal (list, local_var)
{
if (flags_on & att_function)
pflag = show_func_attributes (list->word->word, nodefs);
+ else if (local_var)
+ pflag = show_localname_attributes (list->word->word, nodefs);
else
pflag = show_name_attributes (list->word->word, nodefs);
if (pflag)
@@ -463,9 +457,9 @@ restart_new_var_name:
return an existing {array,assoc} variable to be flagged as an
error below. */
if (flags_on & att_assoc)
- var = make_local_assoc_variable (newname, 1);
+ var = make_local_assoc_variable (newname, MKLOC_ARRAYOK|inherit_flag);
else if ((flags_on & att_array) || making_array_special)
- var = make_local_array_variable (newname, 1);
+ var = make_local_array_variable (newname, MKLOC_ASSOCOK|inherit_flag);
else
#endif
if (offset == 0 && (flags_on & att_nameref))
@@ -479,18 +473,18 @@ restart_new_var_name:
if (refvar && refvar->context != variable_context)
{
refvar = 0;
- var = make_local_variable (name, 0);
+ var = make_local_variable (name, inherit_flag);
}
else if (refvar && refvar->context == variable_context)
var = refvar;
/* Maybe we just want to create a new local variable */
else if (var == 0 || var->context != variable_context)
- var = make_local_variable (name, 0);
+ var = make_local_variable (name, inherit_flag);
/* otherwise we have a var at the right context */
}
else
/* XXX - check name for validity here with valid_nameref_value */
- var = make_local_variable ((flags_on & att_nameref) ? name : newname, 0); /* sets att_invisible for new vars */
+ var = make_local_variable ((flags_on & att_nameref) ? name : newname, inherit_flag); /* sets att_invisible for new vars */
if (var == 0)
{
@@ -533,7 +527,12 @@ restart_new_var_name:
any_failed++;
NEXT_VARIABLE ();
}
-
+ else if (flags_on & (att_array|att_assoc))
+ {
+ sh_invalidopt ((flags_on & att_array) ? "-a" : "-A");
+ any_failed++;
+ NEXT_VARIABLE ();
+ }
/* declare -[Ff] name [name...] */
if (flags_on == att_function && flags_off == 0)
{
@@ -558,6 +557,7 @@ restart_new_var_name:
else /* declare -[fF] -[rx] name [name...] */
{
VSETATTR (var, flags_on);
+ flags_off &= ~att_function; /* makes no sense */
VUNSETATTR (var, flags_off);
}
}
@@ -727,20 +727,20 @@ restart_new_var_name:
if (flags_on & att_assoc)
{
var = make_new_assoc_variable (name);
- if (var && offset == 0 && no_invisible_vars == 0)
+ if (var && offset == 0)
VSETATTR (var, att_invisible);
}
else if ((flags_on & att_array) || making_array_special)
{
var = make_new_array_variable (name);
- if (var && offset == 0 && no_invisible_vars == 0)
+ if (var && offset == 0)
VSETATTR (var, att_invisible);
}
else
#endif
{
var = mkglobal ? bind_global_variable (name, (char *)NULL, ASS_FORCE) : bind_variable (name, (char *)NULL, ASS_FORCE);
- if (var && offset == 0 && no_invisible_vars == 0)
+ if (var && offset == 0)
VSETATTR (var, att_invisible);
}
if (var == 0)
diff --git a/builtins/enable.def b/builtins/enable.def
index 39c36698..9d9010b7 100644
--- a/builtins/enable.def
+++ b/builtins/enable.def
@@ -1,7 +1,7 @@
This file is enable.def, from which is created enable.c.
It implements the builtin "enable" in Bash.
-Copyright (C) 1987-2016 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -84,13 +84,13 @@ $END
#define SFLAG 0x20
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
-static int dyn_load_builtin __P((WORD_LIST *, int, char *));
+static int dyn_load_builtin PARAMS((WORD_LIST *, int, char *));
#endif
#if defined (HAVE_DLCLOSE)
-static int dyn_unload_builtin __P((char *));
-static void delete_builtin __P((struct builtin *));
-static int local_dlclose __P((void *));
+static int dyn_unload_builtin PARAMS((char *));
+static void delete_builtin PARAMS((struct builtin *));
+static int local_dlclose PARAMS((void *));
#endif
#define STRUCT_SUFFIX "_struct"
@@ -98,8 +98,8 @@ static int local_dlclose __P((void *));
#define LOAD_SUFFIX "_builtin_load"
#define UNLOAD_SUFFIX "_builtin_unload"
-static void list_some_builtins __P((int));
-static int enable_shell_command __P((char *, int));
+static void list_some_builtins PARAMS((int));
+static int enable_shell_command PARAMS((char *, int));
/* Enable/disable shell commands present in LIST. If list is not specified,
then print out a list of shell commands showing which are enabled and
@@ -362,6 +362,8 @@ dyn_load_builtin (list, flags, filename)
strcpy (struct_name, name);
strcpy (struct_name + size, STRUCT_SUFFIX);
+ old_builtin = builtin_address_internal (name, 1);
+
b = (struct builtin *)dlsym (handle, struct_name);
if (b == 0)
{
@@ -381,6 +383,9 @@ dyn_load_builtin (list, flags, filename)
loadfunc = (sh_load_func_t *)dlsym (handle, funcname);
if (loadfunc)
{
+ /* Add warning if running an init function more than once */
+ if (old_builtin && (old_builtin->flags & STATIC_BUILTIN) == 0)
+ builtin_warning (_("%s: dynamic builtin already loaded"), name);
r = (*loadfunc) (name);
if (r == 0)
{
@@ -396,7 +401,7 @@ dyn_load_builtin (list, flags, filename)
b->flags |= SPECIAL_BUILTIN;
b->handle = handle;
- if (old_builtin = builtin_address_internal (name, 1))
+ if (old_builtin)
{
replaced++;
FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
diff --git a/builtins/evalfile.c b/builtins/evalfile.c
index 32a7c8d6..fc3975ec 100644
--- a/builtins/evalfile.c
+++ b/builtins/evalfile.c
@@ -123,7 +123,7 @@ file_error_and_exit:
if (flags & FEVAL_LONGJMP)
{
- last_command_exit_value = 1;
+ last_command_exit_value = EXECUTION_FAILURE;
jump_to_top_level (EXITPROG);
}
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
index 2f13a66a..18928a17 100644
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -1,6 +1,6 @@
/* evalstring.c - evaluate a string as one or more shell commands. */
-/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -63,7 +63,7 @@ extern int errno;
int parse_and_execute_level = 0;
-static int cat_file __P((REDIRECT *));
+static int cat_file PARAMS((REDIRECT *));
#define PE_TAG "parse_and_execute top"
#define PS_TAG "parse_string top"
@@ -88,6 +88,11 @@ int
should_suppress_fork (command)
COMMAND *command;
{
+#if 0 /* TAG: bash-5.2 */
+ int subshell;
+
+ subshell = subshell_environment & SUBSHELL_PROCSUB; /* salt to taste */
+#endif
return (startup_state == 2 && parse_and_execute_level == 1 &&
running_trap == 0 &&
*bash_input.location.string == '\0' &&
@@ -96,7 +101,11 @@ should_suppress_fork (command)
signal_is_trapped (EXIT_TRAP) == 0 &&
signal_is_trapped (ERROR_TRAP) == 0 &&
any_signals_trapped () < 0 &&
+#if 0 /* TAG: bash-5.2 */
+ (subshell || (command->redirects == 0 && command->value.Simple->redirects == 0)) &&
+#else
command->redirects == 0 && command->value.Simple->redirects == 0 &&
+#endif
((command->flags & CMD_TIME_PIPELINE) == 0) &&
((command->flags & CMD_INVERT_RETURN) == 0));
}
@@ -145,7 +154,27 @@ optimize_subshell_command (command)
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR))
optimize_subshell_command (command->value.Connection->second);
}
-
+
+void
+optimize_shell_function (command)
+ COMMAND *command;
+{
+ COMMAND *fc;
+
+ fc = (command->type == cm_group) ? command->value.Group->command : command;
+
+ if (fc->type == cm_simple && should_suppress_fork (fc))
+ {
+ fc->flags |= CMD_NO_FORK;
+ fc->value.Simple->flags |= CMD_NO_FORK;
+ }
+ else if (fc->type == cm_connection && can_optimize_connection (fc) && should_suppress_fork (fc->value.Connection->second))
+ {
+ fc->value.Connection->second->flags |= CMD_NO_FORK;
+ fc->value.Connection->second->value.Simple->flags |= CMD_NO_FORK;
+ }
+}
+
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup (old_running_trap)
@@ -339,6 +368,7 @@ parse_and_execute (string, from_file, flags)
if (command)
run_unwind_frame ("pe_dispose");
last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
+ set_pipestatus_from_exit (last_command_exit_value);
if (subshell_environment)
{
should_jump_to_top_level = 1;
@@ -389,6 +419,7 @@ parse_and_execute (string, from_file, flags)
internal_warning (_("%s: ignoring function definition attempt"), from_file);
should_jump_to_top_level = 0;
last_result = last_command_exit_value = EX_BADUSAGE;
+ set_pipestatus_from_exit (last_command_exit_value);
reset_parser ();
break;
}
@@ -609,7 +640,7 @@ itrace("parse_string: longjmp executed: code = %d", code);
break;
}
- out:
+out:
global_command = oglobal;
nc = bash_input.location.string - ostring;
@@ -654,7 +685,7 @@ cat_file (r)
if (fn == 0)
{
- redirection_error (r, AMBIGUOUS_REDIRECT);
+ redirection_error (r, AMBIGUOUS_REDIRECT, fn);
return -1;
}
diff --git a/builtins/exec.def b/builtins/exec.def
index d4670673..cbcb641a 100644
--- a/builtins/exec.def
+++ b/builtins/exec.def
@@ -1,7 +1,7 @@
This file is exec.def, from which is created exec.c.
It implements the builtin "exec" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,7 +22,7 @@ $PRODUCES exec.c
$BUILTIN exec
$FUNCTION exec_builtin
-$SHORT_DOC exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
+$SHORT_DOC exec [-cl] [-a name] [command [argument ...]] [redirection ...]
Replace the shell with the given command.
Execute COMMAND, replacing this shell with the specified program.
@@ -52,6 +52,8 @@ $END
# include <unistd.h>
#endif
+#include <stdio.h>
+
#include "../bashansi.h"
#include "../bashintl.h"
@@ -99,7 +101,7 @@ exec_builtin (list)
WORD_LIST *list;
{
int exit_value = EXECUTION_FAILURE;
- int cleanenv, login, opt;
+ int cleanenv, login, opt, orig_job_control;
char *argv0, *command, **args, **env, *newname, *com2;
cleanenv = login = 0;
@@ -216,6 +218,7 @@ exec_builtin (list)
restore_original_signals ();
#if defined (JOB_CONTROL)
+ orig_job_control = job_control; /* XXX - was also interactive_shell */
if (subshell_environment == 0)
end_job_control ();
if (interactive || job_control)
@@ -262,7 +265,7 @@ failed_exec:
initialize_signals (1);
#if defined (JOB_CONTROL)
- if (interactive_shell || job_control)
+ if (orig_job_control)
restart_job_control ();
#endif /* JOB_CONTROL */
diff --git a/builtins/exit.def b/builtins/exit.def
index 5167b2e0..dc6f3d5b 100644
--- a/builtins/exit.def
+++ b/builtins/exit.def
@@ -1,7 +1,7 @@
This file is exit.def, from which is created exit.c.
It implements the builtins "exit", and "logout" in Bash.
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -50,7 +50,7 @@ $END
extern int check_jobs_at_exit;
-static int exit_or_logout __P((WORD_LIST *));
+static int exit_or_logout PARAMS((WORD_LIST *));
static int sourced_logout;
int
diff --git a/builtins/fc.def b/builtins/fc.def
index 62a28c4c..467dbcbc 100644
--- a/builtins/fc.def
+++ b/builtins/fc.def
@@ -1,7 +1,7 @@
This file is fc.def, from which is created fc.c.
It implements the builtin "fc" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -86,9 +86,19 @@ $END
extern int errno;
#endif /* !errno */
-extern int unlink __P((const char *));
+#define HIST_INVALID INT_MIN
+#define HIST_ERANGE INT_MIN+1
+#define HIST_NOTFOUND INT_MIN+2
-extern FILE *sh_mktmpfp __P((char *, int, char **));
+/* Values for the flags argument to fc_gethnum */
+#define HN_LISTING 0x01
+#define HN_FIRST 0x02
+
+extern int unlink PARAMS((const char *));
+
+extern FILE *sh_mktmpfp PARAMS((char *, int, char **));
+
+extern int suppress_debug_trap_verbose;
/* **************************************************************** */
/* */
@@ -144,14 +154,14 @@ typedef struct repl {
} \
} while (0)
-static char *fc_dosubs __P((char *, REPL *));
-static char *fc_gethist __P((char *, HIST_ENTRY **));
-static int fc_gethnum __P((char *, HIST_ENTRY **));
-static int fc_number __P((WORD_LIST *));
-static void fc_replhist __P((char *));
+static char *fc_dosubs PARAMS((char *, REPL *));
+static char *fc_gethist PARAMS((char *, HIST_ENTRY **, int));
+static int fc_gethnum PARAMS((char *, HIST_ENTRY **, int));
+static int fc_number PARAMS((WORD_LIST *));
+static void fc_replhist PARAMS((char *));
#ifdef INCLUDE_UNUSED
-static char *fc_readline __P((FILE *));
-static void fc_addhist __P((char *));
+static char *fc_readline PARAMS((FILE *));
+static void fc_addhist PARAMS((char *));
#endif
static void
@@ -199,7 +209,7 @@ fc_builtin (list)
break;
case 'l':
- listing = 1;
+ listing = HN_LISTING; /* for fc_gethnum */
break;
case 'r':
@@ -258,7 +268,7 @@ fc_builtin (list)
/* If we still have something in list, it is a command spec.
Otherwise, we use the most recent command in time. */
- command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
+ command = fc_gethist (list ? list->word->word : (char *)NULL, hlist, 0);
if (command == NULL)
{
@@ -319,18 +329,15 @@ fc_builtin (list)
while (last_hist >= 0 && hlist[last_hist] == 0)
last_hist--;
if (last_hist < 0)
- {
- sh_erange ((char *)NULL, _("history specification"));
- return (EXECUTION_FAILURE);
- }
+ last_hist = 0; /* per POSIX */
if (list)
{
- histbeg = fc_gethnum (list->word->word, hlist);
+ histbeg = fc_gethnum (list->word->word, hlist, listing|HN_FIRST);
list = list->next;
if (list)
- histend = fc_gethnum (list->word->word, hlist);
+ histend = fc_gethnum (list->word->word, hlist, listing);
else if (histbeg == real_last)
histend = listing ? real_last : histbeg;
else
@@ -351,6 +358,28 @@ fc_builtin (list)
histbeg = histend = last_hist;
}
+ if (histbeg == HIST_INVALID || histend == HIST_INVALID)
+ {
+ sh_erange ((char *)NULL, _("history specification"));
+ return (EXECUTION_FAILURE);
+ }
+ else if (histbeg == HIST_ERANGE || histend == HIST_ERANGE)
+ {
+ sh_erange ((char *)NULL, _("history specification"));
+ return (EXECUTION_FAILURE);
+ }
+ else if (histbeg == HIST_NOTFOUND || histend == HIST_NOTFOUND)
+ {
+ builtin_error (_("no command found"));
+ return (EXECUTION_FAILURE);
+ }
+
+ /* We don't throw an error for line specifications out of range, per POSIX */
+ if (histbeg < 0)
+ histbeg = 0;
+ if (histend < 0)
+ histend = 0;
+
/* "When not listing, the fc command that caused the editing shall not be
entered into the history list." */
if (listing == 0 && hist_last_line_added)
@@ -364,14 +393,36 @@ fc_builtin (list)
in parse_and_execute(). */
if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0)
last_hist = histbeg = --histend;
+
+ if (hlist[last_hist] == 0)
+ last_hist--;
+ if (histend >= last_hist)
+ histend = last_hist;
+ else if (histbeg >= last_hist)
+ histbeg = last_hist;
}
- /* We print error messages for line specifications out of range. */
- if ((histbeg < 0) || (histend < 0))
+ if (histbeg == HIST_INVALID || histend == HIST_INVALID)
+ {
+ sh_erange ((char *)NULL, _("history specification"));
+ return (EXECUTION_FAILURE);
+ }
+ else if (histbeg == HIST_ERANGE || histend == HIST_ERANGE)
{
sh_erange ((char *)NULL, _("history specification"));
return (EXECUTION_FAILURE);
}
+ else if (histbeg == HIST_NOTFOUND || histend == HIST_NOTFOUND)
+ {
+ builtin_error (_("no command found"));
+ return (EXECUTION_FAILURE);
+ }
+
+ /* We don't throw an error for line specifications out of range, per POSIX */
+ if (histbeg < 0)
+ histbeg = 0;
+ if (histend < 0)
+ histend = 0;
if (histend < histbeg)
{
@@ -445,7 +496,7 @@ fc_builtin (list)
}
#if defined (READLINE)
- /* If we're executing as part of a dispatched readline commnand like
+ /* If we're executing as part of a dispatched readline command like
{emacs,vi}_edit_and_execute_command, the readline state will indicate it.
We could remove the partial command from the history, but ksh93 doesn't
so we stay compatible. */
@@ -463,7 +514,9 @@ fc_builtin (list)
add_unwind_protect (xfree, fn);
add_unwind_protect (unlink, fn);
add_unwind_protect (set_verbose_flag, (char *)NULL);
+ unwind_protect_int (suppress_debug_trap_verbose);
echo_input_at_read = 1;
+ suppress_debug_trap_verbose = 1;
retval = fc_execute_file (fn);
run_unwind_frame ("fc builtin");
@@ -488,16 +541,21 @@ fc_number (list)
/* Return an absolute index into HLIST which corresponds to COMMAND. If
COMMAND is a number, then it was specified in relative terms. If it
- is a string, then it is the start of a command line present in HLIST. */
+ is a string, then it is the start of a command line present in HLIST.
+ MODE includes HN_LISTING if we are listing commands, and does not if we
+ are executing them. If MODE includes HN_FIRST we are looking for the
+ first history number specification. */
static int
-fc_gethnum (command, hlist)
+fc_gethnum (command, hlist, mode)
char *command;
HIST_ENTRY **hlist;
+ int mode;
{
int sign, n, clen, rh;
- register int i, j, last_hist, real_last;
+ register int i, j, last_hist, real_last, listing;
register char *s;
+ listing = mode & HN_LISTING;
sign = 1;
/* Count history elements. */
for (i = 0; hlist[i]; i++);
@@ -550,19 +608,33 @@ fc_gethnum (command, hlist)
n = atoi (s);
n *= sign;
+ /* We want to return something that is an offset to HISTORY_BASE. */
+
/* If the value is negative or zero, then it is an offset from
the current history item. */
+ /* We don't use HN_FIRST here, so we don't return different values
+ depending on whether we're looking for the first or last in a
+ pair of range arguments, but nobody else does, either. */
if (n < 0)
{
n += i + 1;
return (n < 0 ? 0 : n);
}
else if (n == 0)
- return ((sign == -1) ? real_last : i);
+ return ((sign == -1) ? (listing ? real_last : HIST_INVALID) : i);
else
{
+ /* If we're out of range (greater than I (last history entry) or
+ less than HISTORY_BASE, we want to return different values
+ based on whether or not we are looking for the first or last
+ value in a desired range of history entries. */
n -= history_base;
- return (i < n ? i : n);
+ if (n < 0)
+ return (mode & HN_FIRST ? 0 : i);
+ else if (n >= i)
+ return (mode & HN_FIRST ? 0 : i);
+ else
+ return n;
}
}
@@ -572,22 +644,24 @@ fc_gethnum (command, hlist)
if (STREQN (command, histline (j), clen))
return (j);
}
- return (-1);
+ return (HIST_NOTFOUND);
}
/* Locate the most recent history line which begins with
- COMMAND in HLIST, and return a malloc()'ed copy of it. */
+ COMMAND in HLIST, and return a malloc()'ed copy of it.
+ MODE is 1 if we are listing commands, 0 if we are executing them. */
static char *
-fc_gethist (command, hlist)
+fc_gethist (command, hlist, mode)
char *command;
HIST_ENTRY **hlist;
+ int mode;
{
int i;
if (hlist == 0)
return ((char *)NULL);
- i = fc_gethnum (command, hlist);
+ i = fc_gethnum (command, hlist, mode);
if (i >= 0)
return (savestring (histline (i)));
diff --git a/builtins/fg_bg.def b/builtins/fg_bg.def
index 6a68d6ab..0fb53223 100644
--- a/builtins/fg_bg.def
+++ b/builtins/fg_bg.def
@@ -1,7 +1,7 @@
This file is fg_bg.def, from which is created fg_bg.c.
It implements the builtins "bg" and "fg" in Bash.
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -52,7 +52,7 @@ $END
#include "bashgetopt.h"
#if defined (JOB_CONTROL)
-static int fg_bg __P((WORD_LIST *, int));
+static int fg_bg PARAMS((WORD_LIST *, int));
/* How to bring a job into the foreground. */
int
diff --git a/builtins/gen-helpfiles.c b/builtins/gen-helpfiles.c
index fac34edf..6bed4474 100644
--- a/builtins/gen-helpfiles.c
+++ b/builtins/gen-helpfiles.c
@@ -1,6 +1,6 @@
/* gen-helpfiles - create files containing builtin help text */
-/* Copyright (C) 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2012-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -98,11 +98,11 @@ char *helpfile_directory;
/* Forward declarations. */
-int write_helpfiles __P((struct builtin *));
+int write_helpfiles PARAMS((struct builtin *));
/* For each file mentioned on the command line, process it and
write the information to STRUCTFILE and EXTERNFILE, while
- creating the production file if neccessary. */
+ creating the production file if necessary. */
int
main (argc, argv)
int argc;
diff --git a/builtins/getopt.h b/builtins/getopt.h
index 99096188..fd978597 100644
--- a/builtins/getopt.h
+++ b/builtins/getopt.h
@@ -1,6 +1,6 @@
/* getopt.h - declarations for getopt. */
-/* Copyright (C) 1989, 1990, 1991, 1992, 1993, 2008,2009 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -59,7 +59,7 @@ extern int sh_optopt;
/* Set to 1 when an unrecognized option is encountered. */
extern int sh_badopt;
-extern int sh_getopt __P((int, char *const *, const char *));
+extern int sh_getopt PARAMS((int, char *const *, const char *));
typedef struct sh_getopt_state
{
@@ -71,12 +71,12 @@ typedef struct sh_getopt_state
int gs_flags;
} sh_getopt_state_t;
-extern void sh_getopt_restore_state __P((char **));
+extern void sh_getopt_restore_state PARAMS((char **));
-extern sh_getopt_state_t *sh_getopt_alloc_istate __P((void));
-extern void sh_getopt_dispose_istate __P((sh_getopt_state_t *));
+extern sh_getopt_state_t *sh_getopt_alloc_istate PARAMS((void));
+extern void sh_getopt_dispose_istate PARAMS((sh_getopt_state_t *));
-extern sh_getopt_state_t *sh_getopt_save_istate __P((void));
-extern void sh_getopt_restore_istate __P((sh_getopt_state_t *));
+extern sh_getopt_state_t *sh_getopt_save_istate PARAMS((void));
+extern void sh_getopt_restore_istate PARAMS((sh_getopt_state_t *));
#endif /* _SH_GETOPT_H */
diff --git a/builtins/getopts.def b/builtins/getopts.def
index f473ef01..4c39c474 100644
--- a/builtins/getopts.def
+++ b/builtins/getopts.def
@@ -1,7 +1,7 @@
This file is getopts.def, from which is created getopts.c.
It implements the builtin "getopts" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,7 +22,7 @@ $PRODUCES getopts.c
$BUILTIN getopts
$FUNCTION getopts_builtin
-$SHORT_DOC getopts optstring name [arg]
+$SHORT_DOC getopts optstring name [arg ...]
Parse option arguments.
Getopts is used by shell procedures to parse positional parameters
@@ -54,8 +54,8 @@ If the shell variable OPTERR has the value 0, getopts disables the
printing of error messages, even if the first character of
OPTSTRING is not a colon. OPTERR has the value 1 by default.
-Getopts normally parses the positional parameters ($0 - $9), but if
-more arguments are given, they are parsed instead.
+Getopts normally parses the positional parameters, but if arguments
+are supplied as ARG values, they are parsed instead.
Exit Status:
Returns success if an option is found; fails if the end of options is
@@ -86,9 +86,9 @@ $END
#define G_INVALID_OPT -2
#define G_ARG_MISSING -3
-static int getopts_unbind_variable __P((char *));
-static int getopts_bind_variable __P((char *, char *));
-static int dogetopts __P((int, char **));
+static int getopts_unbind_variable PARAMS((char *));
+static int getopts_bind_variable PARAMS((char *, char *));
+static int dogetopts PARAMS((int, char **));
/* getopts_reset is magic code for when OPTIND is reset. N is the
value that has just been assigned to OPTIND. */
@@ -212,10 +212,7 @@ dogetopts (argc, argv)
register WORD_LIST *words;
char **v;
- for (i = 0; i < 10 && dollar_vars[i]; i++)
- ;
- for (words = rest_of_args; words; words = words->next, i++)
- ;
+ i = number_of_args () + 1; /* +1 for $0 */
v = strvec_create (i + 1);
for (i = 0; i < 10 && dollar_vars[i]; i++)
v[i] = dollar_vars[i];
diff --git a/builtins/hash.def b/builtins/hash.def
index b3039308..c58e91c4 100644
--- a/builtins/hash.def
+++ b/builtins/hash.def
@@ -1,7 +1,7 @@
This file is hash.def, from which is created hash.c.
It implements the builtin "hash" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -70,11 +70,11 @@ $END
extern int dot_found_in_search;
-static int add_hashed_command __P((char *, int));
-static int print_hash_info __P((BUCKET_CONTENTS *));
-static int print_portable_hash_info __P((BUCKET_CONTENTS *));
-static int print_hashed_commands __P((int));
-static int list_hashed_filename_targets __P((WORD_LIST *, int));
+static int add_hashed_command PARAMS((char *, int));
+static int print_hash_info PARAMS((BUCKET_CONTENTS *));
+static int print_portable_hash_info PARAMS((BUCKET_CONTENTS *));
+static int print_hashed_commands PARAMS((int));
+static int list_hashed_filename_targets PARAMS((WORD_LIST *, int));
/* Print statistics on the current state of hashed commands. If LIST is
not empty, then rehash (or hash in the first place) the specified
@@ -123,9 +123,9 @@ hash_builtin (list)
list = loptend;
/* hash -t requires at least one argument. */
- if (list == 0 && list_targets)
+ if (list == 0 && (delete || list_targets))
{
- sh_needarg ("-t");
+ sh_needarg (delete ? "-d" : "-t");
return (EXECUTION_FAILURE);
}
@@ -134,7 +134,8 @@ hash_builtin (list)
if (list == 0 && expunge_hash_table == 0)
{
opt = print_hashed_commands (list_portably);
- if (opt == 0 && posixly_correct == 0)
+ if (opt == 0 && posixly_correct == 0 &&
+ (list_portably == 0 || shell_compatibility_level <= 50))
printf (_("%s: hash table empty\n"), this_command_name);
return (EXECUTION_SUCCESS);
diff --git a/builtins/help.def b/builtins/help.def
index 006c4b5d..f33b2b93 100644
--- a/builtins/help.def
+++ b/builtins/help.def
@@ -1,7 +1,7 @@
This file is help.def, from which is created help.c.
It implements the builtin "help" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -79,11 +79,11 @@ extern int errno;
extern const char * const bash_copyright;
extern const char * const bash_license;
-static void show_builtin_command_help __P((void));
-static int open_helpfile __P((char *));
-static void show_desc __P((char *, int));
-static void show_manpage __P((char *, int));
-static void show_longdoc __P((int));
+static void show_builtin_command_help PARAMS((void));
+static int open_helpfile PARAMS((char *));
+static void show_desc PARAMS((char *, int));
+static void show_manpage PARAMS((char *, int));
+static void show_longdoc PARAMS((int));
/* Print out a list of the known functions in the shell, and what they do.
If LIST is supplied, print out the list which matches for each pattern
@@ -128,11 +128,11 @@ help_builtin (list)
/* We should consider making `help bash' do something. */
- if (glob_pattern_p (list->word->word))
+ if (glob_pattern_p (list->word->word) == 1)
{
printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
print_word_list (list, ", ");
- printf ("'\n\n");
+ printf ("%s", _("'\n\n"));
}
for (match_found = 0, pattern = ""; list; list = list->next)
diff --git a/builtins/history.def b/builtins/history.def
index 77093a45..5db44c2c 100644
--- a/builtins/history.def
+++ b/builtins/history.def
@@ -1,7 +1,7 @@
This file is history.def, from which is created history.c.
It implements the builtin "history" in Bash.
-Copyright (C) 1987-2018 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -75,6 +75,7 @@ $END
#include "../bashintl.h"
#include "../shell.h"
+#include "../flags.h"
#include "../parser.h"
#include "../bashhist.h"
#include <readline/history.h>
@@ -85,10 +86,10 @@ $END
extern int errno;
#endif
-static char *histtime __P((HIST_ENTRY *, const char *));
-static int display_history __P((WORD_LIST *));
-static void push_history __P((WORD_LIST *));
-static int expand_and_print_history __P((WORD_LIST *));
+static char *histtime PARAMS((HIST_ENTRY *, const char *));
+static int display_history PARAMS((WORD_LIST *));
+static void push_history PARAMS((WORD_LIST *));
+static int expand_and_print_history PARAMS((WORD_LIST *));
#define AFLAG 0x01
#define RFLAG 0x02
@@ -243,7 +244,7 @@ range_error:
}
opt = ind + history_base; /* compensate for opt - history_base below */
}
- else if ((delete_offset < history_base) || (delete_offset > (history_base + history_length)))
+ else if ((delete_offset < history_base) || (delete_offset >= (history_base + history_length)))
{
sh_erange (delete_arg, _("history position"));
return (EXECUTION_FAILURE);
@@ -269,6 +270,14 @@ range_error:
filename = list ? list->word->word : get_string_value ("HISTFILE");
result = EXECUTION_SUCCESS;
+#if defined (RESTRICTED_SHELL)
+ if (restricted && strchr (filename, '/'))
+ {
+ sh_restricted (filename);
+ return (EXECUTION_FAILURE);
+ }
+#endif
+
if (flags & AFLAG) /* Append session's history to file. */
result = maybe_append_history (filename);
else if (flags & WFLAG) /* Write entire history. */
diff --git a/builtins/jobs.def b/builtins/jobs.def
index be1a7d8f..1ce098d0 100644
--- a/builtins/jobs.def
+++ b/builtins/jobs.def
@@ -1,7 +1,7 @@
This file is jobs.def, from which is created jobs.c.
It implements the builtins "jobs" and "disown" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -68,7 +68,7 @@ $END
#define JSTATE_RUNNING 0x1
#define JSTATE_STOPPED 0x2
-static int execute_list_with_replacements __P((WORD_LIST *));
+static int execute_list_with_replacements PARAMS((WORD_LIST *));
/* The `jobs' command. Prints outs a list of active jobs. If the
argument `-l' is given, then the process id's are printed also.
@@ -276,7 +276,7 @@ disown_builtin (list)
{
BLOCK_CHILD (set, oset);
job = (list && legal_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value)
- ? get_job_by_pid ((pid_t) pid_value, 0)
+ ? get_job_by_pid ((pid_t) pid_value, 0, 0)
: get_job_spec (list);
if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
diff --git a/builtins/kill.def b/builtins/kill.def
index 8d6e3ed1..c655092e 100644
--- a/builtins/kill.def
+++ b/builtins/kill.def
@@ -1,7 +1,7 @@
This file is kill.def, from which is created kill.c.
It implements the builtin "kill" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -70,7 +70,7 @@ $END
extern int errno;
#endif /* !errno */
-static void kill_error __P((pid_t, int));
+static void kill_error PARAMS((pid_t, int));
#if !defined (CONTINUE_AFTER_KILL_ERROR)
# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
diff --git a/builtins/mapfile.def b/builtins/mapfile.def
index 995d34ac..65c3cb4f 100644
--- a/builtins/mapfile.def
+++ b/builtins/mapfile.def
@@ -2,7 +2,7 @@ This file is mapfile.def, from which is created mapfile.c.
It implements the builtin "mapfile" in Bash.
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
-Copyright (C) 2008-2016 Free Software Foundation, Inc.
+Copyright (C) 2008-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -91,7 +91,7 @@ extern int errno;
#if defined (ARRAY_VARS)
-static int run_callback __P((const char *, unsigned int, const char *));
+static int run_callback PARAMS((const char *, unsigned int, const char *));
#define DEFAULT_ARRAY_NAME "MAPFILE"
#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
index 4f512010..e243021f 100644
--- a/builtins/mkbuiltins.c
+++ b/builtins/mkbuiltins.c
@@ -1,7 +1,7 @@
/* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
a single source file called builtins.def. */
-/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -439,7 +439,7 @@ array_free (array)
/* The definition of a function. */
typedef int Function ();
-typedef int mk_handler_func_t __P((char *, DEF_FILE *, char *));
+typedef int mk_handler_func_t PARAMS((char *, DEF_FILE *, char *));
/* Structure handles processor directives. */
typedef struct {
@@ -447,14 +447,14 @@ typedef struct {
mk_handler_func_t *function;
} HANDLER_ENTRY;
-extern int builtin_handler __P((char *, DEF_FILE *, char *));
-extern int function_handler __P((char *, DEF_FILE *, char *));
-extern int short_doc_handler __P((char *, DEF_FILE *, char *));
-extern int comment_handler __P((char *, DEF_FILE *, char *));
-extern int depends_on_handler __P((char *, DEF_FILE *, char *));
-extern int produces_handler __P((char *, DEF_FILE *, char *));
-extern int end_handler __P((char *, DEF_FILE *, char *));
-extern int docname_handler __P((char *, DEF_FILE *, char *));
+extern int builtin_handler PARAMS((char *, DEF_FILE *, char *));
+extern int function_handler PARAMS((char *, DEF_FILE *, char *));
+extern int short_doc_handler PARAMS((char *, DEF_FILE *, char *));
+extern int comment_handler PARAMS((char *, DEF_FILE *, char *));
+extern int depends_on_handler PARAMS((char *, DEF_FILE *, char *));
+extern int produces_handler PARAMS((char *, DEF_FILE *, char *));
+extern int end_handler PARAMS((char *, DEF_FILE *, char *));
+extern int docname_handler PARAMS((char *, DEF_FILE *, char *));
HANDLER_ENTRY handlers[] = {
{ "BUILTIN", builtin_handler },
@@ -1233,7 +1233,7 @@ write_builtins (defs, structfile, externfile)
if (externfile)
{
if (builtin->function)
- fprintf (externfile, "extern int %s __P((WORD_LIST *));\n",
+ fprintf (externfile, "extern int %s PARAMS((WORD_LIST *));\n",
builtin->function);
fprintf (externfile, "extern char * const %s_doc[];\n",
diff --git a/builtins/printf.def b/builtins/printf.def
index bc6ef57d..0a5f4897 100644
--- a/builtins/printf.def
+++ b/builtins/printf.def
@@ -1,7 +1,7 @@
This file is printf.def, from which is created printf.c.
It implements the builtin "printf" in Bash.
-Copyright (C) 1997-2017 Free Software Foundation, Inc.
+Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -149,7 +149,7 @@ extern int errno;
if (vflag) \
{ \
SHELL_VAR *v; \
- v = bind_printf_variable (vname, vbuf, 0); \
+ v = builtin_bind_variable (vname, vbuf, 0); \
stupidly_hack_special_variables (vname); \
if (v == 0 || readonly_p (v) || noassign_p (v)) \
return (EXECUTION_FAILURE); \
@@ -187,26 +187,25 @@ extern int errno;
extern time_t shell_start_time;
#if !HAVE_ASPRINTF
-extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
+extern int asprintf PARAMS((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
#endif
#if !HAVE_VSNPRINTF
-extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0)));
+extern int vsnprintf PARAMS((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0)));
#endif
-static void printf_erange __P((char *));
-static int printstr __P((char *, char *, int, int, int));
-static int tescape __P((char *, char *, int *, int *));
-static char *bexpand __P((char *, int, int *, int *));
-static char *vbadd __P((char *, int));
-static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
-static char *mklong __P((char *, char *, size_t));
-static int getchr __P((void));
-static char *getstr __P((void));
-static int getint __P((void));
-static intmax_t getintmax __P((void));
-static uintmax_t getuintmax __P((void));
-static SHELL_VAR *bind_printf_variable __P((char *, char *, int));
+static void printf_erange PARAMS((char *));
+static int printstr PARAMS((char *, char *, int, int, int));
+static int tescape PARAMS((char *, char *, int *, int *));
+static char *bexpand PARAMS((char *, int, int *, int *));
+static char *vbadd PARAMS((char *, int));
+static int vbprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
+static char *mklong PARAMS((char *, char *, size_t));
+static int getchr PARAMS((void));
+static char *getstr PARAMS((void));
+static int getint PARAMS((void));
+static intmax_t getintmax PARAMS((void));
+static uintmax_t getuintmax PARAMS((void));
#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
typedef long double floatmax_t;
@@ -217,11 +216,11 @@ typedef double floatmax_t;
# define FLOATMAX_CONV ""
# define strtofltmax strtod
#endif
-static floatmax_t getfloatmax __P((void));
+static floatmax_t getfloatmax PARAMS((void));
-static intmax_t asciicode __P((void));
+static intmax_t asciicode PARAMS((void));
-static WORD_LIST *garglist;
+static WORD_LIST *garglist, *orig_arglist;
static int retval;
static int conversion_error;
@@ -301,7 +300,7 @@ printf_builtin (list)
if (vflag && list->word->word && list->word->word[0] == '\0')
{
SHELL_VAR *v;
- v = bind_printf_variable (vname, "", 0);
+ v = builtin_bind_variable (vname, "", 0);
stupidly_hack_special_variables (vname);
return ((v == 0 || readonly_p (v) || noassign_p (v)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
@@ -312,7 +311,7 @@ printf_builtin (list)
format = list->word->word;
tw = 0;
- garglist = list->next;
+ garglist = orig_arglist = list->next;
/* If the format string is empty after preprocessing, return immediately. */
if (format == 0 || *format == 0)
@@ -1271,26 +1270,3 @@ asciicode ()
garglist = garglist->next;
return (ch);
}
-
-static SHELL_VAR *
-bind_printf_variable (name, value, flags)
- char *name;
- char *value;
- int flags;
-{
- SHELL_VAR *v;
-
-#if defined (ARRAY_VARS)
- if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
- v = bind_variable (name, value, flags);
- else
- v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0));
-#else /* !ARRAY_VARS */
- v = bind_variable (name, value, flags);
-#endif /* !ARRAY_VARS */
-
- if (v && readonly_p (v) == 0 && noassign_p (v) == 0)
- VUNSETATTR (v, att_invisible);
-
- return v;
-}
diff --git a/builtins/pushd.def b/builtins/pushd.def
index 71e04097..829f827d 100644
--- a/builtins/pushd.def
+++ b/builtins/pushd.def
@@ -1,7 +1,7 @@
This file is pushd.def, from which is created pushd.c. It implements the
builtins "pushd", "popd", and "dirs" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -157,12 +157,12 @@ static int directory_list_size;
/* Offset to the end of the list. */
static int directory_list_offset;
-static void pushd_error __P((int, char *));
-static void clear_directory_stack __P((void));
-static int cd_to_string __P((char *));
-static int change_to_temp __P((char *));
-static void add_dirstack_element __P((char *));
-static int get_dirstack_index __P((intmax_t, int, int *));
+static void pushd_error PARAMS((int, char *));
+static void clear_directory_stack PARAMS((void));
+static int cd_to_string PARAMS((char *));
+static int change_to_temp PARAMS((char *));
+static void add_dirstack_element PARAMS((char *));
+static int get_dirstack_index PARAMS((intmax_t, int, int *));
#define NOCD 0x01
#define ROTATE 0x02
diff --git a/builtins/read.def b/builtins/read.def
index b57c8c39..39e16e84 100644
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -1,7 +1,7 @@
This file is read.def, from which is created read.c.
It implements the builtin "read" in Bash.
-Copyright (C) 1987-2017 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -119,20 +119,20 @@ struct ttsave
};
#if defined (READLINE)
-static void reset_attempted_completion_function __P((char *));
-static int set_itext __P((void));
-static char *edit_line __P((char *, char *));
-static void set_eol_delim __P((int));
-static void reset_eol_delim __P((char *));
+static void reset_attempted_completion_function PARAMS((char *));
+static int set_itext PARAMS((void));
+static char *edit_line PARAMS((char *, char *));
+static void set_eol_delim PARAMS((int));
+static void reset_eol_delim PARAMS((char *));
#endif
-static SHELL_VAR *bind_read_variable __P((char *, char *));
+static SHELL_VAR *bind_read_variable PARAMS((char *, char *));
#if defined (HANDLE_MULTIBYTE)
-static int read_mbchar __P((int, char *, int, int, int));
+static int read_mbchar PARAMS((int, char *, int, int, int));
#endif
-static void ttyrestore __P((struct ttsave *));
+static void ttyrestore PARAMS((struct ttsave *));
-static sighandler sigalrm __P((int));
-static void reset_alarm __P((void));
+static sighandler sigalrm PARAMS((int));
+static void reset_alarm PARAMS((void));
/* Try this to see what the rest of the shell can do with the information. */
procenv_t alrmbuf;
@@ -198,6 +198,7 @@ read_builtin (list)
#if defined (READLINE)
char *rlbuf, *itext;
int rlind;
+ FILE *save_instream;
#endif
USE_VAR(size);
@@ -273,7 +274,7 @@ read_builtin (list)
break;
#endif
case 't':
- code = uconvert (list_optarg, &ival, &uval);
+ code = uconvert (list_optarg, &ival, &uval, (char **)NULL);
if (code == 0 || ival < 0 || uval < 0)
{
builtin_error (_("%s: invalid timeout specification"), list_optarg);
@@ -376,7 +377,7 @@ read_builtin (list)
/* $TMOUT, if set, is the default timeout for read. */
if (have_timeout == 0 && (e = get_string_value ("TMOUT")))
{
- code = uconvert (e, &ival, &uval);
+ code = uconvert (e, &ival, &uval, (char **)NULL);
if (code == 0 || ival < 0 || uval < 0)
tmsec = tmusec = 0;
else
@@ -527,6 +528,19 @@ read_builtin (list)
initialize_terminating_signals ();
}
+#if defined (READLINE)
+ save_instream = 0;
+ if (edit && fd != 0)
+ {
+ if (bash_readline_initialized == 0)
+ initialize_readline ();
+
+ unwind_protect_var (rl_instream);
+ save_instream = rl_instream;
+ rl_instream = fdopen (fd, "r");
+ }
+#endif
+
/* This *must* be the top unwind-protect on the stack, so the manipulation
of the unwind-protect stack after the realloc() works right. */
add_unwind_protect (xfree, input_string);
@@ -555,7 +569,8 @@ read_builtin (list)
#if defined (READLINE)
if (edit)
{
- if (rlbuf && rlbuf[rlind] == '\0')
+ /* If we have a null delimiter, don't treat NULL as ending the line */
+ if (rlbuf && rlbuf[rlind] == '\0' && delim != '\0')
{
free (rlbuf);
rlbuf = (char *)0;
@@ -589,6 +604,7 @@ read_builtin (list)
reading = 1;
CHECK_ALRM;
+ errno = 0;
if (unbuffered_read == 2)
retval = posixly_correct ? zreadintr (fd, &c, 1) : zreadn (fd, &c, nchars - nr);
else if (unbuffered_read)
@@ -599,13 +615,18 @@ read_builtin (list)
if (retval <= 0)
{
+ int t;
+
+ t = errno;
if (retval < 0 && errno == EINTR)
{
check_signals (); /* in case we didn't call zread via zreadc */
lastsig = LASTSIG();
if (lastsig == 0)
lastsig = trapped_signal_received;
+#if 0
run_pending_traps (); /* because interrupt_immediately is not set */
+#endif
}
else
lastsig = 0;
@@ -613,6 +634,7 @@ read_builtin (list)
ttyrestore (&termsave); /* fix terminal before exiting */
CHECK_TERMSIG;
eof = 1;
+ errno = t; /* preserve it for the error message below */
break;
}
@@ -759,6 +781,11 @@ add_char:
if (unbuffered_read == 0)
zsyncfd (fd);
+#if defined (READLINE)
+ if (save_instream)
+ rl_instream = save_instream; /* can't portably free it */
+#endif
+
discard_unwind_frame ("read_builtin");
retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
@@ -966,14 +993,7 @@ bind_read_variable (name, value)
{
SHELL_VAR *v;
-#if defined (ARRAY_VARS)
- if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
- v = bind_variable (name, value, 0);
- else
- v = assign_array_element (name, value, assoc_expand_once ? ASS_NOEXPAND : 0);
-#else /* !ARRAY_VARS */
- v = bind_variable (name, value, 0);
-#endif /* !ARRAY_VARS */
+ v = builtin_bind_variable (name, value, 0);
return (v == 0 ? v
: ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v));
}
@@ -1136,15 +1156,17 @@ set_eol_delim (c)
initialize_readline ();
cmap = rl_get_keymap ();
- /* Change newline to self-insert */
+ /* Save the old delimiter char binding */
old_newline_ctype = cmap[RETURN].type;
old_newline_func = cmap[RETURN].function;
+ old_delim_ctype = cmap[c].type;
+ old_delim_func = cmap[c].function;
+
+ /* Change newline to self-insert */
cmap[RETURN].type = ISFUNC;
cmap[RETURN].function = rl_insert;
/* Bind the delimiter character to accept-line. */
- old_delim_ctype = cmap[c].type;
- old_delim_func = cmap[c].function;
cmap[c].type = ISFUNC;
cmap[c].function = rl_newline;
diff --git a/builtins/reserved.def b/builtins/reserved.def
index 7f3c236b..33184b02 100644
--- a/builtins/reserved.def
+++ b/builtins/reserved.def
@@ -2,7 +2,7 @@ This file is reserved.def, in which the shell reserved words are defined.
It has no direct C file production, but defines builtins for the Bash
builtin help command.
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -194,7 +194,7 @@ $SHORT_DOC (( expression ))
Evaluate arithmetic expression.
The EXPRESSION is evaluated according to the rules for arithmetic
-evaluation. Equivalent to "let EXPRESSION".
+evaluation. Equivalent to `let "EXPRESSION"'.
Exit Status:
Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise.
diff --git a/builtins/return.def b/builtins/return.def
index 77e8d7c7..03c98eb1 100644
--- a/builtins/return.def
+++ b/builtins/return.def
@@ -66,6 +66,6 @@ return_builtin (list)
else
{
builtin_error (_("can only `return' from a function or sourced script"));
- return (EXECUTION_FAILURE);
+ return (EX_USAGE);
}
}
diff --git a/builtins/set.def b/builtins/set.def
index d2bba434..8ee01657 100644
--- a/builtins/set.def
+++ b/builtins/set.def
@@ -1,7 +1,7 @@
This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
-Copyright (C) 1987-2018 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -151,24 +151,24 @@ Exit Status:
Returns success unless an invalid option is given.
$END
-typedef int setopt_set_func_t __P((int, char *));
-typedef int setopt_get_func_t __P((char *));
+typedef int setopt_set_func_t PARAMS((int, char *));
+typedef int setopt_get_func_t PARAMS((char *));
-static int find_minus_o_option __P((char *));
+static int find_minus_o_option PARAMS((char *));
-static void print_minus_o_option __P((char *, int, int));
-static void print_all_shell_variables __P((void));
+static void print_minus_o_option PARAMS((char *, int, int));
+static void print_all_shell_variables PARAMS((void));
-static int set_ignoreeof __P((int, char *));
-static int set_posix_mode __P((int, char *));
+static int set_ignoreeof PARAMS((int, char *));
+static int set_posix_mode PARAMS((int, char *));
#if defined (READLINE)
-static int set_edit_mode __P((int, char *));
-static int get_edit_mode __P((char *));
+static int set_edit_mode PARAMS((int, char *));
+static int get_edit_mode PARAMS((char *));
#endif
#if defined (HISTORY)
-static int bash_set_history __P((int, char *));
+static int bash_set_history PARAMS((int, char *));
#endif
static const char * const on = "on";
@@ -358,17 +358,29 @@ void
set_current_options (bitmap)
const char *bitmap;
{
- int i;
+ int i, v, cv, *on_or_off;
if (bitmap == 0)
return;
for (i = 0; o_options[i].name; i++)
{
+ v = bitmap[i] ? FLAG_ON : FLAG_OFF;
if (o_options[i].letter)
- change_flag (o_options[i].letter, bitmap[i] ? FLAG_ON : FLAG_OFF);
+ {
+ /* We should not get FLAG_UNKNOWN here */
+ on_or_off = find_flag (o_options[i].letter);
+ cv = *on_or_off ? FLAG_ON : FLAG_OFF;
+ if (v != cv)
+ change_flag (o_options[i].letter, v);
+ }
else
- SET_BINARY_O_OPTION_VALUE (i, bitmap[i] ? FLAG_ON : FLAG_OFF, o_options[i].name);
+ {
+ cv = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
+ cv = cv ? FLAG_ON : FLAG_OFF;
+ if (v != cv)
+ SET_BINARY_O_OPTION_VALUE (i, v, o_options[i].name);
+ }
}
/* Now reset the variables changed by posix mode */
@@ -395,6 +407,11 @@ set_posix_mode (on_or_off, option_name)
int on_or_off;
char *option_name;
{
+ /* short-circuit on no-op */
+ if ((on_or_off == FLAG_ON && posixly_correct) ||
+ (on_or_off == FLAG_OFF && posixly_correct == 0))
+ return 0;
+
posixly_correct = on_or_off == FLAG_ON;
if (posixly_correct == 0)
unbind_variable_noref ("POSIXLY_CORRECT");
@@ -646,7 +663,7 @@ reset_shell_options ()
#endif
#if defined (HISTORY)
dont_save_function_defs = 0;
- remember_on_history = enable_history_list = 1;
+ remember_on_history = enable_history_list = 1; /* XXX */
#endif
}
@@ -818,7 +835,7 @@ unset_builtin (list)
WORD_LIST *list;
{
int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
- int global_unset_func, global_unset_var, vflags;
+ int global_unset_func, global_unset_var, vflags, valid_id;
char *name, *tname;
unset_function = unset_variable = unset_array = nameref = any_failed = 0;
@@ -884,17 +901,28 @@ unset_builtin (list)
#endif
/* Get error checking out of the way first. The low-level functions
just perform the unset, relying on the caller to verify. */
+ valid_id = legal_identifier (name);
+
+ /* Whether or not we are in posix mode, if neither -f nor -v appears,
+ skip over trying to unset variables with invalid names and just
+ treat them as potential shell function names. */
+ if (global_unset_func == 0 && global_unset_var == 0 && valid_id == 0)
+ {
+ unset_variable = unset_array = 0;
+ unset_function = 1;
+ }
/* Bash allows functions with names which are not valid identifiers
to be created when not in posix mode, so check only when in posix
mode when unsetting a function. */
- if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
+ if (unset_function == 0 && valid_id == 0)
{
sh_invalidid (name);
NEXT_VARIABLE ();
}
- /* Only search for functions here if -f supplied. */
+ /* Search for functions here if -f supplied or if NAME cannot be a
+ variable name. */
var = unset_function ? find_function (name)
: (nameref ? find_variable_last_nameref (name, 0) : find_variable (name));
diff --git a/builtins/setattr.def b/builtins/setattr.def
index 251bcacb..a193462d 100644
--- a/builtins/setattr.def
+++ b/builtins/setattr.def
@@ -1,7 +1,7 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -42,7 +42,7 @@ $PRODUCES setattr.c
extern sh_builtin_func_t *this_shell_builtin;
#ifdef ARRAY_VARS
-extern int declare_builtin __P((WORD_LIST *));
+extern int declare_builtin PARAMS((WORD_LIST *));
#endif
#define READONLY_OR_EXPORT \
@@ -371,6 +371,30 @@ show_all_var_attributes (v, nodefs)
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
+/* Show all local variable variables with their attributes. This shows unset
+ local variables (all_local_variables called with 0 argment). */
+int
+show_local_var_attributes (v, nodefs)
+ int v, nodefs;
+{
+ SHELL_VAR **variable_list, *var;
+ int any_failed;
+ register int i;
+
+ variable_list = all_local_variables (0);
+ if (variable_list == 0)
+ return (EXECUTION_SUCCESS);
+
+ for (i = any_failed = 0; var = variable_list[i]; i++)
+ {
+ show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
+ if (any_failed = sh_chkwrite (any_failed))
+ break;
+ }
+ free (variable_list);
+ return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
+}
+
int
var_attribute_string (var, pattr, flags)
SHELL_VAR *var;
@@ -504,13 +528,27 @@ show_name_attributes (name, nodefs)
{
SHELL_VAR *var;
-#if 0
- var = find_variable_tempenv (name);
-#else
var = find_variable_noref (name);
-#endif
- if (var /* && invisible_p (var) == 0 */)
+ if (var) /* show every variable with attributes, even unset ones */
+ {
+ show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
+ return (0);
+ }
+ else
+ return (1);
+}
+
+int
+show_localname_attributes (name, nodefs)
+ char *name;
+ int nodefs;
+{
+ SHELL_VAR *var;
+
+ var = find_variable_noref (name);
+
+ if (var && local_p (var) && var->context == variable_context) /* show every variable with attributes, even unset ones */
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
@@ -607,7 +645,7 @@ set_var_attribute (name, attribute, undo)
if (var == 0)
{
var = bind_variable (name, (char *)NULL, 0);
- if (var && no_invisible_vars == 0)
+ if (var)
VSETATTR (var, att_invisible);
}
else if (var->context != 0)
diff --git a/builtins/shift.def b/builtins/shift.def
index 589e3299..bb9af01b 100644
--- a/builtins/shift.def
+++ b/builtins/shift.def
@@ -1,7 +1,7 @@
This file is shift.def, from which is created shift.c.
It implements the builtin "shift" in Bash.
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -58,8 +58,7 @@ shift_builtin (list)
WORD_LIST *list;
{
intmax_t times;
- register int count;
- WORD_LIST *temp;
+ int itimes, nargs;
CHECK_HELPOPT (list);
@@ -73,32 +72,17 @@ shift_builtin (list)
sh_erange (list ? list->word->word : NULL, _("shift count"));
return (EXECUTION_FAILURE);
}
- else if (times > number_of_args ())
+ nargs = number_of_args ();
+ if (times > nargs)
{
if (print_shift_error)
sh_erange (list ? list->word->word : NULL, _("shift count"));
return (EXECUTION_FAILURE);
}
-
- while (times-- > 0)
- {
- if (dollar_vars[1])
- free (dollar_vars[1]);
-
- for (count = 1; count < 9; count++)
- dollar_vars[count] = dollar_vars[count + 1];
-
- if (rest_of_args)
- {
- temp = rest_of_args;
- dollar_vars[9] = savestring (temp->word->word);
- rest_of_args = rest_of_args->next;
- temp->next = (WORD_LIST *)NULL;
- dispose_words (temp);
- }
- else
- dollar_vars[9] = (char *)NULL;
- }
+ else if (times == nargs)
+ clear_dollar_vars ();
+ else
+ shift_args (itimes = times);
invalidate_cached_quoted_dollar_at ();
diff --git a/builtins/shopt.def b/builtins/shopt.def
index 1c485361..6dca2242 100644
--- a/builtins/shopt.def
+++ b/builtins/shopt.def
@@ -1,7 +1,7 @@
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
-Copyright (C) 1994-2018 Free Software Foundation, Inc.
+Copyright (C) 1994-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -105,7 +105,7 @@ extern int force_fignore;
extern int dircomplete_spelling, dircomplete_expand;
extern int complete_fullquote;
-extern int enable_hostname_completion __P((int));
+extern int enable_hostname_completion PARAMS((int));
#endif
#if defined (PROGRAMMABLE_COMPLETION)
@@ -126,21 +126,21 @@ extern int array_expand_once;
extern int syslog_history;
#endif
-static void shopt_error __P((char *));
+static void shopt_error PARAMS((char *));
-static int set_shellopts_after_change __P((char *, int));
-static int set_compatibility_level __P((char *, int));
+static int set_shellopts_after_change PARAMS((char *, int));
+static int set_compatibility_level PARAMS((char *, int));
#if defined (RESTRICTED_SHELL)
-static int set_restricted_shell __P((char *, int));
+static int set_restricted_shell PARAMS((char *, int));
#endif
#if defined (READLINE)
-static int shopt_enable_hostname_completion __P((char *, int));
-static int shopt_set_complete_direxpand __P((char *, int));
+static int shopt_enable_hostname_completion PARAMS((char *, int));
+static int shopt_set_complete_direxpand PARAMS((char *, int));
#endif
-static int shopt_set_debug_mode __P((char *, int));
+static int shopt_set_debug_mode PARAMS((char *, int));
static int shopt_login_shell;
static int shopt_compat31;
@@ -151,7 +151,7 @@ static int shopt_compat42;
static int shopt_compat43;
static int shopt_compat44;
-typedef int shopt_set_func_t __P((char *, int));
+typedef int shopt_set_func_t PARAMS((char *, int));
/* If you add a new variable name here, make sure to set the default value
appropriately in reset_shopt_options. */
@@ -255,14 +255,14 @@ static struct {
static const char * const on = "on";
static const char * const off = "off";
-static int find_shopt __P((char *));
-static int toggle_shopts __P((int, WORD_LIST *, int));
-static void print_shopt __P((char *, int, int));
-static int list_shopts __P((WORD_LIST *, int));
-static int list_some_shopts __P((int, int));
-static int list_shopt_o_options __P((WORD_LIST *, int));
-static int list_some_o_options __P((int, int));
-static int set_shopt_o_options __P((int, WORD_LIST *, int));
+static int find_shopt PARAMS((char *));
+static int toggle_shopts PARAMS((int, WORD_LIST *, int));
+static void print_shopt PARAMS((char *, int, int));
+static int list_shopts PARAMS((WORD_LIST *, int));
+static int list_some_shopts PARAMS((int, int));
+static int list_shopt_o_options PARAMS((WORD_LIST *, int));
+static int list_some_o_options PARAMS((int, int));
+static int set_shopt_o_options PARAMS((int, WORD_LIST *, int));
#define SFLAG 0x01
#define UFLAG 0x02
@@ -347,6 +347,7 @@ reset_shopt_options ()
inherit_errexit = 0;
interactive_comments = 1;
lastpipe_opt = 0;
+ localvar_inherit = localvar_unset = 0;
mail_warning = 0;
glob_ignore_case = match_ignore_case = 0;
print_shift_error = 0;
@@ -360,6 +361,10 @@ reset_shopt_options ()
extended_glob = EXTGLOB_DEFAULT;
#endif
+#if defined (ARRAY_VARS)
+ assoc_expand_once = 0;
+#endif
+
#if defined (HISTORY)
literal_history = 0;
force_append_history = 0;
@@ -390,6 +395,9 @@ reset_shopt_options ()
#if defined (PROGRAMMABLE_COMPLETION)
prog_completion_enabled = 1;
+# if defined (ALIAS)
+ progcomp_alias = 0;
+# endif
#endif
#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
diff --git a/builtins/source.def b/builtins/source.def
index bdd197fd..5b2f994d 100644
--- a/builtins/source.def
+++ b/builtins/source.def
@@ -1,7 +1,7 @@
This file is source.def, from which is created source.c.
It implements the builtins "." and "source" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -80,7 +80,7 @@ $END
extern int errno;
#endif /* !errno */
-static void maybe_pop_dollar_vars __P((void));
+static void maybe_pop_dollar_vars PARAMS((void));
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
int source_uses_path = 1;
@@ -156,7 +156,7 @@ source_builtin (list)
free (x);
if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
{
- last_command_exit_value = 1;
+ last_command_exit_value = EXECUTION_FAILURE;
jump_to_top_level (EXITPROG);
}
return (EXECUTION_FAILURE);
diff --git a/builtins/suspend.def b/builtins/suspend.def
index db28feec..e99fd26b 100644
--- a/builtins/suspend.def
+++ b/builtins/suspend.def
@@ -1,7 +1,7 @@
This file is suspend.def, from which is created suspend.c.
It implements the builtin "suspend" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -54,7 +54,7 @@ $END
#include "common.h"
#include "bashgetopt.h"
-static sighandler suspend_continue __P((int));
+static sighandler suspend_continue PARAMS((int));
static SigHandler *old_cont;
#if 0
diff --git a/builtins/trap.def b/builtins/trap.def
index 09846981..daeec9ea 100644
--- a/builtins/trap.def
+++ b/builtins/trap.def
@@ -1,7 +1,7 @@
This file is trap.def, from which is created trap.c.
It implements the builtin "trap" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -75,8 +75,8 @@ $END
#include "common.h"
#include "bashgetopt.h"
-static void showtrap __P((int));
-static int display_traps __P((WORD_LIST *));
+static void showtrap PARAMS((int, int));
+static int display_traps PARAMS((WORD_LIST *, int));
/* The trap command:
@@ -133,7 +133,7 @@ trap_builtin (list)
{
initialize_terminating_signals ();
get_all_original_signals ();
- return (sh_chkwrite (display_traps (list)));
+ return (sh_chkwrite (display_traps (list, display && posixly_correct)));
}
else
{
@@ -211,7 +211,7 @@ trap_builtin (list)
if (interactive)
set_signal_handler (SIGINT, sigint_sighandler);
/* special cases for interactive == 0 */
- else if (interactive_shell && (sourcelevel||running_trap))
+ else if (interactive_shell && (sourcelevel||running_trap||parse_and_execute_level))
set_signal_handler (SIGINT, sigint_sighandler);
else
set_signal_handler (SIGINT, termsig_sighandler);
@@ -246,14 +246,19 @@ trap_builtin (list)
}
static void
-showtrap (i)
- int i;
+showtrap (i, show_default)
+ int i, show_default;
{
char *t, *p, *sn;
p = trap_list[i];
if (p == (char *)DEFAULT_SIG && signal_is_hard_ignored (i) == 0)
- return;
+ {
+ if (show_default)
+ t = "-";
+ else
+ return;
+ }
else if (signal_is_hard_ignored (i))
t = (char *)NULL;
else
@@ -274,19 +279,21 @@ showtrap (i)
else
printf ("trap -- %s %s\n", t ? t : "''", sn);
- FREE (t);
+ if (show_default == 0)
+ FREE (t);
}
static int
-display_traps (list)
+display_traps (list, show_all)
WORD_LIST *list;
+ int show_all;
{
int result, i;
if (list == 0)
{
for (i = 0; i < BASH_NSIG; i++)
- showtrap (i);
+ showtrap (i, show_all);
return (EXECUTION_SUCCESS);
}
@@ -299,7 +306,7 @@ display_traps (list)
result = EXECUTION_FAILURE;
}
else
- showtrap (i);
+ showtrap (i, show_all);
}
return (result);
diff --git a/builtins/type.def b/builtins/type.def
index 699ecd20..a8e47c0a 100644
--- a/builtins/type.def
+++ b/builtins/type.def
@@ -1,7 +1,7 @@
This file is type.def, from which is created type.c.
It implements the builtin "type" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -76,7 +76,7 @@ $END
#include "common.h"
#include "bashgetopt.h"
-extern int find_reserved_word __P((char *));
+extern int find_reserved_word PARAMS((char *));
/* For each word in LIST, find out what the shell is going to do with
it as a simple command. i.e., which file would this shell use to
diff --git a/builtins/ulimit.def b/builtins/ulimit.def
index 9b88c8cb..a895c5e2 100644
--- a/builtins/ulimit.def
+++ b/builtins/ulimit.def
@@ -1,7 +1,7 @@
This file is ulimit.def, from which is created ulimit.c.
It implements the builtin "ulimit" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -52,6 +52,7 @@ Options:
-v the size of virtual memory
-x the maximum number of file locks
-P the maximum number of pseudoterminals
+ -R the maximum time a real-time process can run before blocking
-T the maximum number of threads
Not all options are available on all platforms.
@@ -203,22 +204,22 @@ extern int errno;
#define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
-static int _findlim __P((int));
+static int _findlim PARAMS((int));
-static int ulimit_internal __P((int, char *, int, int));
+static int ulimit_internal PARAMS((int, char *, int, int));
-static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
-static int set_limit __P((int, RLIMTYPE, int));
+static int get_limit PARAMS((int, RLIMTYPE *, RLIMTYPE *));
+static int set_limit PARAMS((int, RLIMTYPE, int));
-static void printone __P((int, RLIMTYPE, int));
-static void print_all_limits __P((int));
+static void printone PARAMS((int, RLIMTYPE, int));
+static void print_all_limits PARAMS((int));
-static int set_all_limits __P((int, RLIMTYPE));
+static int set_all_limits PARAMS((int, RLIMTYPE));
-static int filesize __P((RLIMTYPE *));
-static int pipesize __P((RLIMTYPE *));
-static int getmaxuprc __P((RLIMTYPE *));
-static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
+static int filesize PARAMS((RLIMTYPE *));
+static int pipesize PARAMS((RLIMTYPE *));
+static int getmaxuprc PARAMS((RLIMTYPE *));
+static int getmaxvm PARAMS((RLIMTYPE *, RLIMTYPE *));
typedef struct {
int option; /* The ulimit option for this limit. */
@@ -232,8 +233,11 @@ static RESOURCE_LIMITS limits[] = {
#ifdef RLIMIT_NPTS
{ 'P', RLIMIT_NPTS, 1, "number of pseudoterminals", (char *)NULL },
#endif
+#ifdef RLIMIT_RTTIME
+ { 'R', RLIMIT_RTTIME, 1, "real-time non-blocking time", "microseconds" },
+#endif
#ifdef RLIMIT_PTHREAD
- { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
+ { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
#endif
#ifdef RLIMIT_SBSIZE
{ 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" },
@@ -741,7 +745,7 @@ printone (limind, curlim, pdesc)
else
sprintf (unitstr, "(-%c) ", limits[limind].option);
- printf ("%-20s %16s", limits[limind].description, unitstr);
+ printf ("%-20s %20s", limits[limind].description, unitstr);
}
if (curlim == RLIM_INFINITY)
puts ("unlimited");
diff --git a/builtins/umask.def b/builtins/umask.def
index d3138d4d..8041d56b 100644
--- a/builtins/umask.def
+++ b/builtins/umask.def
@@ -1,7 +1,7 @@
This file is umask.def, from which is created umask.c.
It implements the builtin "umask" in Bash.
-Copyright (C) 1987-2015 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -67,8 +67,8 @@ $END
/* */
/* **************************************************************** */
-static void print_symbolic_umask __P((mode_t));
-static int symbolic_umask __P((WORD_LIST *));
+static void print_symbolic_umask PARAMS((mode_t));
+static int symbolic_umask PARAMS((WORD_LIST *));
/* Set or display the mask used by the system when creating files. Flag
of -S means display the umask in a symbolic mode. */
diff --git a/builtins/wait.def b/builtins/wait.def
index 5deb3735..12260737 100644
--- a/builtins/wait.def
+++ b/builtins/wait.def
@@ -1,7 +1,7 @@
This file is wait.def, from which is created wait.c.
It implements the builtin "wait" in Bash.
-Copyright (C) 1987-2017 Free Software Foundation, Inc.
+Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,7 +22,7 @@ $BUILTIN wait
$FUNCTION wait_builtin
$DEPENDS_ON JOB_CONTROL
$PRODUCES wait.c
-$SHORT_DOC wait [-fn] [id ...]
+$SHORT_DOC wait [-fn] [-p var] [id ...]
Wait for job completion and return exit status.
Waits for each process identified by an ID, which may be a process ID or a
@@ -31,15 +31,22 @@ given, waits for all currently active child processes, and the return
status is zero. If ID is a job specification, waits for all processes
in that job's pipeline.
-If the -n option is supplied, waits for the next job to terminate and
-returns its exit status.
+If the -n option is supplied, waits for a single job from the list of IDs,
+or, if no IDs are supplied, for the next job to complete and returns its
+exit status.
+
+If the -p option is supplied, the process or job identifier of the job
+for which the exit status is returned is assigned to the variable VAR
+named by the option argument. The variable will be unset initially, before
+any assignment. This is useful only when the -n option is supplied.
If the -f option is supplied, and job control is enabled, waits for the
specified ID to terminate, instead of waiting for it to change status.
Exit Status:
Returns the status of the last ID; fails if ID is invalid or an invalid
-option is given.
+option is given, or if -n is supplied and the shell has no unwaited-for
+children.
$END
$BUILTIN wait
@@ -73,6 +80,8 @@ $END
#include "../shell.h"
#include "../execute_cmd.h"
#include "../jobs.h"
+#include "../trap.h"
+#include "../sig.h"
#include "common.h"
#include "bashgetopt.h"
@@ -81,6 +90,9 @@ extern int wait_signal_received;
procenv_t wait_intr_buf;
int wait_intr_flag;
+static int set_waitlist PARAMS((WORD_LIST *));
+static void unset_waitlist PARAMS((void));
+
/* Wait for the pid in LIST to stop or die. If no arguments are given, then
wait for all of the active background processes of the shell and return
0. If a list of pids or job specs are given, return the exit status of
@@ -89,7 +101,6 @@ int wait_intr_flag;
#define WAIT_RETURN(s) \
do \
{ \
- interrupt_immediately = old_interrupt_immediately;\
wait_signal_received = 0; \
wait_intr_flag = 0; \
return (s);\
@@ -101,13 +112,17 @@ wait_builtin (list)
WORD_LIST *list;
{
int status, code, opt, nflag, wflags;
- volatile int old_interrupt_immediately;
+ char *vname;
+ SHELL_VAR *pidvar;
+ struct procstat pstat;
USE_VAR(list);
nflag = wflags = 0;
+ vname = NULL;
+ pidvar = (SHELL_VAR *)NULL;
reset_internal_getopt ();
- while ((opt = internal_getopt (list, "nf")) != -1)
+ while ((opt = internal_getopt (list, "fnp:")) != -1)
{
switch (opt)
{
@@ -118,6 +133,9 @@ wait_builtin (list)
case 'f':
wflags |= JWAIT_FORCE;
break;
+ case 'p':
+ vname = list_optarg;
+ break;
#endif
CASE_HELPOPT;
default:
@@ -127,10 +145,24 @@ wait_builtin (list)
}
list = loptend;
- old_interrupt_immediately = interrupt_immediately;
-#if 0
- interrupt_immediately++;
+ /* Sanity-check variable name if -p supplied. */
+ if (vname)
+ {
+#if defined (ARRAY_VARS)
+ int arrayflags;
+
+ arrayflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
+ if (legal_identifier (vname) == 0 && valid_array_reference (vname, arrayflags) == 0)
+#else
+ if (legal_identifier (vname) == 0)
#endif
+ {
+ sh_invalidid (vname);
+ WAIT_RETURN (EXECUTION_FAILURE);
+ }
+ if (builtin_unbind_variable (vname) == -2)
+ WAIT_RETURN (EXECUTION_FAILURE);
+ }
/* POSIX.2 says: When the shell is waiting (by means of the wait utility)
for asynchronous commands to complete, the reception of a signal for
@@ -151,15 +183,43 @@ wait_builtin (list)
WAIT_RETURN (status);
}
+ opt = first_pending_trap ();
+#if defined (SIGCHLD)
+ /* We special case SIGCHLD when not in posix mode because we don't break
+ out of the wait even when the signal is trapped; we run the trap after
+ the wait completes. See how it's handled in jobs.c:waitchld(). */
+ if (opt == SIGCHLD && posixly_correct == 0)
+ opt = next_pending_trap (opt+1);
+#endif
+ if (opt != -1)
+ {
+ last_command_exit_signal = wait_signal_received = opt;
+ status = opt + 128;
+ WAIT_RETURN (status);
+ }
+
/* We support jobs or pids.
wait <pid-or-job> [pid-or-job ...] */
#if defined (JOB_CONTROL)
if (nflag)
{
- status = wait_for_any_job (wflags);
+ if (list)
+ {
+ opt = set_waitlist (list);
+ if (opt == 0)
+ WAIT_RETURN (127);
+ wflags |= JWAIT_WAITING;
+ }
+
+ status = wait_for_any_job (wflags, &pstat);
if (status < 0)
status = 127;
+
+ if (vname && status >= 0)
+ bind_var_to_int (vname, pstat.pid);
+ if (list)
+ unset_waitlist ();
WAIT_RETURN (status);
}
#endif
@@ -168,7 +228,9 @@ wait_builtin (list)
currently active background processes. */
if (list == 0)
{
- wait_for_background_pids ();
+ wait_for_background_pids (&pstat);
+ if (vname)
+ bind_var_to_int (vname, pstat.pid);
WAIT_RETURN (EXECUTION_SUCCESS);
}
@@ -186,10 +248,14 @@ wait_builtin (list)
{
pid = (pid_t)pid_value;
status = wait_for_single_pid (pid, wflags|JWAIT_PERROR);
+ pstat.pid = pid;
+ pstat.status = status;
}
else
{
sh_badpid (w);
+ pstat.pid = NO_PID;
+ pstat.status = 127;
WAIT_RETURN (EXECUTION_FAILURE);
}
}
@@ -209,22 +275,90 @@ wait_builtin (list)
sh_badjob (list->word->word);
UNBLOCK_CHILD (oset);
status = 127; /* As per Posix.2, section 4.70.2 */
+ pstat.pid = NO_PID;
+ pstat.status = status;
list = list->next;
continue;
}
/* Job spec used. Wait for the last pid in the pipeline. */
UNBLOCK_CHILD (oset);
- status = wait_for_job (job, wflags);
+ status = wait_for_job (job, wflags, &pstat);
}
#endif /* JOB_CONTROL */
else
{
sh_badpid (w);
+ pstat.pid = NO_PID;
+ pstat.status = 127;
status = EXECUTION_FAILURE;
}
+
+ /* Don't waste time with a longjmp. */
+ if (wait_signal_received)
+ {
+ last_command_exit_signal = wait_signal_received;
+ status = 128 + wait_signal_received;
+ wait_sigint_cleanup ();
+ WAIT_RETURN (status);
+ }
+
list = list->next;
}
WAIT_RETURN (status);
}
+
+#if defined (JOB_CONTROL)
+/* Take each valid pid or jobspec in LIST and mark the corresponding job as
+ J_WAITING, so wait -n knows which jobs to wait for. Return the number of
+ jobs we found. */
+static int
+set_waitlist (list)
+ WORD_LIST *list;
+{
+ sigset_t set, oset;
+ int job, r, njob;
+ intmax_t pid;
+ WORD_LIST *l;
+
+ BLOCK_CHILD (set, oset);
+ njob = 0;
+ for (l = list; l; l = l->next)
+ {
+ job = NO_JOB;
+ job = (l && legal_number (l->word->word, &pid) && pid == (pid_t) pid)
+ ? get_job_by_pid ((pid_t) pid, 0, 0)
+ : get_job_spec (l);
+ if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
+ {
+ sh_badjob (l->word->word);
+ continue;
+ }
+ /* We don't check yet to see if one of the desired jobs has already
+ terminated, but we could. We wait until wait_for_any_job(). This
+ has the advantage of validating all the arguments. */
+ if ((jobs[job]->flags & J_WAITING) == 0)
+ {
+ njob++;
+ jobs[job]->flags |= J_WAITING;
+ }
+ }
+ UNBLOCK_CHILD (oset);
+ return (njob);
+}
+
+/* Clean up after a call to wait -n jobs */
+static void
+unset_waitlist ()
+{
+ int i;
+ sigset_t set, oset;
+
+ BLOCK_CHILD (set, oset);
+ for (i = 0; i < js.j_jobslots; i++)
+ if (jobs[i] && (jobs[i]->flags & J_WAITING))
+ jobs[i]->flags &= ~J_WAITING;
+ UNBLOCK_CHILD (oset);
+}
+#endif