mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-07 10:42:28 +02:00
Bash-5.3-alpha release
This commit is contained in:
+13
-1
@@ -1,6 +1,6 @@
|
||||
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
|
||||
#
|
||||
# Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -343,6 +343,7 @@ common.o: $(topdir)/builtins.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
common.o: $(topdir)/subst.h $(topdir)/execute_cmd.h $(topdir)/error.h
|
||||
common.o: $(topdir)/externs.h ../pathnames.h ./builtext.h
|
||||
common.o: $(BASHINCDIR)/chartypes.h
|
||||
common.o: $(BASHINCDIR)/unlocked-io.h
|
||||
evalfile.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h ${BASHINCDIR}/filecntl.h
|
||||
evalfile.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
evalfile.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h
|
||||
@@ -439,6 +440,7 @@ echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/
|
||||
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
|
||||
echo.o: $(BASHINCDIR)/unlocked-io.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
|
||||
@@ -468,6 +470,7 @@ exit.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/jobs.h
|
||||
exit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
exit.o: $(topdir)/execute_cmd.h
|
||||
exit.o: $(BASHINCDIR)/maxpath.h ./builtext.h ../pathnames.h
|
||||
exit.o: $(BASHINCDIR)/unlocked-io.h
|
||||
fc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
|
||||
fc.o: $(topdir)/builtins.h $(topdir)/command.h $(srcdir)/bashgetopt.h
|
||||
fc.o: $(topdir)/bashhist.h $(topdir)/parser.h
|
||||
@@ -478,6 +481,7 @@ fc.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/shell.h $(topdir)/syntax.h
|
||||
fc.o: $(topdir)/flags.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
fc.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h $(BASHINCDIR)/chartypes.h
|
||||
fc.o: ../pathnames.h
|
||||
fc.o: $(BASHINCDIR)/unlocked-io.h
|
||||
fg_bg.o: $(topdir)/bashtypes.h $(srcdir)/bashgetopt.h
|
||||
fg_bg.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
fg_bg.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
@@ -498,6 +502,7 @@ hash.o: $(topdir)/findcmd.h $(topdir)/hashlib.h $(topdir)/sig.h
|
||||
hash.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
hash.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
hash.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||
hash.o: $(BASHINCDIR)/unlocked-io.h
|
||||
hash.o: $(topdir)/conftypes.h $(topdir)/execute_cmd.h
|
||||
hash.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ../pathnames.h
|
||||
help.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
@@ -507,6 +512,7 @@ help.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
help.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h
|
||||
help.o: $(topdir)/conftypes.h $(topdir)/execute_cmd.h
|
||||
help.o: ${srcdir}/common.h $(topdir)/sig.h ../pathnames.h
|
||||
help.o: $(BASHINCDIR)/unlocked-io.h
|
||||
history.o: $(topdir)/bashtypes.h
|
||||
history.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
history.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
@@ -515,6 +521,7 @@ history.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/sig.h $(topdir)/pars
|
||||
history.o: ${BASHINCDIR}/filecntl.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
|
||||
history.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/bashhist.h $(BASHINCDIR)/maxpath.h
|
||||
history.o: ../pathnames.h
|
||||
history.o: $(BASHINCDIR)/unlocked-io.h
|
||||
inlib.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
inlib.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
inlib.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
@@ -538,6 +545,7 @@ let.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/s
|
||||
let.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
let.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
let.o: ../pathnames.h
|
||||
let.o: $(BASHINCDIR)/unlocked-io.h
|
||||
printf.o: ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/bashjmp.h
|
||||
printf.o: $(topdir)/command.h $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
printf.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
@@ -547,6 +555,7 @@ printf.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/stdc.h $(src
|
||||
printf.o: $(topdir)/bashtypes.h ${srcdir}/common.h $(BASHINCDIR)/chartypes.h
|
||||
printf.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
printf.o: ../pathnames.h
|
||||
printf.o: $(BASHINCDIR)/unlocked-io.h
|
||||
pushd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
pushd.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
@@ -554,6 +563,7 @@ pushd.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/sig.h
|
||||
pushd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
pushd.o: $(BASHINCDIR)/maxpath.h $(srcdir)/common.h ./builtext.h
|
||||
pushd.o: ../pathnames.h
|
||||
pushd.o: $(BASHINCDIR)/unlocked-io.h
|
||||
read.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
read.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
@@ -562,6 +572,7 @@ read.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/v
|
||||
read.o: $(BASHINCDIR)/shtty.h $(topdir)/sig.h
|
||||
read.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h
|
||||
read.o: $(topdir)/arrayfunc.h ../pathnames.h
|
||||
read.o: $(BASHINCDIR)/unlocked-io.h
|
||||
return.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
return.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
return.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/sig.h
|
||||
@@ -622,6 +633,7 @@ times.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)
|
||||
times.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
times.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
times.o: $(BASHINCDIR)/posixtime.h ../pathnames.h
|
||||
times.o: $(BASHINCDIR)/unlocked-io.h
|
||||
trap.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
trap.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
|
||||
trap.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h $(topdir)/sig.h
|
||||
|
||||
+18
-22
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -63,12 +63,11 @@ $END
|
||||
/* Flags for print_alias */
|
||||
#define AL_REUSABLE 0x01
|
||||
|
||||
static void print_alias PARAMS((alias_t *, int));
|
||||
static int print_alias (alias_t *, int);
|
||||
|
||||
/* Hack the alias command in a Korn shell way. */
|
||||
int
|
||||
alias_builtin (list)
|
||||
WORD_LIST *list;
|
||||
alias_builtin (WORD_LIST *list)
|
||||
{
|
||||
int any_failed, offset, pflag, dflags;
|
||||
alias_t **alias_list, *t;
|
||||
@@ -104,13 +103,14 @@ alias_builtin (list)
|
||||
if (alias_list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
any_failed = EXECUTION_SUCCESS;
|
||||
for (offset = 0; alias_list[offset]; offset++)
|
||||
print_alias (alias_list[offset], dflags);
|
||||
if (any_failed = print_alias (alias_list[offset], dflags) != EXECUTION_SUCCESS)
|
||||
break;
|
||||
|
||||
free (alias_list); /* XXX - Do not free the strings. */
|
||||
|
||||
if (list == 0)
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
return (any_failed != EXECUTION_SUCCESS ? EXECUTION_FAILURE : sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
any_failed = 0;
|
||||
@@ -126,7 +126,7 @@ alias_builtin (list)
|
||||
name[offset] = '\0';
|
||||
value = name + offset + 1;
|
||||
|
||||
if (legal_alias_name (name, 0) == 0)
|
||||
if (valid_alias_name (name, 0) == 0)
|
||||
{
|
||||
builtin_error (_("`%s': invalid alias name"), name);
|
||||
any_failed++;
|
||||
@@ -138,7 +138,10 @@ alias_builtin (list)
|
||||
{
|
||||
t = find_alias (name);
|
||||
if (t)
|
||||
print_alias (t, dflags);
|
||||
{
|
||||
if (print_alias (t, dflags) != EXECUTION_SUCCESS)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_notfound (name);
|
||||
@@ -167,10 +170,9 @@ $END
|
||||
#if defined (ALIAS)
|
||||
/* Remove aliases named in LIST from the aliases database. */
|
||||
int
|
||||
unalias_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
unalias_builtin (WORD_LIST *list)
|
||||
{
|
||||
register alias_t *alias;
|
||||
alias_t *alias;
|
||||
int opt, aflag;
|
||||
|
||||
aflag = 0;
|
||||
@@ -206,11 +208,7 @@ unalias_builtin (list)
|
||||
aflag = 0;
|
||||
while (list)
|
||||
{
|
||||
alias = find_alias (list->word->word);
|
||||
|
||||
if (alias)
|
||||
remove_alias (alias->name);
|
||||
else
|
||||
if (remove_alias (list->word->word) < 0)
|
||||
{
|
||||
sh_notfound (list->word->word);
|
||||
aflag++;
|
||||
@@ -223,10 +221,8 @@ unalias_builtin (list)
|
||||
}
|
||||
|
||||
/* Output ALIAS in such a way as to allow it to be read back in. */
|
||||
static void
|
||||
print_alias (alias, flags)
|
||||
alias_t *alias;
|
||||
int flags;
|
||||
static int
|
||||
print_alias (alias_t *alias, int flags)
|
||||
{
|
||||
char *value;
|
||||
|
||||
@@ -236,6 +232,6 @@ print_alias (alias, flags)
|
||||
printf ("%s=%s\n", alias->name, value);
|
||||
free (value);
|
||||
|
||||
fflush (stdout);
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
#endif /* ALIAS */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* bashgetopt.c -- `getopt' for use by the builtins. */
|
||||
|
||||
/* Copyright (C) 1992-2021 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1992-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -48,9 +48,7 @@ WORD_LIST *lcurrent = (WORD_LIST *)NULL;
|
||||
WORD_LIST *loptend; /* Points to the first non-option argument in the list */
|
||||
|
||||
int
|
||||
internal_getopt(list, opts)
|
||||
WORD_LIST *list;
|
||||
char *opts;
|
||||
internal_getopt(WORD_LIST *list, char *opts)
|
||||
{
|
||||
register int c;
|
||||
register char *cp;
|
||||
@@ -154,7 +152,7 @@ char *opts;
|
||||
list_optflags = 0;
|
||||
}
|
||||
} else {
|
||||
if (lcurrent->next && legal_number(lcurrent->next->word->word, (intmax_t *)0)) {
|
||||
if (lcurrent->next && valid_number(lcurrent->next->word->word, (intmax_t *)0)) {
|
||||
lcurrent = lcurrent->next;
|
||||
list_optarg = lcurrent->word->word;
|
||||
list_optflags = lcurrent->word->flags;
|
||||
@@ -187,7 +185,7 @@ char *opts;
|
||||
*/
|
||||
|
||||
void
|
||||
reset_internal_getopt ()
|
||||
reset_internal_getopt (void)
|
||||
{
|
||||
lhead = lcurrent = loptend = (WORD_LIST *)NULL;
|
||||
sp = 1;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* bashgetopt.h -- extern declarations for stuff defined in bashgetopt.c. */
|
||||
|
||||
/* Copyright (C) 1993-2021 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -37,7 +37,7 @@ extern int list_opttype;
|
||||
extern WORD_LIST *lcurrent;
|
||||
extern WORD_LIST *loptend;
|
||||
|
||||
extern int internal_getopt PARAMS((WORD_LIST *, char *));
|
||||
extern void reset_internal_getopt PARAMS((void));
|
||||
extern int internal_getopt (WORD_LIST *, char *);
|
||||
extern void reset_internal_getopt (void);
|
||||
|
||||
#endif /* !__BASH_GETOPT_H */
|
||||
|
||||
+41
-24
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 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 PARAMS((char *));
|
||||
static int unbind_command PARAMS((char *));
|
||||
static int unbind_keyseq PARAMS((char *));
|
||||
static int query_bindings (char *);
|
||||
static int unbind_command (char *);
|
||||
static int unbind_keyseq (char *);
|
||||
|
||||
#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
|
||||
|
||||
@@ -108,8 +108,7 @@ static int unbind_keyseq PARAMS((char *));
|
||||
#define XXFLAG 0x2000
|
||||
|
||||
int
|
||||
bind_builtin (list)
|
||||
WORD_LIST *list;
|
||||
bind_builtin (WORD_LIST *list)
|
||||
{
|
||||
int return_code;
|
||||
Keymap kmap, saved_keymap;
|
||||
@@ -117,14 +116,7 @@ bind_builtin (list)
|
||||
char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq, *t;
|
||||
|
||||
if (no_line_editing)
|
||||
{
|
||||
#if 0
|
||||
builtin_error (_("line editing not enabled"));
|
||||
return (EXECUTION_FAILURE);
|
||||
#else
|
||||
builtin_warning (_("line editing not enabled"));
|
||||
#endif
|
||||
}
|
||||
builtin_warning (_("line editing not enabled"));
|
||||
|
||||
kmap = saved_keymap = (Keymap) NULL;
|
||||
flags = 0;
|
||||
@@ -192,7 +184,7 @@ bind_builtin (list)
|
||||
case 'X':
|
||||
flags |= XXFLAG;
|
||||
break;
|
||||
case GETOPT_HELP:
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
BIND_RETURN (EX_USAGE);
|
||||
@@ -227,10 +219,37 @@ bind_builtin (list)
|
||||
rl_list_funmap_names ();
|
||||
|
||||
if (flags & PFLAG)
|
||||
rl_function_dumper (1);
|
||||
{
|
||||
#if 0 /* TAG:bash-5.3 */
|
||||
if (list == 0)
|
||||
rl_function_dumper (1);
|
||||
else
|
||||
while (list)
|
||||
{
|
||||
rl_print_keybinding (list->word->word, kmap, 1);
|
||||
list = list->next;
|
||||
}
|
||||
#else
|
||||
rl_function_dumper (1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (flags & PPFLAG)
|
||||
rl_function_dumper (0);
|
||||
{
|
||||
#if 0 /* TAG:bash-5.3 */
|
||||
if (list == 0)
|
||||
rl_function_dumper (0);
|
||||
else
|
||||
while (list)
|
||||
{
|
||||
rl_print_keybinding (list->word->word, kmap, 0);
|
||||
list = list->next;
|
||||
}
|
||||
#else
|
||||
rl_function_dumper (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (flags & SFLAG)
|
||||
rl_macro_dumper (1);
|
||||
@@ -277,7 +296,8 @@ bind_builtin (list)
|
||||
/* Process the rest of the arguments as binding specifications. */
|
||||
while (list)
|
||||
{
|
||||
int olen, nlen, d, i;
|
||||
size_t olen, nlen;
|
||||
int d, i;
|
||||
char **obindings, **nbindings;
|
||||
|
||||
obindings = rl_invoking_keyseqs (bash_execute_unix_command);
|
||||
@@ -315,8 +335,7 @@ bind_builtin (list)
|
||||
}
|
||||
|
||||
static int
|
||||
query_bindings (name)
|
||||
char *name;
|
||||
query_bindings (char *name)
|
||||
{
|
||||
rl_command_func_t *function;
|
||||
char **keyseqs;
|
||||
@@ -347,8 +366,7 @@ query_bindings (name)
|
||||
}
|
||||
|
||||
static int
|
||||
unbind_command (name)
|
||||
char *name;
|
||||
unbind_command (char *name)
|
||||
{
|
||||
rl_command_func_t *function;
|
||||
|
||||
@@ -364,8 +382,7 @@ unbind_command (name)
|
||||
}
|
||||
|
||||
static int
|
||||
unbind_keyseq (seq)
|
||||
char *seq;
|
||||
unbind_keyseq (char *seq)
|
||||
{
|
||||
char *kseq;
|
||||
int kslen, type;
|
||||
|
||||
+15
-9
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2022 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 PARAMS((void));
|
||||
static int check_loop_level (void);
|
||||
|
||||
/* The depth of while's and until's. */
|
||||
int loop_level = 0;
|
||||
@@ -60,8 +60,7 @@ int continuing = 0;
|
||||
/* Set up to break x levels, where x defaults to 1, but can be specified
|
||||
as the first argument. */
|
||||
int
|
||||
break_builtin (list)
|
||||
WORD_LIST *list;
|
||||
break_builtin (WORD_LIST *list)
|
||||
{
|
||||
intmax_t newbreak;
|
||||
|
||||
@@ -70,10 +69,14 @@ break_builtin (list)
|
||||
if (check_loop_level () == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
(void)get_numeric_arg (list, 1, &newbreak);
|
||||
/* This will not return if an error is encountered. */
|
||||
(void)get_numeric_arg (list, interactive_shell ? 2 : 1, &newbreak);
|
||||
|
||||
if (newbreak <= 0)
|
||||
{
|
||||
/* skip over `--' option to get the right error message */
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
sh_erange (list->word->word, _("loop count"));
|
||||
breaking = loop_level;
|
||||
return (EXECUTION_FAILURE);
|
||||
@@ -102,8 +105,7 @@ $END
|
||||
/* Set up to continue x levels, where x defaults to 1, but can be specified
|
||||
as the first argument. */
|
||||
int
|
||||
continue_builtin (list)
|
||||
WORD_LIST *list;
|
||||
continue_builtin (WORD_LIST *list)
|
||||
{
|
||||
intmax_t newcont;
|
||||
|
||||
@@ -112,10 +114,14 @@ continue_builtin (list)
|
||||
if (check_loop_level () == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
(void)get_numeric_arg (list, 1, &newcont);
|
||||
/* This will not return if an error is encountered. */
|
||||
(void)get_numeric_arg (list, interactive_shell ? 2 : 1, &newcont);
|
||||
|
||||
if (newcont <= 0)
|
||||
{
|
||||
/* skip over `--' option to get the right error message */
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
sh_erange (list->word->word, _("loop count"));
|
||||
breaking = loop_level;
|
||||
return (EXECUTION_FAILURE);
|
||||
@@ -132,7 +138,7 @@ continue_builtin (list)
|
||||
/* Return non-zero if a break or continue command would be okay.
|
||||
Print an error message if break or continue is meaningless here. */
|
||||
static int
|
||||
check_loop_level ()
|
||||
check_loop_level (void)
|
||||
{
|
||||
#if defined (BREAK_COMPLAINS)
|
||||
if (loop_level == 0 && posixly_correct == 0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
This file is builtin.def, from which is created builtin.c.
|
||||
It implements the builtin "builtin" in Bash.
|
||||
|
||||
Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2017,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -50,8 +50,7 @@ $END
|
||||
/* Run the command mentioned in list directly, without going through the
|
||||
normal alias/function/builtin/filename lookup process. */
|
||||
int
|
||||
builtin_builtin (list)
|
||||
WORD_LIST *list;
|
||||
builtin_builtin (WORD_LIST *list)
|
||||
{
|
||||
sh_builtin_func_t *function;
|
||||
register char *command;
|
||||
|
||||
+9
-5
@@ -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-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2019,2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -69,8 +69,7 @@ extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
int
|
||||
caller_builtin (list)
|
||||
WORD_LIST *list;
|
||||
caller_builtin (WORD_LIST *list)
|
||||
{
|
||||
#if !defined (ARRAY_VARS)
|
||||
printf ("1 NULL\n");
|
||||
@@ -109,7 +108,7 @@ caller_builtin (list)
|
||||
if (funcname_a == 0 || array_empty (funcname_a))
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
if (legal_number (list->word->word, &num))
|
||||
if (valid_number (list->word->word, &num))
|
||||
{
|
||||
lineno_s = array_reference (bash_lineno_a, num);
|
||||
source_s = array_reference (bash_source_a, num+1);
|
||||
@@ -140,7 +139,12 @@ N_("Returns the context of the current subroutine call.\n\
|
||||
provide a stack trace.\n\
|
||||
\n\
|
||||
The value of EXPR indicates how many call frames to go back before the\n\
|
||||
current one; the top frame is frame 0."),
|
||||
current one; the top frame is frame 0.\n\
|
||||
\n\
|
||||
Exit Status:\n\
|
||||
Returns 0 unless the shell is not executing a shell function or EXPR\n\
|
||||
is invalid."
|
||||
),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
|
||||
+44
-63
@@ -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-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 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 PARAMS((int));
|
||||
static int setpwd PARAMS((char *));
|
||||
static char *resetpwd PARAMS((char *));
|
||||
static int change_to_directory PARAMS((char *, int, int));
|
||||
static int bindpwd (int);
|
||||
static int setpwd (char *);
|
||||
static char *resetpwd (char *);
|
||||
static int change_to_directory (char *, int, int);
|
||||
|
||||
static int cdxattr PARAMS((char *, char **));
|
||||
static void resetxattr PARAMS((void));
|
||||
static int cdxattr (char *, char **);
|
||||
static void resetxattr (void);
|
||||
|
||||
/* Change this to 1 to get cd spelling correction by default. */
|
||||
int cdspelling = 0;
|
||||
@@ -75,7 +75,7 @@ static int xattrfd = -1;
|
||||
|
||||
$BUILTIN cd
|
||||
$FUNCTION cd_builtin
|
||||
$SHORT_DOC cd [-L|[-P [-e]] [-@]] [dir]
|
||||
$SHORT_DOC cd [-L|[-P [-e]]] [-@] [dir]
|
||||
Change the shell working directory.
|
||||
|
||||
Change the current directory to DIR. The default DIR is the value of the
|
||||
@@ -115,8 +115,7 @@ $END
|
||||
|
||||
/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */
|
||||
static int
|
||||
setpwd (dirname)
|
||||
char *dirname;
|
||||
setpwd (char *dirname)
|
||||
{
|
||||
int old_anm;
|
||||
SHELL_VAR *tvar;
|
||||
@@ -134,8 +133,7 @@ setpwd (dirname)
|
||||
}
|
||||
|
||||
static int
|
||||
bindpwd (no_symlinks)
|
||||
int no_symlinks;
|
||||
bindpwd (int no_symlinks)
|
||||
{
|
||||
char *dirname, *pwdvar;
|
||||
int old_anm, r, canon_failed;
|
||||
@@ -160,10 +158,9 @@ bindpwd (no_symlinks)
|
||||
pwdvar = get_string_value ("PWD");
|
||||
|
||||
tvar = bind_variable ("OLDPWD", pwdvar, 0);
|
||||
if (tvar && readonly_p (tvar))
|
||||
if (tvar == 0 || readonly_p (tvar))
|
||||
r = EXECUTION_FAILURE;
|
||||
|
||||
if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
else if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
{
|
||||
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
|
||||
array_needs_making = 0;
|
||||
@@ -183,8 +180,7 @@ bindpwd (no_symlinks)
|
||||
/* Call get_working_directory to reset the value of
|
||||
the_current_working_directory () */
|
||||
static char *
|
||||
resetpwd (caller)
|
||||
char *caller;
|
||||
resetpwd (char *caller)
|
||||
{
|
||||
char *tdir;
|
||||
|
||||
@@ -194,10 +190,9 @@ resetpwd (caller)
|
||||
return (tdir);
|
||||
}
|
||||
|
||||
/* return new constructed directory name in *NDIRP */
|
||||
static int
|
||||
cdxattr (dir, ndirp)
|
||||
char *dir; /* don't assume we can always free DIR */
|
||||
char **ndirp; /* return new constructed directory name */
|
||||
cdxattr (char *dir, char **ndirp)
|
||||
{
|
||||
#if defined (O_XATTR)
|
||||
int apfd, fd, r, e;
|
||||
@@ -241,7 +236,7 @@ cdxattr (dir, ndirp)
|
||||
|
||||
/* Clean up the O_XATTR baggage. Currently only closes xattrfd */
|
||||
static void
|
||||
resetxattr ()
|
||||
resetxattr (void)
|
||||
{
|
||||
#if defined (O_XATTR)
|
||||
if (xattrfd >= 0)
|
||||
@@ -264,8 +259,7 @@ resetxattr ()
|
||||
so the programming interface is simple, and it handles errors and
|
||||
restrictions properly. */
|
||||
int
|
||||
cd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
cd_builtin (WORD_LIST *list)
|
||||
{
|
||||
char *dirname, *cdpath, *path, *temp;
|
||||
int path_index, no_symlinks, opt, lflag, e;
|
||||
@@ -320,9 +314,9 @@ cd_builtin (list)
|
||||
if (list == 0)
|
||||
{
|
||||
/* `cd' without arguments is equivalent to `cd $HOME' */
|
||||
dirname = get_string_value ("HOME");
|
||||
dirname = get_string_value ("HOME"); /* POSIX cd step 2 */
|
||||
|
||||
if (dirname == 0)
|
||||
if (dirname == 0) /* POSIX cd step 1 */
|
||||
{
|
||||
builtin_error (_("HOME not set"));
|
||||
return (EXECUTION_FAILURE);
|
||||
@@ -333,13 +327,13 @@ cd_builtin (list)
|
||||
else if (list->next)
|
||||
{
|
||||
builtin_error (_("too many arguments"));
|
||||
return (EXECUTION_FAILURE);
|
||||
return (EX_USAGE);
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
else if (list->word->word[0] == '\0')
|
||||
{
|
||||
builtin_error (_("null directory"));
|
||||
builtin_error (_("null directory")); /* POSIX cd implementation defined */
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
@@ -353,19 +347,14 @@ cd_builtin (list)
|
||||
builtin_error (_("OLDPWD not set"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#if 0
|
||||
lflag = interactive ? LCD_PRINTPATH : 0;
|
||||
#else
|
||||
lflag = LCD_PRINTPATH; /* According to SUSv3 */
|
||||
#endif
|
||||
lflag = LCD_PRINTPATH; /* POSIX cd `-' operand */
|
||||
}
|
||||
else if (absolute_pathname (list->word->word))
|
||||
else
|
||||
dirname = list->word->word;
|
||||
else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH")))
|
||||
{
|
||||
dirname = list->word->word;
|
||||
|
||||
/* Find directory in $CDPATH. */
|
||||
if (privileged_mode == 0 && absolute_pathname (dirname) == 0 && (cdpath = get_string_value ("CDPATH")))
|
||||
{
|
||||
/* Find directory in $CDPATH, POSIX cd step 5. */
|
||||
path_index = 0;
|
||||
while (path = extract_colon_unit (cdpath, &path_index))
|
||||
{
|
||||
@@ -395,23 +384,7 @@ cd_builtin (list)
|
||||
else
|
||||
free (temp);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* changed for bash-4.2 Posix cd description steps 5-6 */
|
||||
/* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
|
||||
try the current directory, so we just punt now with an error
|
||||
message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
|
||||
is so we don't mistakenly treat a CDPATH value of "" as not
|
||||
specifying the current directory. */
|
||||
if (posixly_correct && cdpath[0])
|
||||
{
|
||||
builtin_error ("%s: %s", dirname, strerror (ENOENT));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
dirname = list->word->word;
|
||||
|
||||
/* When we get here, DIRNAME is the directory to change to. If we
|
||||
chdir successfully, just return. */
|
||||
@@ -482,8 +455,7 @@ static int verbatim_pwd;
|
||||
|
||||
/* Print the name of the current working directory. */
|
||||
int
|
||||
pwd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
pwd_builtin (WORD_LIST *list)
|
||||
{
|
||||
char *directory;
|
||||
int opt, pflag;
|
||||
@@ -548,9 +520,7 @@ pwd_builtin (list)
|
||||
to the working directory. Return 1 on success, 0 on failure. */
|
||||
|
||||
static int
|
||||
change_to_directory (newdir, nolinks, xattr)
|
||||
char *newdir;
|
||||
int nolinks, xattr;
|
||||
change_to_directory (char *newdir, int nolinks, int xattr)
|
||||
{
|
||||
char *t, *tdir, *ndir;
|
||||
int err, canon_failed, r, ndlen;
|
||||
@@ -568,8 +538,11 @@ change_to_directory (newdir, nolinks, xattr)
|
||||
/* TDIR is either the canonicalized absolute pathname of NEWDIR
|
||||
(nolinks == 0) or the absolute physical pathname of NEWDIR
|
||||
(nolinks != 0). */
|
||||
tdir = nolinks ? sh_physpath (t, 0)
|
||||
: sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
|
||||
if (t && *t)
|
||||
tdir = nolinks ? sh_physpath (t, 0)
|
||||
: sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
|
||||
else
|
||||
tdir = NULL;
|
||||
|
||||
ndlen = strlen (newdir);
|
||||
|
||||
@@ -662,9 +635,17 @@ change_to_directory (newdir, nolinks, xattr)
|
||||
|
||||
/* We're not in physical mode (nolinks == 0), but we failed to change to
|
||||
the canonicalized directory name (TDIR). Try what the user passed
|
||||
verbatim. If we succeed, reinitialize the_current_working_directory.
|
||||
POSIX requires that we just fail here, so we do in posix mode. */
|
||||
if (posixly_correct == 0 && chdir (newdir) == 0)
|
||||
verbatim. If we succeed, reinitialize the_current_working_directory. */
|
||||
|
||||
/* The first block is step 9 in the POSIX cd algorithm. */
|
||||
if (posixly_correct && ndlen < PATH_MAX && strlen (tdir) >= PATH_MAX)
|
||||
r = chdir (newdir);
|
||||
else if (posixly_correct == 0)
|
||||
r = chdir (newdir);
|
||||
else
|
||||
r = -1;
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
t = resetpwd ("cd");
|
||||
if (t == 0)
|
||||
|
||||
+3
-5
@@ -1,7 +1,7 @@
|
||||
This file is colon.def, from which is created colon.c.
|
||||
It implements the builtin ":" in Bash.
|
||||
|
||||
Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2019,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -61,16 +61,14 @@ $END
|
||||
|
||||
/* Return a successful result. */
|
||||
int
|
||||
colon_builtin (ignore)
|
||||
WORD_LIST *ignore;
|
||||
colon_builtin (WORD_LIST *ignore)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return an unsuccessful result. */
|
||||
int
|
||||
false_builtin (ignore)
|
||||
WORD_LIST *ignore;
|
||||
false_builtin (WORD_LIST *ignore)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
+11
-9
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -53,18 +53,18 @@ $END
|
||||
#include "../shell.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../flags.h"
|
||||
#include "../parser.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR
|
||||
extern size_t confstr PARAMS((int, char *, size_t));
|
||||
extern size_t confstr (int, char *, size_t);
|
||||
#endif
|
||||
|
||||
/* Run the commands mentioned in LIST without paying attention to shell
|
||||
functions. */
|
||||
int
|
||||
command_builtin (list)
|
||||
WORD_LIST *list;
|
||||
command_builtin (WORD_LIST *list)
|
||||
{
|
||||
int result, verbose, use_standard_path, opt;
|
||||
COMMAND *command;
|
||||
@@ -124,20 +124,22 @@ command_builtin (list)
|
||||
|
||||
#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN | (use_standard_path ? CMD_STDPATH : 0))
|
||||
|
||||
INTERNAL_DEBUG (("command_builtin: running execute_command for `%s'", list->word->word));
|
||||
/* This code isn't executed any more; look at execute_cmd.c:execute_simple_command()
|
||||
where command is treated as a pseudo-reserved prefix so we can optimize
|
||||
away forks where possible. */
|
||||
|
||||
/* 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 ();
|
||||
command = make_bare_simple_command (line_number);
|
||||
command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
|
||||
command->value.Simple->redirects = (REDIRECT *)NULL;
|
||||
command->flags |= COMMAND_BUILTIN_FLAGS;
|
||||
command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
|
||||
|
||||
add_unwind_protect ((char *)dispose_command, command);
|
||||
add_unwind_protect (uw_dispose_command, command);
|
||||
result = execute_command (command);
|
||||
dispose_command (command);
|
||||
|
||||
run_unwind_frame ("command_builtin");
|
||||
|
||||
discard_unwind_frame ("command_builtin");
|
||||
return (result);
|
||||
}
|
||||
|
||||
+97
-165
@@ -1,6 +1,6 @@
|
||||
/* common.c - utility functions for all builtins */
|
||||
|
||||
/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -34,12 +34,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
@@ -85,7 +80,7 @@ sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
|
||||
shell. */
|
||||
|
||||
static void
|
||||
builtin_error_prolog ()
|
||||
builtin_error_prolog (void)
|
||||
{
|
||||
char *name;
|
||||
|
||||
@@ -100,19 +95,13 @@ builtin_error_prolog ()
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
builtin_error (const char *format, ...)
|
||||
#else
|
||||
builtin_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
builtin_error_prolog ();
|
||||
|
||||
SH_VA_START (args, format);
|
||||
va_start (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
@@ -120,20 +109,14 @@ builtin_error (format, va_alist)
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
builtin_warning (const char *format, ...)
|
||||
#else
|
||||
builtin_warning (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
builtin_error_prolog ();
|
||||
fprintf (stderr, _("warning: "));
|
||||
|
||||
SH_VA_START (args, format);
|
||||
va_start (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
@@ -142,7 +125,7 @@ builtin_warning (format, va_alist)
|
||||
|
||||
/* Print a usage summary for the currently-executing builtin command. */
|
||||
void
|
||||
builtin_usage ()
|
||||
builtin_usage (void)
|
||||
{
|
||||
if (this_command_name && *this_command_name)
|
||||
fprintf (stderr, _("%s: usage: "), this_command_name);
|
||||
@@ -153,22 +136,25 @@ builtin_usage ()
|
||||
/* Return if LIST is NULL else barf and jump to top_level. Used by some
|
||||
builtins that do not accept arguments. */
|
||||
void
|
||||
no_args (list)
|
||||
WORD_LIST *list;
|
||||
no_args (WORD_LIST *list, int fatal)
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
builtin_error (_("too many arguments"));
|
||||
top_level_cleanup ();
|
||||
jump_to_top_level (DISCARD);
|
||||
set_exit_status (EX_BADUSAGE);
|
||||
/* for now, the caller determines whether this is a fatal error */
|
||||
if (interactive_shell == 0 && fatal)
|
||||
jump_to_top_level (EXITPROG);
|
||||
else
|
||||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that no options were given to the currently-executing builtin,
|
||||
and return 0 if there were options. */
|
||||
int
|
||||
no_options (list)
|
||||
WORD_LIST *list;
|
||||
no_options (WORD_LIST *list)
|
||||
{
|
||||
int opt;
|
||||
|
||||
@@ -187,22 +173,19 @@ no_options (list)
|
||||
}
|
||||
|
||||
void
|
||||
sh_needarg (s)
|
||||
char *s;
|
||||
sh_needarg (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: option requires an argument"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_neednumarg (s)
|
||||
char *s;
|
||||
sh_neednumarg (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: numeric argument required"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_notfound (s)
|
||||
char *s;
|
||||
sh_notfound (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: not found"), s);
|
||||
}
|
||||
@@ -210,29 +193,25 @@ sh_notfound (s)
|
||||
/* Function called when one of the builtin commands detects an invalid
|
||||
option. */
|
||||
void
|
||||
sh_invalidopt (s)
|
||||
char *s;
|
||||
sh_invalidopt (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: invalid option"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidoptname (s)
|
||||
char *s;
|
||||
sh_invalidoptname (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: invalid option name"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidid (s)
|
||||
char *s;
|
||||
sh_invalidid (const char *s)
|
||||
{
|
||||
builtin_error (_("`%s': not a valid identifier"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidnum (s)
|
||||
char *s;
|
||||
sh_invalidnum (const char *s)
|
||||
{
|
||||
char *msg;
|
||||
|
||||
@@ -246,36 +225,31 @@ sh_invalidnum (s)
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidsig (s)
|
||||
char *s;
|
||||
sh_invalidsig (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: invalid signal specification"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_badpid (s)
|
||||
char *s;
|
||||
sh_badpid (const char *s)
|
||||
{
|
||||
builtin_error (_("`%s': not a pid or valid job spec"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_readonly (s)
|
||||
const char *s;
|
||||
sh_readonly (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: readonly variable"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_noassign (s)
|
||||
const char *s;
|
||||
sh_noassign (const char *s)
|
||||
{
|
||||
internal_error (_("%s: cannot assign"), s); /* XXX */
|
||||
}
|
||||
|
||||
void
|
||||
sh_erange (s, desc)
|
||||
char *s, *desc;
|
||||
sh_erange (const char *s, const char *desc)
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument"));
|
||||
@@ -285,15 +259,13 @@ sh_erange (s, desc)
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
void
|
||||
sh_badjob (s)
|
||||
char *s;
|
||||
sh_badjob (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: no such job"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_nojobs (s)
|
||||
char *s;
|
||||
sh_nojobs (const char *s)
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: no job control"), s);
|
||||
@@ -304,8 +276,7 @@ sh_nojobs (s)
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
void
|
||||
sh_restricted (s)
|
||||
char *s;
|
||||
sh_restricted (const char *s)
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: restricted"), s);
|
||||
@@ -315,14 +286,13 @@ sh_restricted (s)
|
||||
#endif
|
||||
|
||||
void
|
||||
sh_notbuiltin (s)
|
||||
char *s;
|
||||
sh_notbuiltin (const char *s)
|
||||
{
|
||||
builtin_error (_("%s: not a shell builtin"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_wrerror ()
|
||||
sh_wrerror (void)
|
||||
{
|
||||
#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE)
|
||||
if (errno != EPIPE)
|
||||
@@ -331,8 +301,7 @@ sh_wrerror ()
|
||||
}
|
||||
|
||||
void
|
||||
sh_ttyerror (set)
|
||||
int set;
|
||||
sh_ttyerror (int set)
|
||||
{
|
||||
if (set)
|
||||
builtin_error (_("error setting terminal attributes: %s"), strerror (errno));
|
||||
@@ -341,8 +310,7 @@ sh_ttyerror (set)
|
||||
}
|
||||
|
||||
int
|
||||
sh_chkwrite (s)
|
||||
int s;
|
||||
sh_chkwrite (int s)
|
||||
{
|
||||
QUIT;
|
||||
fflush (stdout);
|
||||
@@ -367,9 +335,7 @@ sh_chkwrite (s)
|
||||
in the list in *IP, if IP is non-null. A convenience function for
|
||||
loadable builtins; also used by `test'. */
|
||||
char **
|
||||
make_builtin_argv (list, ip)
|
||||
WORD_LIST *list;
|
||||
int *ip;
|
||||
make_builtin_argv (WORD_LIST *list, int *ip)
|
||||
{
|
||||
char **argv;
|
||||
|
||||
@@ -383,9 +349,7 @@ make_builtin_argv (list, ip)
|
||||
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;
|
||||
int destructive;
|
||||
remember_args (WORD_LIST *list, int destructive)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -413,7 +377,7 @@ remember_args (list, destructive)
|
||||
{
|
||||
dispose_words (rest_of_args);
|
||||
rest_of_args = copy_word_list (list);
|
||||
posparam_count += list_length (list);
|
||||
posparam_count += list_length ((GENERIC_LIST *)list);
|
||||
}
|
||||
|
||||
if (destructive)
|
||||
@@ -423,8 +387,7 @@ remember_args (list, destructive)
|
||||
}
|
||||
|
||||
void
|
||||
shift_args (times)
|
||||
int times;
|
||||
shift_args (int times)
|
||||
{
|
||||
WORD_LIST *temp;
|
||||
int count;
|
||||
@@ -456,7 +419,7 @@ shift_args (times)
|
||||
}
|
||||
|
||||
int
|
||||
number_of_args ()
|
||||
number_of_args (void)
|
||||
{
|
||||
#if 0
|
||||
register WORD_LIST *list;
|
||||
@@ -479,19 +442,19 @@ static int changed_dollar_vars;
|
||||
/* Have the dollar variables been reset to new values since we last
|
||||
checked? */
|
||||
int
|
||||
dollar_vars_changed ()
|
||||
dollar_vars_changed (void)
|
||||
{
|
||||
return (changed_dollar_vars);
|
||||
}
|
||||
|
||||
void
|
||||
set_dollar_vars_unchanged ()
|
||||
set_dollar_vars_unchanged (void)
|
||||
{
|
||||
changed_dollar_vars = 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_dollar_vars_changed ()
|
||||
set_dollar_vars_changed (void)
|
||||
{
|
||||
if (variable_context)
|
||||
changed_dollar_vars |= ARGS_FUNC;
|
||||
@@ -515,10 +478,7 @@ set_dollar_vars_changed ()
|
||||
current command; if FATAL is 0, return an indication of an invalid
|
||||
number by setting *NUMOK == 0 and return -1. */
|
||||
int
|
||||
get_numeric_arg (list, fatal, count)
|
||||
WORD_LIST *list;
|
||||
int fatal;
|
||||
intmax_t *count;
|
||||
get_numeric_arg (WORD_LIST *list, int fatal, intmax_t *count)
|
||||
{
|
||||
char *arg;
|
||||
|
||||
@@ -531,20 +491,17 @@ get_numeric_arg (list, fatal, count)
|
||||
if (list)
|
||||
{
|
||||
arg = list->word->word;
|
||||
if (arg == 0 || (legal_number (arg, count) == 0))
|
||||
if (arg == 0 || (valid_number (arg, count) == 0))
|
||||
{
|
||||
sh_neednumarg (list->word->word ? list->word->word : "`'");
|
||||
if (fatal == 0)
|
||||
return 0;
|
||||
else if (fatal == 1) /* fatal == 1; abort */
|
||||
throw_to_top_level ();
|
||||
else /* fatal == 2; discard current command */
|
||||
{
|
||||
top_level_cleanup ();
|
||||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
set_exit_status (EX_BADUSAGE);
|
||||
/* fatal == 1: abort; fatal == 2: discard current command */
|
||||
top_level_cleanup ();
|
||||
jump_to_top_level ((fatal == 1) ? EXITPROG : DISCARD);
|
||||
}
|
||||
no_args (list->next);
|
||||
no_args (list->next, 0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
@@ -552,8 +509,7 @@ get_numeric_arg (list, fatal, count)
|
||||
|
||||
/* Get an eight-bit status value from LIST */
|
||||
int
|
||||
get_exitstat (list)
|
||||
WORD_LIST *list;
|
||||
get_exitstat (WORD_LIST *list)
|
||||
{
|
||||
int status;
|
||||
intmax_t sval;
|
||||
@@ -564,24 +520,27 @@ get_exitstat (list)
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
/* If we're not running the DEBUG trap, the return builtin, when not
|
||||
given any arguments, uses the value of $? before the trap ran. If
|
||||
given an argument, return uses it. This means that the trap can't
|
||||
change $?. The DEBUG trap gets to change $?, though, since that is
|
||||
part of its reason for existing, and because the extended debug mode
|
||||
does things with the return value. */
|
||||
if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1)
|
||||
/* If we're not running the DEBUG trap, and haven't executed a shell
|
||||
function from the trap action, the return builtin, when not given
|
||||
any arguments, uses the value of $? before the trap ran. The business
|
||||
about executing a shell function from the trap action is from POSIX
|
||||
interp 1602 (10/2022). If given an argument, return uses it
|
||||
unconditionally. This means that the trap can't change $?. The DEBUG
|
||||
trap gets to change $?, though, since that is part of its reason for
|
||||
existing, and because the extended debug mode does things with the
|
||||
return value. */
|
||||
if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1 && trap_return_context == funcnest + sourcenest)
|
||||
return (trap_saved_exit_value);
|
||||
return (last_command_exit_value);
|
||||
}
|
||||
|
||||
arg = list->word->word;
|
||||
if (arg == 0 || legal_number (arg, &sval) == 0)
|
||||
if (arg == 0 || valid_number (arg, &sval) == 0)
|
||||
{
|
||||
sh_neednumarg (list->word->word ? list->word->word : "`'");
|
||||
return EX_BADUSAGE;
|
||||
return EX_USAGE;
|
||||
}
|
||||
no_args (list->next);
|
||||
no_args (list->next, 0);
|
||||
|
||||
status = sval & 255;
|
||||
return status;
|
||||
@@ -590,8 +549,7 @@ get_exitstat (list)
|
||||
/* Return the octal number parsed from STRING, or -1 to indicate
|
||||
that the string contained a bad number. */
|
||||
int
|
||||
read_octal (string)
|
||||
char *string;
|
||||
read_octal (char *string)
|
||||
{
|
||||
int result, digits;
|
||||
|
||||
@@ -621,8 +579,7 @@ read_octal (string)
|
||||
char *the_current_working_directory = (char *)NULL;
|
||||
|
||||
char *
|
||||
get_working_directory (for_whom)
|
||||
char *for_whom;
|
||||
get_working_directory (const char *for_whom)
|
||||
{
|
||||
if (no_symbolic_links)
|
||||
{
|
||||
@@ -651,8 +608,7 @@ get_working_directory (for_whom)
|
||||
|
||||
/* Make NAME our internal idea of the current working directory. */
|
||||
void
|
||||
set_working_directory (name)
|
||||
char *name;
|
||||
set_working_directory (const char *name)
|
||||
{
|
||||
FREE (the_current_working_directory);
|
||||
the_current_working_directory = savestring (name);
|
||||
@@ -666,13 +622,12 @@ set_working_directory (name)
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
int
|
||||
get_job_by_name (name, flags)
|
||||
const char *name;
|
||||
int flags;
|
||||
get_job_by_name (const char *name, int flags)
|
||||
{
|
||||
register int i, wl, cl, match, job;
|
||||
register PROCESS *p;
|
||||
register JOB *j;
|
||||
int i, match, job;
|
||||
size_t wl, cl;
|
||||
PROCESS *p;
|
||||
JOB *j;
|
||||
|
||||
job = NO_JOB;
|
||||
wl = strlen (name);
|
||||
@@ -721,8 +676,7 @@ get_job_by_name (name, flags)
|
||||
|
||||
/* Return the job spec found in LIST. */
|
||||
int
|
||||
get_job_spec (list)
|
||||
WORD_LIST *list;
|
||||
get_job_spec (WORD_LIST *list)
|
||||
{
|
||||
register char *word;
|
||||
int job, jflags;
|
||||
@@ -770,9 +724,7 @@ get_job_spec (list)
|
||||
* NOTE: `kill' calls this function with forcecols == 0
|
||||
*/
|
||||
int
|
||||
display_signal_list (list, forcecols)
|
||||
WORD_LIST *list;
|
||||
int forcecols;
|
||||
display_signal_list (WORD_LIST *list, int forcecols)
|
||||
{
|
||||
register int i, column;
|
||||
char *name;
|
||||
@@ -818,7 +770,7 @@ display_signal_list (list, forcecols)
|
||||
/* List individual signal names or numbers. */
|
||||
while (list)
|
||||
{
|
||||
if (legal_number (list->word->word, &lsignum))
|
||||
if (valid_number (list->word->word, &lsignum))
|
||||
{
|
||||
/* This is specified by Posix.2 so that exit statuses can be
|
||||
mapped into signal numbers. */
|
||||
@@ -875,9 +827,7 @@ display_signal_list (list, forcecols)
|
||||
Return the address of the builtin.
|
||||
DISABLED_OKAY means find it even if the builtin is disabled. */
|
||||
struct builtin *
|
||||
builtin_address_internal (name, disabled_okay)
|
||||
char *name;
|
||||
int disabled_okay;
|
||||
builtin_address_internal (const char *name, int disabled_okay)
|
||||
{
|
||||
int hi, lo, mid, j;
|
||||
|
||||
@@ -915,8 +865,7 @@ builtin_address_internal (name, disabled_okay)
|
||||
|
||||
/* Return the pointer to the function implementing builtin command NAME. */
|
||||
sh_builtin_func_t *
|
||||
find_shell_builtin (name)
|
||||
char *name;
|
||||
find_shell_builtin (const char *name)
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 0);
|
||||
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
|
||||
@@ -924,8 +873,7 @@ find_shell_builtin (name)
|
||||
|
||||
/* Return the address of builtin with NAME, whether it is enabled or not. */
|
||||
sh_builtin_func_t *
|
||||
builtin_address (name)
|
||||
char *name;
|
||||
builtin_address (const char *name)
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 1);
|
||||
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
|
||||
@@ -934,8 +882,7 @@ builtin_address (name)
|
||||
/* Return the function implementing the builtin NAME, but only if it is a
|
||||
POSIX.2 special builtin. */
|
||||
sh_builtin_func_t *
|
||||
find_special_builtin (name)
|
||||
char *name;
|
||||
find_special_builtin (const char *name)
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 0);
|
||||
return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
|
||||
@@ -944,8 +891,7 @@ find_special_builtin (name)
|
||||
}
|
||||
|
||||
static int
|
||||
shell_builtin_compare (sbp1, sbp2)
|
||||
struct builtin *sbp1, *sbp2;
|
||||
shell_builtin_compare (const struct builtin *sbp1, const struct builtin *sbp2)
|
||||
{
|
||||
int result;
|
||||
|
||||
@@ -958,7 +904,7 @@ shell_builtin_compare (sbp1, sbp2)
|
||||
/* Sort the table of shell builtins so that the binary search will work
|
||||
in find_shell_builtin. */
|
||||
void
|
||||
initialize_shell_builtins ()
|
||||
initialize_shell_builtins (void)
|
||||
{
|
||||
qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
|
||||
(QSFUNC *)shell_builtin_compare);
|
||||
@@ -966,7 +912,7 @@ initialize_shell_builtins ()
|
||||
|
||||
#if !defined (HELP_BUILTIN)
|
||||
void
|
||||
builtin_help ()
|
||||
builtin_help (void)
|
||||
{
|
||||
printf ("%s: %s\n", this_command_name, _("help not available in this version"));
|
||||
}
|
||||
@@ -980,10 +926,7 @@ builtin_help ()
|
||||
|
||||
/* Assign NAME=VALUE, passing FLAGS to the assignment functions. */
|
||||
SHELL_VAR *
|
||||
builtin_bind_variable (name, value, flags)
|
||||
char *name;
|
||||
char *value;
|
||||
int flags;
|
||||
builtin_bind_variable (char *name, char *value, int flags)
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
int vflags, bindflags;
|
||||
@@ -991,12 +934,11 @@ builtin_bind_variable (name, value, flags)
|
||||
#if defined (ARRAY_VARS)
|
||||
/* Callers are responsible for calling this with array references that have
|
||||
already undergone valid_array_reference checks (read, printf). */
|
||||
vflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
|
||||
bindflags = flags | (assoc_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB;
|
||||
if (flags & ASS_NOEXPAND)
|
||||
vflags |= VA_NOEXPAND;
|
||||
if (flags & ASS_ONEWORD)
|
||||
vflags |= VA_ONEWORD;
|
||||
/* XXX - should we unconditionally set ASS_NOEXPAND if the shell
|
||||
compatibility level is > 52? */
|
||||
bindflags = flags | (array_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB;
|
||||
vflags = convert_assign_flags_to_validarray_flags (flags);
|
||||
vflags |= array_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
|
||||
|
||||
if (valid_array_reference (name, vflags) == 0)
|
||||
v = bind_variable (name, value, flags);
|
||||
@@ -1013,10 +955,7 @@ builtin_bind_variable (name, value, flags)
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
builtin_bind_var_to_int (name, val, flags)
|
||||
char *name;
|
||||
intmax_t val;
|
||||
int flags;
|
||||
builtin_bind_var_to_int (char *name, intmax_t val, int flags)
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
@@ -1026,13 +965,11 @@ builtin_bind_var_to_int (name, val, flags)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *
|
||||
builtin_find_indexed_array (array_name, flags)
|
||||
char *array_name;
|
||||
int flags;
|
||||
builtin_find_indexed_array (char *array_name, int flags)
|
||||
{
|
||||
SHELL_VAR *entry;
|
||||
|
||||
if ((flags & 2) && legal_identifier (array_name) == 0)
|
||||
if ((flags & 2) && valid_identifier (array_name) == 0)
|
||||
{
|
||||
sh_invalidid (array_name);
|
||||
return (SHELL_VAR *)NULL;
|
||||
@@ -1061,8 +998,7 @@ builtin_find_indexed_array (array_name, flags)
|
||||
/* Like check_unbind_variable, but for use by builtins (only matters for
|
||||
error messages). */
|
||||
int
|
||||
builtin_unbind_variable (vname)
|
||||
const char *vname;
|
||||
builtin_unbind_variable (const char *vname)
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
@@ -1081,16 +1017,13 @@ builtin_unbind_variable (vname)
|
||||
}
|
||||
|
||||
int
|
||||
builtin_arrayref_flags (w, baseflags)
|
||||
WORD_DESC *w;
|
||||
int baseflags;
|
||||
builtin_arrayref_flags (WORD_DESC *w, int baseflags)
|
||||
{
|
||||
char *t;
|
||||
int vflags;
|
||||
|
||||
vflags = baseflags;
|
||||
|
||||
/* Don't require assoc_expand_once if we have an argument that's already
|
||||
/* Don't require array_expand_once if we have an argument that's already
|
||||
passed through valid_array_reference and been expanded once. That
|
||||
doesn't protect it from normal expansions like word splitting, so
|
||||
proper quoting is still required. */
|
||||
@@ -1099,7 +1032,7 @@ builtin_arrayref_flags (w, baseflags)
|
||||
|
||||
# if 0
|
||||
/* This is a little sketchier but handles quoted arguments. */
|
||||
if (assoc_expand_once && (t = strchr (w->word, '[')) && t[strlen(t) - 1] == ']')
|
||||
if (array_expand_once && (t = strchr (w->word, '[')) && t[strlen(t) - 1] == ']')
|
||||
vflags |= VA_ONEWORD|VA_NOEXPAND;
|
||||
# endif
|
||||
|
||||
@@ -1114,17 +1047,16 @@ builtin_arrayref_flags (w, baseflags)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
int
|
||||
set_expand_once (nval, uwp)
|
||||
int nval, uwp;
|
||||
set_expand_once (int nval, int uwp)
|
||||
{
|
||||
int oa;
|
||||
|
||||
oa = assoc_expand_once;
|
||||
oa = array_expand_once;
|
||||
if (shell_compatibility_level > 51) /* XXX - internal */
|
||||
{
|
||||
if (uwp)
|
||||
unwind_protect_int (assoc_expand_once);
|
||||
assoc_expand_once = nval;
|
||||
unwind_protect_int (array_expand_once);
|
||||
array_expand_once = nval;
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
+107
-107
@@ -81,163 +81,163 @@ do { \
|
||||
#define MAX_ATTRIBUTES 16
|
||||
|
||||
/* Functions from common.c */
|
||||
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 *));
|
||||
extern void builtin_error (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
|
||||
extern void builtin_warning (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
|
||||
extern void builtin_usage (void);
|
||||
extern void no_args (WORD_LIST *, int);
|
||||
extern int no_options (WORD_LIST *);
|
||||
|
||||
/* common error message functions */
|
||||
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_readonly PARAMS((const char *));
|
||||
extern void sh_noassign PARAMS((const char *));
|
||||
extern void sh_erange PARAMS((char *, char *));
|
||||
extern void sh_badpid PARAMS((char *));
|
||||
extern void sh_badjob PARAMS((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 void sh_needarg (const char *);
|
||||
extern void sh_neednumarg (const char *);
|
||||
extern void sh_notfound (const char *);
|
||||
extern void sh_invalidopt (const char *);
|
||||
extern void sh_invalidoptname (const char *);
|
||||
extern void sh_invalidid (const char *);
|
||||
extern void sh_invalidnum (const char *);
|
||||
extern void sh_invalidsig (const char *);
|
||||
extern void sh_readonly (const char *);
|
||||
extern void sh_noassign (const char *);
|
||||
extern void sh_erange (const char *, const char *);
|
||||
extern void sh_badpid (const char *);
|
||||
extern void sh_badjob (const char *);
|
||||
extern void sh_nojobs (const char *);
|
||||
extern void sh_restricted (const char *);
|
||||
extern void sh_notbuiltin (const char *);
|
||||
extern void sh_wrerror (void);
|
||||
extern void sh_ttyerror (int);
|
||||
extern int sh_chkwrite (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 char **make_builtin_argv (WORD_LIST *, int *);
|
||||
extern void remember_args (WORD_LIST *, int);
|
||||
extern void shift_args (int);
|
||||
extern int number_of_args (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 dollar_vars_changed (void);
|
||||
extern void set_dollar_vars_unchanged (void);
|
||||
extern void set_dollar_vars_changed (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 *));
|
||||
extern int get_numeric_arg (WORD_LIST *, int, intmax_t *);
|
||||
extern int get_exitstat (WORD_LIST *);
|
||||
extern int read_octal (char *);
|
||||
|
||||
/* Keeps track of the current working directory. */
|
||||
extern char *the_current_working_directory;
|
||||
extern char *get_working_directory PARAMS((char *));
|
||||
extern void set_working_directory PARAMS((char *));
|
||||
extern char *get_working_directory (const char *);
|
||||
extern void set_working_directory (const char *);
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
extern int get_job_by_name PARAMS((const char *, int));
|
||||
extern int get_job_spec PARAMS((WORD_LIST *));
|
||||
extern int get_job_by_name (const char *, int);
|
||||
extern int get_job_spec (WORD_LIST *);
|
||||
#endif
|
||||
extern int display_signal_list PARAMS((WORD_LIST *, int));
|
||||
extern int display_signal_list (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 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));
|
||||
extern struct builtin *builtin_address_internal (const char *, int);
|
||||
extern sh_builtin_func_t *find_shell_builtin (const char *);
|
||||
extern sh_builtin_func_t *builtin_address (const char *);
|
||||
extern sh_builtin_func_t *find_special_builtin (const char *);
|
||||
extern void initialize_shell_builtins (void);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
extern int set_expand_once PARAMS((int, int));
|
||||
extern int set_expand_once (int, int);
|
||||
#endif
|
||||
|
||||
/* Functions from exit.def */
|
||||
extern void bash_logout PARAMS((void));
|
||||
extern void bash_logout (void);
|
||||
|
||||
/* Functions from getopts.def */
|
||||
extern void getopts_reset PARAMS((int));
|
||||
extern void getopts_reset (int);
|
||||
|
||||
/* Functions from help.def */
|
||||
extern void builtin_help PARAMS((void));
|
||||
extern void builtin_help (void);
|
||||
|
||||
/* Functions from read.def */
|
||||
extern void read_tty_cleanup PARAMS((void));
|
||||
extern int read_tty_modified PARAMS((void));
|
||||
extern void read_tty_cleanup (void);
|
||||
extern int read_tty_modified (void);
|
||||
|
||||
extern int read_builtin_timeout PARAMS((int));
|
||||
extern void check_read_timeout PARAMS((void));
|
||||
extern int read_builtin_timeout (int);
|
||||
extern void check_read_timeout (void);
|
||||
|
||||
/* Functions from set.def */
|
||||
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 int minus_o_option_value (char *);
|
||||
extern void list_minus_o_opts (int, int);
|
||||
extern char **get_minus_o_opts (void);
|
||||
extern int set_minus_o_option (int, char *);
|
||||
|
||||
extern void set_shellopts PARAMS((void));
|
||||
extern void parse_shellopts PARAMS((char *));
|
||||
extern void initialize_shell_options PARAMS((int));
|
||||
extern void set_shellopts (void);
|
||||
extern void parse_shellopts (char *);
|
||||
extern void initialize_shell_options (int);
|
||||
|
||||
extern void reset_shell_options PARAMS((void));
|
||||
extern void reset_shell_options (void);
|
||||
|
||||
extern char *get_current_options PARAMS((void));
|
||||
extern void set_current_options PARAMS((const char *));
|
||||
extern char *get_current_options (void);
|
||||
extern void set_current_options (const char *);
|
||||
|
||||
/* Functions from shopt.def */
|
||||
extern void reset_shopt_options PARAMS((void));
|
||||
extern char **get_shopt_options PARAMS((void));
|
||||
extern void reset_shopt_options (void);
|
||||
extern char **get_shopt_options (void);
|
||||
|
||||
extern int shopt_setopt PARAMS((char *, int));
|
||||
extern int shopt_listopt PARAMS((char *, int));
|
||||
extern int shopt_setopt (char *, int);
|
||||
extern int shopt_listopt (char *, int);
|
||||
|
||||
extern int set_login_shell PARAMS((char *, int));
|
||||
extern int set_login_shell (char *, int);
|
||||
|
||||
extern void set_bashopts PARAMS((void));
|
||||
extern void parse_bashopts PARAMS((char *));
|
||||
extern void initialize_bashopts PARAMS((int));
|
||||
extern void set_bashopts (void);
|
||||
extern void parse_bashopts (char *);
|
||||
extern void initialize_bashopts (int);
|
||||
|
||||
extern void set_compatibility_opts PARAMS((void));
|
||||
extern void set_compatibility_opts (void);
|
||||
|
||||
/* Functions from type.def */
|
||||
extern int describe_command PARAMS((char *, int));
|
||||
extern int describe_command (char *, int);
|
||||
|
||||
/* Functions from setattr.def */
|
||||
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 *));
|
||||
extern int set_or_show_attributes (WORD_LIST *, int, int);
|
||||
extern int show_all_var_attributes (int, int);
|
||||
extern int show_local_var_attributes (int, int);
|
||||
extern int show_var_attributes (SHELL_VAR *, int, int);
|
||||
extern int show_name_attributes (char *, int);
|
||||
extern int show_localname_attributes (char *, int);
|
||||
extern int show_func_attributes (char *, int);
|
||||
extern void set_var_attribute (char *, int, int);
|
||||
extern int var_attribute_string (SHELL_VAR *, int, char *);
|
||||
|
||||
/* Functions from pushd.def */
|
||||
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));
|
||||
extern char *get_dirstack_from_string (char *);
|
||||
extern char *get_dirstack_element (intmax_t, int);
|
||||
extern void set_dirstack_element (intmax_t, int, char *);
|
||||
extern WORD_LIST *get_directory_stack (int);
|
||||
|
||||
/* Functions from evalstring.c */
|
||||
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, COMMAND **, char **));
|
||||
extern int should_suppress_fork PARAMS((COMMAND *));
|
||||
extern int can_optimize_connection PARAMS((COMMAND *));
|
||||
extern int can_optimize_cat_file PARAMS((COMMAND *));
|
||||
extern void optimize_connection_fork PARAMS((COMMAND *));
|
||||
extern void optimize_subshell_command PARAMS((COMMAND *));
|
||||
extern void optimize_shell_function PARAMS((COMMAND *));
|
||||
extern int parse_and_execute (char *, const char *, int);
|
||||
extern int evalstring (char *, const char *, int);
|
||||
extern void parse_and_execute_cleanup (int);
|
||||
extern int parse_string (char *, const char *, int, COMMAND **, char **);
|
||||
extern int should_suppress_fork (COMMAND *);
|
||||
extern int can_optimize_connection (COMMAND *);
|
||||
extern int can_optimize_cat_file (COMMAND *);
|
||||
extern void optimize_connection_fork (COMMAND *);
|
||||
extern void optimize_subshell_command (COMMAND *);
|
||||
extern void optimize_shell_function (COMMAND *);
|
||||
|
||||
/* Functions from evalfile.c */
|
||||
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 *));
|
||||
extern int maybe_execute_file (const char *, int);
|
||||
extern int force_execute_file (const char *, int);
|
||||
extern int source_file (const char *, int);
|
||||
extern int fc_execute_file (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 SHELL_VAR *builtin_bind_var_to_int PARAMS((char *, intmax_t, int));
|
||||
extern int builtin_unbind_variable PARAMS((const char *));
|
||||
extern SHELL_VAR *builtin_bind_variable (char *, char *, int);
|
||||
extern SHELL_VAR *builtin_bind_var_to_int (char *, intmax_t, int);
|
||||
extern int builtin_unbind_variable (const char *);
|
||||
|
||||
extern SHELL_VAR *builtin_find_indexed_array PARAMS((char *, int));
|
||||
extern int builtin_arrayref_flags PARAMS((WORD_DESC *, int));
|
||||
extern SHELL_VAR *builtin_find_indexed_array (char *, int);
|
||||
extern int builtin_arrayref_flags (WORD_DESC *, int);
|
||||
|
||||
/* variables from evalfile.c */
|
||||
extern int sourcelevel;
|
||||
@@ -275,9 +275,9 @@ extern int wait_intr_flag;
|
||||
#if defined (ARRAY_VARS)
|
||||
#define SET_VFLAGS(wordflags, vflags, bindflags) \
|
||||
do { \
|
||||
vflags = assoc_expand_once ? VA_NOEXPAND : 0; \
|
||||
bindflags = assoc_expand_once ? ASS_NOEXPAND : 0; \
|
||||
if (assoc_expand_once && (wordflags & W_ARRAYREF)) \
|
||||
vflags = array_expand_once ? VA_NOEXPAND : 0; \
|
||||
bindflags = array_expand_once ? ASS_NOEXPAND : 0; \
|
||||
if (array_expand_once && (wordflags & W_ARRAYREF)) \
|
||||
vflags |= VA_ONEWORD|VA_NOEXPAND; \
|
||||
if (vflags & VA_NOEXPAND) \
|
||||
bindflags |= ASS_NOEXPAND; \
|
||||
|
||||
+91
-65
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -27,8 +27,8 @@ $SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G glo
|
||||
Specify how arguments are to be completed by Readline.
|
||||
|
||||
For each NAME, specify how arguments are to be completed. If no options
|
||||
are supplied, existing completion specifications are printed in a way that
|
||||
allows them to be reused as input.
|
||||
or NAMEs are supplied, display existing completion specifications in a way
|
||||
that allows them to be reused as input.
|
||||
|
||||
Options:
|
||||
-p print existing completion specifications in a reusable format
|
||||
@@ -84,23 +84,23 @@ struct _optflags {
|
||||
int Iflag;
|
||||
};
|
||||
|
||||
static int find_compact PARAMS((char *));
|
||||
static int find_compopt PARAMS((char *));
|
||||
static int find_compact (char *);
|
||||
static int find_compopt (char *);
|
||||
|
||||
static int build_actions PARAMS((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *));
|
||||
static int build_actions (WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *, char **);
|
||||
|
||||
static int remove_cmd_completions PARAMS((WORD_LIST *));
|
||||
static int remove_cmd_completions (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 int print_one_completion (char *, COMPSPEC *);
|
||||
static int print_compitem (BUCKET_CONTENTS *);
|
||||
static void print_compopts (const char *, COMPSPEC *, int);
|
||||
static void print_all_completions (void);
|
||||
static int print_cmd_completions (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 void print_compoptions (unsigned long, int);
|
||||
static void print_compactions (unsigned long);
|
||||
static void print_arg (const char *, const char *, int);
|
||||
static void print_cmd_name (const char *);
|
||||
|
||||
static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
|
||||
|
||||
@@ -145,6 +145,7 @@ static const struct _compopt {
|
||||
{ "default", COPT_DEFAULT },
|
||||
{ "dirnames", COPT_DIRNAMES },
|
||||
{ "filenames",COPT_FILENAMES},
|
||||
{ "fullquote",COPT_FULLQUOTE},
|
||||
{ "noquote", COPT_NOQUOTE },
|
||||
{ "nosort", COPT_NOSORT },
|
||||
{ "nospace", COPT_NOSPACE },
|
||||
@@ -153,8 +154,7 @@ static const struct _compopt {
|
||||
};
|
||||
|
||||
static int
|
||||
find_compact (name)
|
||||
char *name;
|
||||
find_compact (char *name)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -165,8 +165,7 @@ find_compact (name)
|
||||
}
|
||||
|
||||
static int
|
||||
find_compopt (name)
|
||||
char *name;
|
||||
find_compopt (char *name)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -182,6 +181,8 @@ find_compopt (name)
|
||||
bitmap of compspec options (arguments to `-o'). PP, if non-null, gets 1
|
||||
if -p is supplied; RP, if non-null, gets 1 if -r is supplied.
|
||||
If either is null, the corresponding option generates an error.
|
||||
VNAMEP is a pointer to a string to store the name of the output variable
|
||||
supplied with the -V option.
|
||||
This also sets variables corresponding to options that take arguments as
|
||||
a side effect; the caller should ensure that those variables are set to
|
||||
NULL before calling build_actions. Return value:
|
||||
@@ -191,10 +192,7 @@ find_compopt (name)
|
||||
*/
|
||||
|
||||
static int
|
||||
build_actions (list, flagp, actp, optp)
|
||||
WORD_LIST *list;
|
||||
struct _optflags *flagp;
|
||||
unsigned long *actp, *optp;
|
||||
build_actions (WORD_LIST *list, struct _optflags *flagp, unsigned long *actp, unsigned long *optp, char **vnamep)
|
||||
{
|
||||
int opt, ind, opt_given;
|
||||
unsigned long acts, copts;
|
||||
@@ -204,7 +202,7 @@ build_actions (list, flagp, actp, optp)
|
||||
opt_given = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DEI")) != -1)
|
||||
while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:V:DEI")) != -1)
|
||||
{
|
||||
opt_given = 1;
|
||||
switch (opt)
|
||||
@@ -346,6 +344,25 @@ build_actions (list, flagp, actp, optp)
|
||||
case 'S':
|
||||
Sarg = list_optarg;
|
||||
break;
|
||||
case 'V':
|
||||
#if defined (ARRAY_VARS)
|
||||
if (vnamep)
|
||||
{
|
||||
*vnamep = list_optarg;
|
||||
if (valid_identifier (list_optarg) == 0)
|
||||
{
|
||||
sh_invalidid (list_optarg);
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sh_invalidopt ("-V");
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
Warg = list_optarg;
|
||||
break;
|
||||
@@ -367,8 +384,7 @@ build_actions (list, flagp, actp, optp)
|
||||
|
||||
/* Add, remove, and display completion specifiers. */
|
||||
int
|
||||
complete_builtin (list)
|
||||
WORD_LIST *list;
|
||||
complete_builtin (WORD_LIST *list)
|
||||
{
|
||||
int opt_given, rval;
|
||||
unsigned long acts, copts;
|
||||
@@ -391,7 +407,7 @@ complete_builtin (list)
|
||||
|
||||
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
|
||||
as a side effect if they are supplied as options. */
|
||||
rval = build_actions (list, &oflags, &acts, &copts);
|
||||
rval = build_actions (list, &oflags, &acts, &copts, (char **)NULL);
|
||||
if (rval == EX_USAGE)
|
||||
return (rval);
|
||||
opt_given = rval != EXECUTION_FAILURE;
|
||||
@@ -473,8 +489,7 @@ complete_builtin (list)
|
||||
}
|
||||
|
||||
static int
|
||||
remove_cmd_completions (list)
|
||||
WORD_LIST *list;
|
||||
remove_cmd_completions (WORD_LIST *list)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int ret;
|
||||
@@ -491,9 +506,7 @@ remove_cmd_completions (list)
|
||||
}
|
||||
|
||||
static void
|
||||
print_compoptions (copts, full)
|
||||
unsigned long copts;
|
||||
int full;
|
||||
print_compoptions (unsigned long copts, int full)
|
||||
{
|
||||
const struct _compopt *co;
|
||||
|
||||
@@ -505,8 +518,7 @@ print_compoptions (copts, full)
|
||||
}
|
||||
|
||||
static void
|
||||
print_compactions (acts)
|
||||
unsigned long acts;
|
||||
print_compactions (unsigned long acts)
|
||||
{
|
||||
const struct _compacts *ca;
|
||||
|
||||
@@ -522,9 +534,7 @@ print_compactions (acts)
|
||||
}
|
||||
|
||||
static void
|
||||
print_arg (arg, flag, quote)
|
||||
const char *arg, *flag;
|
||||
int quote;
|
||||
print_arg (const char *arg, const char *flag, int quote)
|
||||
{
|
||||
char *x;
|
||||
|
||||
@@ -538,8 +548,7 @@ print_arg (arg, flag, quote)
|
||||
}
|
||||
|
||||
static void
|
||||
print_cmd_name (cmd)
|
||||
const char *cmd;
|
||||
print_cmd_name (const char *cmd)
|
||||
{
|
||||
char *x;
|
||||
|
||||
@@ -562,9 +571,7 @@ print_cmd_name (cmd)
|
||||
}
|
||||
|
||||
static int
|
||||
print_one_completion (cmd, cs)
|
||||
char *cmd;
|
||||
COMPSPEC *cs;
|
||||
print_one_completion (char *cmd, COMPSPEC *cs)
|
||||
{
|
||||
printf ("complete ");
|
||||
|
||||
@@ -592,10 +599,7 @@ print_one_completion (cmd, cs)
|
||||
}
|
||||
|
||||
static void
|
||||
print_compopts (cmd, cs, full)
|
||||
const char *cmd;
|
||||
COMPSPEC *cs;
|
||||
int full;
|
||||
print_compopts (const char *cmd, COMPSPEC *cs, int full)
|
||||
{
|
||||
printf ("compopt ");
|
||||
|
||||
@@ -606,8 +610,7 @@ print_compopts (cmd, cs, full)
|
||||
}
|
||||
|
||||
static int
|
||||
print_compitem (item)
|
||||
BUCKET_CONTENTS *item;
|
||||
print_compitem (BUCKET_CONTENTS *item)
|
||||
{
|
||||
COMPSPEC *cs;
|
||||
char *cmd;
|
||||
@@ -619,14 +622,13 @@ print_compitem (item)
|
||||
}
|
||||
|
||||
static void
|
||||
print_all_completions ()
|
||||
print_all_completions (void)
|
||||
{
|
||||
progcomp_walk (print_compitem);
|
||||
}
|
||||
|
||||
static int
|
||||
print_cmd_completions (list)
|
||||
WORD_LIST *list;
|
||||
print_cmd_completions (WORD_LIST *list)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
COMPSPEC *cs;
|
||||
@@ -650,20 +652,22 @@ 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 [-V varname] [-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
|
||||
completions. If the optional WORD argument is supplied, matches against
|
||||
WORD are generated.
|
||||
completions. If the optional WORD argument is present, generate matches
|
||||
against WORD.
|
||||
|
||||
If the -V option is supplied, store the possible completions in the indexed
|
||||
array VARNAME instead of printing them to the standard output.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or an error occurs.
|
||||
$END
|
||||
|
||||
int
|
||||
compgen_builtin (list)
|
||||
WORD_LIST *list;
|
||||
compgen_builtin (WORD_LIST *list)
|
||||
{
|
||||
int rval;
|
||||
unsigned long acts, copts;
|
||||
@@ -671,7 +675,9 @@ compgen_builtin (list)
|
||||
STRINGLIST *sl;
|
||||
char *word, **matches;
|
||||
char *old_line;
|
||||
int old_ind;
|
||||
int old_ind, old_completion, old_quoting, old_suppress;
|
||||
SHELL_VAR *var;
|
||||
char *varname;
|
||||
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
@@ -679,10 +685,11 @@ compgen_builtin (list)
|
||||
acts = copts = (unsigned long)0L;
|
||||
Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
|
||||
cs = (COMPSPEC *)NULL;
|
||||
varname = 0;
|
||||
|
||||
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
|
||||
as a side effect if they are supplied as options. */
|
||||
rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts);
|
||||
rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts, &varname);
|
||||
if (rval == EX_USAGE)
|
||||
return (rval);
|
||||
if (rval == EXECUTION_FAILURE)
|
||||
@@ -713,6 +720,12 @@ compgen_builtin (list)
|
||||
|
||||
rval = EXECUTION_FAILURE;
|
||||
|
||||
old_completion = rl_filename_completion_desired;
|
||||
old_quoting = rl_filename_quoting_desired;
|
||||
old_suppress = rl_completion_suppress_append;
|
||||
|
||||
bashline_set_filename_hooks ();
|
||||
|
||||
/* probably don't have to save these, just being safe */
|
||||
old_line = pcomp_line;
|
||||
old_ind = pcomp_ind;
|
||||
@@ -741,15 +754,29 @@ compgen_builtin (list)
|
||||
strvec_dispose (matches);
|
||||
}
|
||||
|
||||
if (sl)
|
||||
rl_filename_completion_desired = old_completion;
|
||||
rl_filename_quoting_desired = old_quoting;
|
||||
rl_completion_suppress_append = old_suppress;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (varname)
|
||||
{
|
||||
if (sl->list && sl->list_len)
|
||||
var = builtin_find_indexed_array (varname, 1);
|
||||
if (var && sl && sl->list && sl->list_len)
|
||||
{
|
||||
array_from_argv (array_cell (var), sl->list, sl->list_len);
|
||||
rval = EXECUTION_SUCCESS;
|
||||
strlist_print (sl, (char *)NULL);
|
||||
}
|
||||
strlist_dispose (sl);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (sl && sl->list && sl->list_len)
|
||||
{
|
||||
rval = EXECUTION_SUCCESS;
|
||||
strlist_print (sl, (char *)NULL);
|
||||
}
|
||||
if (sl)
|
||||
strlist_dispose (sl);
|
||||
|
||||
compspec_dispose (cs);
|
||||
return (rval);
|
||||
@@ -787,8 +814,7 @@ have a completion specification defined.
|
||||
$END
|
||||
|
||||
int
|
||||
compopt_builtin (list)
|
||||
WORD_LIST *list;
|
||||
compopt_builtin (WORD_LIST *list)
|
||||
{
|
||||
int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag, Iflag;
|
||||
WORD_LIST *l, *wl;
|
||||
|
||||
+120
-59
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -49,7 +49,8 @@ Options which set attributes:
|
||||
-u to convert the value of each NAME to upper case on assignment
|
||||
-x to make NAMEs export
|
||||
|
||||
Using `+' instead of `-' turns off the given attribute.
|
||||
Using `+' instead of `-' turns off the given attribute, except for a,
|
||||
A, and r.
|
||||
|
||||
Variables with the integer attribute have arithmetic evaluation (see
|
||||
the `let' command) performed when the variable is assigned a value.
|
||||
@@ -90,16 +91,15 @@ $END
|
||||
#include "builtext.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
static SHELL_VAR *declare_find_variable PARAMS((const char *, int, int));
|
||||
static char *declare_build_newname PARAMS((char *, char *, int, char *, int));
|
||||
static char *declare_transform_name PARAMS((char *, int, int));
|
||||
static SHELL_VAR *declare_find_variable (const char *, int, int);
|
||||
static char *declare_build_newname (char *, char *, int, char *, int);
|
||||
static char *declare_transform_name (char *, int, int);
|
||||
|
||||
static int declare_internal PARAMS((register WORD_LIST *, int));
|
||||
static int declare_internal (register WORD_LIST *, int);
|
||||
|
||||
/* Declare or change variable attributes. */
|
||||
int
|
||||
declare_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
declare_builtin (WORD_LIST *list)
|
||||
{
|
||||
return (declare_internal (list, 0));
|
||||
}
|
||||
@@ -120,8 +120,7 @@ Returns success unless an invalid option is supplied, a variable
|
||||
assignment error occurs, or the shell is not executing a function.
|
||||
$END
|
||||
int
|
||||
local_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
local_builtin (WORD_LIST *list)
|
||||
{
|
||||
/* Catch a straight `local --help' before checking function context */
|
||||
if (list && list->word && STREQ (list->word->word, "--help"))
|
||||
@@ -146,9 +145,7 @@ local_builtin (list)
|
||||
#endif
|
||||
|
||||
static SHELL_VAR *
|
||||
declare_find_variable (name, mkglobal, chklocal)
|
||||
const char *name;
|
||||
int mkglobal, chklocal;
|
||||
declare_find_variable (const char *name, int mkglobal, int chklocal)
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
@@ -169,11 +166,7 @@ declare_find_variable (name, mkglobal, chklocal)
|
||||
NAME[SUBSCRIPT][[+]=VALUE]
|
||||
from expanding a nameref into NAME */
|
||||
static char *
|
||||
declare_build_newname (name, subscript_start, offset, value, aflags)
|
||||
char *name, *subscript_start;
|
||||
int offset;
|
||||
char *value;
|
||||
int aflags;
|
||||
declare_build_newname (char *name, char *subscript_start, int offset, char *value, int aflags)
|
||||
{
|
||||
size_t namelen, savelen;
|
||||
char *ret;
|
||||
@@ -203,9 +196,7 @@ declare_build_newname (name, subscript_start, offset, value, aflags)
|
||||
}
|
||||
|
||||
static char *
|
||||
declare_transform_name (name, flags_on, flags_off)
|
||||
char *name;
|
||||
int flags_on, flags_off;
|
||||
declare_transform_name (char *name, int flags_on, int flags_off)
|
||||
{
|
||||
SHELL_VAR *var, *v;
|
||||
char *newname;
|
||||
@@ -227,11 +218,48 @@ declare_transform_name (name, flags_on, flags_off)
|
||||
return (newname);
|
||||
}
|
||||
|
||||
/* Some option combinations that don't make any sense */
|
||||
static int
|
||||
declare_invalid_opts (int flags_on, int flags_off)
|
||||
{
|
||||
if ((flags_on & att_function) && (flags_on & (att_array|att_assoc|att_integer|att_nameref)))
|
||||
{
|
||||
char *optchar;
|
||||
|
||||
if (flags_on & att_nameref)
|
||||
optchar = "-n";
|
||||
else if (flags_on & att_integer)
|
||||
optchar = "-i";
|
||||
else if (flags_on & att_assoc)
|
||||
optchar = "-A";
|
||||
else if (flags_on & att_array)
|
||||
optchar = "-a";
|
||||
|
||||
sh_invalidopt (optchar);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else if ((flags_on & att_assoc) && (flags_off & att_assoc))
|
||||
{
|
||||
sh_invalidopt ("-A");
|
||||
return (EX_BADUSAGE);
|
||||
}
|
||||
else if ((flags_on & att_array) && (flags_off & att_array))
|
||||
{
|
||||
sh_invalidopt ("-a");
|
||||
return (EX_BADUSAGE);
|
||||
}
|
||||
else if ((flags_on & att_assoc) && (flags_on & att_array))
|
||||
{
|
||||
sh_invalidopt ("-a");
|
||||
return (EX_BADUSAGE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The workhorse function. */
|
||||
static int
|
||||
declare_internal (list, local_var)
|
||||
register WORD_LIST *list;
|
||||
int local_var;
|
||||
declare_internal (WORD_LIST *list, int local_var)
|
||||
{
|
||||
int flags_on, flags_off, *flags;
|
||||
int any_failed, assign_error, pflag, nodefs, opt, onref, offref;
|
||||
@@ -255,6 +283,10 @@ declare_internal (list, local_var)
|
||||
case 'a':
|
||||
#if defined (ARRAY_VARS)
|
||||
*flags |= att_array;
|
||||
#if 0
|
||||
if (flags == &flags_on)
|
||||
*flags &= ~att_assoc; /* last one wins */
|
||||
#endif
|
||||
break;
|
||||
#else
|
||||
builtin_usage ();
|
||||
@@ -263,6 +295,10 @@ declare_internal (list, local_var)
|
||||
case 'A':
|
||||
#if defined (ARRAY_VARS)
|
||||
*flags |= att_assoc;
|
||||
#if 0
|
||||
if (flags == &flags_on)
|
||||
*flags &= ~att_array; /* last one wins */
|
||||
#endif
|
||||
break;
|
||||
#else
|
||||
builtin_usage ();
|
||||
@@ -370,24 +406,11 @@ declare_internal (list, local_var)
|
||||
return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
/* Some option combinations that don't make any sense */
|
||||
if ((flags_on & att_function) && (flags_on & (att_array|att_assoc|att_integer|att_nameref)))
|
||||
{
|
||||
char *optchar;
|
||||
|
||||
if (flags_on & att_nameref)
|
||||
optchar = "-n";
|
||||
else if (flags_on & att_integer)
|
||||
optchar = "-i";
|
||||
else if (flags_on & att_assoc)
|
||||
optchar = "-A";
|
||||
else if (flags_on & att_array)
|
||||
optchar = "-a";
|
||||
|
||||
sh_invalidopt (optchar);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* check for some invalid option combinations that are usage errors */
|
||||
opt = declare_invalid_opts (flags_on, flags_off);
|
||||
if (opt != 0)
|
||||
return (opt);
|
||||
|
||||
#define NEXT_VARIABLE() free (name); list = list->next; continue
|
||||
|
||||
/* There are arguments left, so we are making variables. */
|
||||
@@ -404,7 +427,7 @@ declare_internal (list, local_var)
|
||||
name = savestring (list->word->word);
|
||||
wflags = list->word->flags;
|
||||
#if defined (ARRAY_VARS)
|
||||
assoc_noexpand = assoc_expand_once && (wflags & W_ASSIGNMENT);
|
||||
assoc_noexpand = array_expand_once && (wflags & W_ASSIGNMENT);
|
||||
#else
|
||||
assoc_noexpand = 0;
|
||||
#endif
|
||||
@@ -442,9 +465,14 @@ declare_internal (list, local_var)
|
||||
/* Can't define functions using assignment statements */
|
||||
if (offset && (flags_on & att_function)) /* declare -f [-rix] foo=bar */
|
||||
{
|
||||
builtin_error (_("cannot use `-f' to make functions"));
|
||||
free (name);
|
||||
return (EXECUTION_FAILURE);
|
||||
if (var = find_function (name))
|
||||
offset = 0;
|
||||
else
|
||||
{
|
||||
builtin_error (_("cannot use `-f' to make functions"));
|
||||
free (name);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* There should be a way, however, to let people look at a particular
|
||||
@@ -456,7 +484,7 @@ declare_internal (list, local_var)
|
||||
/* Should we restrict this when the shell is in posix mode even if
|
||||
the function was created before the shell entered posix mode?
|
||||
Previous versions of the shell enforced the restriction. */
|
||||
if (posixly_correct && legal_identifier (name) == 0)
|
||||
if (posixly_correct && valid_identifier (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
assign_error++;
|
||||
@@ -583,7 +611,7 @@ restart_new_var_name:
|
||||
#endif
|
||||
|
||||
/* Ensure the argument is a valid, well-formed shell identifier. */
|
||||
if (legal_identifier (name) == 0)
|
||||
if (valid_identifier (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
assign_error++;
|
||||
@@ -644,6 +672,10 @@ restart_new_var_name:
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
/* See below; ksh93 doesn't allow the nameref attribute to be removed
|
||||
from a readonly nameref that has a value, even if it doesn't
|
||||
reference an existing variable, so we don't allow it for
|
||||
compatibility. */
|
||||
if (var && nameref_p (var) && readonly_p (var) && nameref_cell (var) && (flags_off & att_nameref))
|
||||
{
|
||||
sh_readonly (name);
|
||||
@@ -683,7 +715,7 @@ restart_new_var_name:
|
||||
if (refvar && nameref_p (refvar) == 0)
|
||||
refvar = 0;
|
||||
/* If the nameref is readonly but doesn't have a value, ksh93
|
||||
allows the nameref attribute to be removed. If it's readonly
|
||||
allows the nameref attribute to be removed. If it's readonly
|
||||
and has a value, even if the value doesn't reference an
|
||||
existing variable, we disallow the modification */
|
||||
if (refvar && nameref_cell (refvar) && readonly_p (refvar))
|
||||
@@ -850,10 +882,26 @@ restart_new_var_name:
|
||||
else if ((readonly_p (var) || noassign_p (var)) && offset)
|
||||
{
|
||||
if (readonly_p (var))
|
||||
sh_readonly (name);
|
||||
assign_error++;
|
||||
{
|
||||
sh_readonly (name);
|
||||
assign_error++;
|
||||
}
|
||||
/* just ignore attempts to assign to noassign variables; returning
|
||||
EXECUTION_FAILURE would cause set -e to exit the shell. */
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
#if 1
|
||||
/* TAG:bash-5.3 20240216 */
|
||||
/* Cannot set or unset invalid attributes on readonly variables */
|
||||
else if (readonly_p (var) && ((flags_on & invalid_readonly_attrs) || (flags_off & invalid_readonly_attrs)))
|
||||
{
|
||||
/* The restrictions on namerefs and readonly variables are handled
|
||||
above. */
|
||||
sh_readonly (name_cell (var));
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
/* Array variable error checking. */
|
||||
@@ -884,7 +932,7 @@ restart_new_var_name:
|
||||
simple_array_assign = 1;
|
||||
else if ((making_array_special || creating_array || array_exists) && offset)
|
||||
{
|
||||
int vlen;
|
||||
size_t vlen;
|
||||
vlen = STRLEN (value);
|
||||
/*itrace("declare_builtin: name = %s value = %s flags = %d", name, value, wflags);*/
|
||||
|
||||
@@ -1001,7 +1049,10 @@ restart_new_var_name:
|
||||
/* If we found this variable in the temporary environment, as with
|
||||
`var=value declare -x var', make sure it is treated identically
|
||||
to `var=value export var'. Do the same for `declare -r' and
|
||||
`readonly'. Preserve the attributes, except for att_tempvar. */
|
||||
`readonly'. Preserve the attributes, except for att_tempvar.
|
||||
This doesn't happen in functions, since declare in shell functions
|
||||
always creates local variables (that inherit their value from the
|
||||
tempenv variable). We don't check variable_context; maybe we should. */
|
||||
/* XXX -- should this create a variable in the global scope, or
|
||||
modify the local variable flags? ksh93 has it modify the
|
||||
global scope.
|
||||
@@ -1010,22 +1061,32 @@ restart_new_var_name:
|
||||
if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var))
|
||||
{
|
||||
SHELL_VAR *tv;
|
||||
char *tvalue;
|
||||
|
||||
/* Temporary environment? Or in the local variable context? */
|
||||
tv = find_tempenv_variable (name_cell (var));
|
||||
if (tv)
|
||||
{
|
||||
tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring ("");
|
||||
tv = bind_variable (name_cell (var), tvalue, 0);
|
||||
/* We don't bother with modifying the temporary env because
|
||||
we're already using it. */
|
||||
tv = bind_variable (name_cell (var), value_cell (var), ASS_NOTEMPENV);
|
||||
|
||||
if (tv)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
/* copy array value if array variable */
|
||||
if ((array_p (var) || assoc_p (var)))
|
||||
arrayvar_copyval (var, tv);
|
||||
#endif
|
||||
/* then copy attributes */
|
||||
tv->attributes |= var->attributes & ~att_tempvar;
|
||||
if (tv->context > 0)
|
||||
if (tv->context > 0 && local_p (var) == 0) /* just paranoia here */
|
||||
VSETATTR (tv, att_propagate);
|
||||
}
|
||||
free (tvalue);
|
||||
}
|
||||
VSETATTR (var, att_propagate);
|
||||
/* XXX - don't propagate local variables back to a previous scope,
|
||||
even in posix mode. */
|
||||
if (local_p (var) == 0)
|
||||
VSETATTR (var, att_propagate);
|
||||
}
|
||||
|
||||
/* Turn on nameref attribute we deferred above. */
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
This file is echo.def, from which is created echo.c.
|
||||
It implements the builtin "echo" in Bash.
|
||||
|
||||
Copyright (C) 1987-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2018,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -107,10 +107,10 @@ int xpg_echo = 0;
|
||||
`-n', then don't print a trailing newline. We also support the
|
||||
echo syntax from Version 9 Unix systems. */
|
||||
int
|
||||
echo_builtin (list)
|
||||
WORD_LIST *list;
|
||||
echo_builtin (WORD_LIST *list)
|
||||
{
|
||||
int display_return, do_v9, i, len;
|
||||
int display_return, do_v9, i;
|
||||
size_t len;
|
||||
char *temp, *s;
|
||||
|
||||
do_v9 = xpg_echo;
|
||||
|
||||
+66
-56
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -41,6 +41,11 @@ Options controlling dynamic loading:
|
||||
|
||||
Without options, each NAME is enabled.
|
||||
|
||||
On systems with dynamic loading, the shell variable BASH_LOADABLES_PATH
|
||||
defines a search path for the directory containing FILENAMEs that do
|
||||
not contain a slash. It may include "." to force a search of the current
|
||||
directory.
|
||||
|
||||
To use the `test' found in $PATH instead of the shell builtin
|
||||
version, type `enable -n test'.
|
||||
|
||||
@@ -85,13 +90,13 @@ $END
|
||||
#define SFLAG 0x20
|
||||
|
||||
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||
static int dyn_load_builtin PARAMS((WORD_LIST *, int, char *));
|
||||
static int dyn_load_builtin (WORD_LIST *, int, char *);
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_DLCLOSE)
|
||||
static int dyn_unload_builtin PARAMS((char *));
|
||||
static void delete_builtin PARAMS((struct builtin *));
|
||||
static int local_dlclose PARAMS((void *));
|
||||
static int dyn_unload_builtin (char *);
|
||||
static void delete_builtin (struct builtin *);
|
||||
static int local_dlclose (void *);
|
||||
#endif
|
||||
|
||||
#define STRUCT_SUFFIX "_struct"
|
||||
@@ -99,15 +104,14 @@ static int local_dlclose PARAMS((void *));
|
||||
#define LOAD_SUFFIX "_builtin_load"
|
||||
#define UNLOAD_SUFFIX "_builtin_unload"
|
||||
|
||||
static void list_some_builtins PARAMS((int));
|
||||
static int enable_shell_command PARAMS((char *, int));
|
||||
static void list_some_builtins (int);
|
||||
static int enable_shell_command (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
|
||||
which are disabled. */
|
||||
int
|
||||
enable_builtin (list)
|
||||
WORD_LIST *list;
|
||||
enable_builtin (WORD_LIST *list)
|
||||
{
|
||||
int result, flags;
|
||||
int opt, filter;
|
||||
@@ -194,6 +198,8 @@ enable_builtin (list)
|
||||
result = EXECUTION_FAILURE; /* normalize return value */
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
set_itemlist_dirty (&it_builtins);
|
||||
set_itemlist_dirty (&it_enabled);
|
||||
set_itemlist_dirty (&it_disabled);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -209,6 +215,8 @@ enable_builtin (list)
|
||||
}
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
set_itemlist_dirty (&it_builtins);
|
||||
set_itemlist_dirty (&it_enabled);
|
||||
set_itemlist_dirty (&it_disabled);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -216,32 +224,37 @@ enable_builtin (list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
opt = enable_shell_command (list->word->word, flags & NFLAG);
|
||||
char *command;
|
||||
|
||||
command = list->word->word;
|
||||
opt = enable_shell_command (command, flags & NFLAG);
|
||||
next = list->next;
|
||||
|
||||
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
|
||||
/* If we try to enable a non-existent builtin, and we have dynamic
|
||||
loading, try the equivalent of `enable -f name name'. */
|
||||
if (opt == EX_NOTFOUND)
|
||||
if (*command && (flags & NFLAG) == 0 && opt == EX_NOTFOUND)
|
||||
{
|
||||
int dflags, r;
|
||||
|
||||
dflags = ENABLED|SILENT|((flags & SFLAG) ? SPECIAL : 0);
|
||||
|
||||
list->next = 0;
|
||||
r = dyn_load_builtin (list, dflags, list->word->word);
|
||||
r = dyn_load_builtin (list, dflags, command);
|
||||
list->next = next;
|
||||
if (r == EXECUTION_SUCCESS)
|
||||
opt = r;
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
set_itemlist_dirty (&it_builtins);
|
||||
set_itemlist_dirty (&it_enabled);
|
||||
set_itemlist_dirty (&it_disabled);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (opt == EX_NOTFOUND)
|
||||
{
|
||||
sh_notbuiltin (list->word->word);
|
||||
sh_notbuiltin (command);
|
||||
result = EXECUTION_FAILURE;
|
||||
}
|
||||
else if (opt != EXECUTION_SUCCESS)
|
||||
@@ -254,10 +267,9 @@ enable_builtin (list)
|
||||
}
|
||||
|
||||
/* List some builtins.
|
||||
FILTER is a mask with two slots: ENABLED and DISABLED. */
|
||||
FILTER is a mask with three slots: SPECIAL, ENABLED, and DISABLED. */
|
||||
static void
|
||||
list_some_builtins (filter)
|
||||
int filter;
|
||||
list_some_builtins (int filter)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -281,9 +293,7 @@ list_some_builtins (filter)
|
||||
/* Enable the shell command NAME. If DISABLE_P is non-zero, then
|
||||
disable NAME instead. */
|
||||
static int
|
||||
enable_shell_command (name, disable_p)
|
||||
char *name;
|
||||
int disable_p;
|
||||
enable_shell_command (char *name, int disable_p)
|
||||
{
|
||||
struct builtin *b;
|
||||
|
||||
@@ -318,15 +328,13 @@ enable_shell_command (name, disable_p)
|
||||
#endif
|
||||
|
||||
static int
|
||||
dyn_load_builtin (list, flags, filename)
|
||||
WORD_LIST *list;
|
||||
int flags;
|
||||
char *filename;
|
||||
dyn_load_builtin (WORD_LIST *list, int flags, char *filename)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
void *handle;
|
||||
|
||||
int total, size, new, replaced, r;
|
||||
int total, replaced, r;
|
||||
size_t size, new;
|
||||
char *struct_name, *name, *funcname;
|
||||
sh_load_func_t *loadfunc;
|
||||
struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin;
|
||||
@@ -339,32 +347,33 @@ dyn_load_builtin (list, flags, filename)
|
||||
#define RTLD_LAZY 1
|
||||
#endif
|
||||
|
||||
handle = 0;
|
||||
if (absolute_program (filename) == 0)
|
||||
{
|
||||
loadables_path = get_string_value ("BASH_LOADABLES_PATH");
|
||||
if (loadables_path)
|
||||
{
|
||||
load_path = find_in_path (filename, loadables_path, FS_NODIRS|FS_EXEC_PREFERRED);
|
||||
if (load_path)
|
||||
{
|
||||
#if defined (_AIX)
|
||||
handle = dlopen (load_path, RTLD_NOW|RTLD_GLOBAL);
|
||||
# define DLFLAGS (RTLD_NOW|RTLD_GLOBAL)
|
||||
#else
|
||||
handle = dlopen (load_path, RTLD_LAZY);
|
||||
# define DLFLAGS RTLD_LAZY
|
||||
#endif /* !_AIX */
|
||||
free (load_path);
|
||||
}
|
||||
|
||||
handle = 0;
|
||||
if (absolute_program (filename))
|
||||
handle = dlopen (filename, DLFLAGS);
|
||||
else if (loadables_path = path_value ("BASH_LOADABLES_PATH", 1))
|
||||
{
|
||||
/* If we have a loadables path, don't fall back to the current directory. */
|
||||
load_path = find_in_path (filename, loadables_path, FS_NODIRS|FS_EXEC_PREFERRED);
|
||||
if (load_path)
|
||||
{
|
||||
handle = dlopen (load_path, DLFLAGS);
|
||||
free (load_path);
|
||||
}
|
||||
}
|
||||
else /* no loadables path, look in current directory */
|
||||
{
|
||||
char *openname;
|
||||
|
||||
/* Fall back to current directory for now */
|
||||
if (handle == 0)
|
||||
#if defined (_AIX)
|
||||
handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
|
||||
#else
|
||||
handle = dlopen (filename, RTLD_LAZY);
|
||||
#endif /* !_AIX */
|
||||
openname = make_absolute (filename, ".");
|
||||
handle = dlopen (openname, DLFLAGS);
|
||||
free (openname);
|
||||
}
|
||||
|
||||
if (handle == 0)
|
||||
{
|
||||
@@ -387,9 +396,14 @@ dyn_load_builtin (list, flags, filename)
|
||||
/* For each new builtin in the shared object, find it and its describing
|
||||
structure. If this is overwriting an existing builtin, do so, otherwise
|
||||
save the loaded struct for creating the new list of builtins. */
|
||||
for (replaced = new = 0; list; list = list->next)
|
||||
for (replaced = 0, new = 0; list; list = list->next)
|
||||
{
|
||||
name = list->word->word;
|
||||
if (absolute_program (name))
|
||||
{
|
||||
builtin_error (_("%s: builtin names may not contain slashes"), name);
|
||||
continue;
|
||||
}
|
||||
|
||||
size = strlen (name);
|
||||
struct_name = (char *)xmalloc (size + 8);
|
||||
@@ -433,6 +447,8 @@ dyn_load_builtin (list, flags, filename)
|
||||
b->flags &= ~STATIC_BUILTIN;
|
||||
if (flags & SPECIAL)
|
||||
b->flags |= SPECIAL_BUILTIN;
|
||||
if (flags & DISABLED)
|
||||
b->flags &= ~BUILTIN_ENABLED;
|
||||
b->handle = handle;
|
||||
|
||||
if (old_builtin)
|
||||
@@ -483,18 +499,13 @@ dyn_load_builtin (list, flags, filename)
|
||||
|
||||
#if defined (HAVE_DLCLOSE)
|
||||
static void
|
||||
delete_builtin (b)
|
||||
struct builtin *b;
|
||||
delete_builtin (struct builtin *b)
|
||||
{
|
||||
int ind, size;
|
||||
struct builtin *new_shell_builtins;
|
||||
|
||||
/* XXX - funky pointer arithmetic - XXX */
|
||||
#ifdef __STDC__
|
||||
ind = b - shell_builtins;
|
||||
#else
|
||||
ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
|
||||
#endif
|
||||
size = num_shell_builtins * sizeof (struct builtin);
|
||||
new_shell_builtins = (struct builtin *)xmalloc (size);
|
||||
|
||||
@@ -519,8 +530,7 @@ delete_builtin (b)
|
||||
/* Tenon's MachTen has a dlclose that doesn't return a value, so we
|
||||
finesse it with a local wrapper. */
|
||||
static int
|
||||
local_dlclose (handle)
|
||||
void *handle;
|
||||
local_dlclose (void *handle)
|
||||
{
|
||||
#if !defined (__MACHTEN__)
|
||||
return (dlclose (handle));
|
||||
@@ -531,14 +541,14 @@ local_dlclose (handle)
|
||||
}
|
||||
|
||||
static int
|
||||
dyn_unload_builtin (name)
|
||||
char *name;
|
||||
dyn_unload_builtin (char *name)
|
||||
{
|
||||
struct builtin *b;
|
||||
void *handle;
|
||||
char *funcname;
|
||||
sh_unload_func_t *unloadfunc;
|
||||
int ref, i, size;
|
||||
int ref, i;
|
||||
size_t size;
|
||||
|
||||
b = builtin_address_internal (name, 1);
|
||||
if (b == 0)
|
||||
|
||||
+2
-3
@@ -1,7 +1,7 @@
|
||||
This file is eval.def, from which is created eval.c.
|
||||
It implements the builtin "eval" in Bash.
|
||||
|
||||
Copyright (C) 1987-2016 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2016,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -46,8 +46,7 @@ $END
|
||||
|
||||
/* Parse the string that these words make, and execute the command found. */
|
||||
int
|
||||
eval_builtin (list)
|
||||
WORD_LIST *list;
|
||||
eval_builtin (WORD_LIST *list)
|
||||
{
|
||||
if (no_options (list))
|
||||
return (EX_USAGE);
|
||||
|
||||
+36
-31
@@ -1,6 +1,6 @@
|
||||
/* evalfile.c - read and evaluate commands from a file or file descriptor */
|
||||
|
||||
/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996-2017,2022-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -68,14 +68,13 @@ extern int errno;
|
||||
#define FEVAL_CHECKBINARY 0x040
|
||||
#define FEVAL_REGFILE 0x080
|
||||
#define FEVAL_NOPUSHARGS 0x100
|
||||
#define FEVAL_RETRY 0x200
|
||||
|
||||
/* How many `levels' of sourced files we have. */
|
||||
int sourcelevel = 0;
|
||||
|
||||
static int
|
||||
_evalfile (filename, flags)
|
||||
const char *filename;
|
||||
int flags;
|
||||
_evalfile (const char *filename, int flags)
|
||||
{
|
||||
volatile int old_interactive;
|
||||
procenv_t old_return_catch;
|
||||
@@ -98,17 +97,16 @@ _evalfile (filename, flags)
|
||||
|
||||
USE_VAR(pflags);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
|
||||
# if defined (DEBUGGER)
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
fd = open (filename, O_RDONLY);
|
||||
errno = 0;
|
||||
do
|
||||
{
|
||||
fd = open (filename, O_RDONLY);
|
||||
i = errno;
|
||||
if (fd < 0 && i == EINTR)
|
||||
QUIT;
|
||||
errno = i;
|
||||
}
|
||||
while (fd < 0 && errno == EINTR && (flags & FEVAL_RETRY));
|
||||
|
||||
if (fd < 0 || (fstat (fd, &finfo) == -1))
|
||||
{
|
||||
@@ -153,7 +151,7 @@ file_error_and_exit:
|
||||
(*errfunc) (_("%s: file is too large"), filename);
|
||||
close (fd);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
|
||||
{
|
||||
@@ -161,6 +159,8 @@ file_error_and_exit:
|
||||
nr = read (fd, string, file_size);
|
||||
if (nr >= 0)
|
||||
string[nr] = '\0';
|
||||
if (nr != file_size)
|
||||
nr = -1; /* XXX - didn't get the whole file */
|
||||
}
|
||||
else
|
||||
nr = zmapfd (fd, &string, 0);
|
||||
@@ -218,6 +218,7 @@ file_error_and_exit:
|
||||
if (flags & FEVAL_NONINT)
|
||||
unwind_protect_int (interactive);
|
||||
unwind_protect_int (sourcelevel);
|
||||
unwind_protect_int (retain_fifos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -232,7 +233,17 @@ file_error_and_exit:
|
||||
return_catch_flag++;
|
||||
sourcelevel++;
|
||||
|
||||
retain_fifos++; /* XXX */
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
|
||||
# if defined (DEBUGGER)
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
|
||||
# endif
|
||||
|
||||
array_push (bash_source_a, (char *)filename);
|
||||
t = itos (executing_line_number ());
|
||||
array_push (bash_lineno_a, t);
|
||||
@@ -247,7 +258,7 @@ file_error_and_exit:
|
||||
fa->funcname_a = funcname_a;
|
||||
fa->funcname_v = funcname_v;
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
add_unwind_protect (restore_funcarray_state, fa);
|
||||
add_unwind_protect (uw_restore_funcarray_state, fa);
|
||||
|
||||
# if defined (DEBUGGER)
|
||||
/* Have to figure out a better way to do this when `source' is supplied
|
||||
@@ -260,7 +271,7 @@ file_error_and_exit:
|
||||
tt[0] = '1'; tt[1] = '\0';
|
||||
array_push (bash_argc_a, tt);
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
add_unwind_protect (pop_args, 0);
|
||||
add_unwind_protect (uw_pop_args, 0);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
@@ -304,6 +315,7 @@ file_error_and_exit:
|
||||
#endif
|
||||
return_catch_flag--;
|
||||
sourcelevel--;
|
||||
retain_fifos--;
|
||||
COPY_PROCENV (old_return_catch, return_catch);
|
||||
}
|
||||
|
||||
@@ -316,15 +328,13 @@ file_error_and_exit:
|
||||
}
|
||||
|
||||
int
|
||||
maybe_execute_file (fname, force_noninteractive)
|
||||
const char *fname;
|
||||
int force_noninteractive;
|
||||
maybe_execute_file (const char *fname, int force_noninteractive)
|
||||
{
|
||||
char *filename;
|
||||
int result, flags;
|
||||
|
||||
filename = bash_tilde_expand (fname, 0);
|
||||
flags = FEVAL_ENOENTOK;
|
||||
flags = FEVAL_ENOENTOK|FEVAL_RETRY;
|
||||
if (force_noninteractive)
|
||||
flags |= FEVAL_NONINT;
|
||||
result = _evalfile (filename, flags);
|
||||
@@ -333,15 +343,13 @@ maybe_execute_file (fname, force_noninteractive)
|
||||
}
|
||||
|
||||
int
|
||||
force_execute_file (fname, force_noninteractive)
|
||||
const char *fname;
|
||||
int force_noninteractive;
|
||||
force_execute_file (const char *fname, int force_noninteractive)
|
||||
{
|
||||
char *filename;
|
||||
int result, flags;
|
||||
|
||||
filename = bash_tilde_expand (fname, 0);
|
||||
flags = 0;
|
||||
flags = FEVAL_RETRY;
|
||||
if (force_noninteractive)
|
||||
flags |= FEVAL_NONINT;
|
||||
result = _evalfile (filename, flags);
|
||||
@@ -351,8 +359,7 @@ force_execute_file (fname, force_noninteractive)
|
||||
|
||||
#if defined (HISTORY)
|
||||
int
|
||||
fc_execute_file (filename)
|
||||
const char *filename;
|
||||
fc_execute_file (const char *filename)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@@ -365,9 +372,7 @@ fc_execute_file (filename)
|
||||
#endif /* HISTORY */
|
||||
|
||||
int
|
||||
source_file (filename, sflags)
|
||||
const char *filename;
|
||||
int sflags;
|
||||
source_file (const char *filename, int sflags)
|
||||
{
|
||||
int flags, rval;
|
||||
|
||||
|
||||
+67
-58
@@ -1,6 +1,6 @@
|
||||
/* evalstring.c - evaluate a string as one or more shell commands. */
|
||||
|
||||
/* Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -63,31 +63,47 @@ extern int errno;
|
||||
|
||||
int parse_and_execute_level = 0;
|
||||
|
||||
static int cat_file PARAMS((REDIRECT *));
|
||||
static int cat_file (REDIRECT *);
|
||||
|
||||
#define PE_TAG "parse_and_execute top"
|
||||
#define PS_TAG "parse_string top"
|
||||
|
||||
#if defined (HISTORY)
|
||||
static void
|
||||
set_history_remembering ()
|
||||
uw_set_history_remembering (void *ignore)
|
||||
{
|
||||
remember_on_history = enable_history_list;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
restore_lastcom (x)
|
||||
char *x;
|
||||
uw_restore_lastcom (void *x)
|
||||
{
|
||||
FREE (the_printed_command_except_trap);
|
||||
the_printed_command_except_trap = x;
|
||||
}
|
||||
|
||||
static void
|
||||
uw_set_current_prompt_level (void *x)
|
||||
{
|
||||
set_current_prompt_level ((intptr_t) x);
|
||||
}
|
||||
|
||||
static void
|
||||
uw_pop_stream (void *x)
|
||||
{
|
||||
pop_stream ();
|
||||
}
|
||||
|
||||
static void
|
||||
uw_parser_restore_alias (void *x)
|
||||
{
|
||||
parser_restore_alias ();
|
||||
}
|
||||
|
||||
int
|
||||
should_optimize_fork (command, subshell)
|
||||
COMMAND *command;
|
||||
int subshell;
|
||||
should_optimize_fork (COMMAND *command, int subshell)
|
||||
{
|
||||
return (running_trap == 0 &&
|
||||
command->type == cm_simple &&
|
||||
@@ -102,9 +118,10 @@ should_optimize_fork (command, subshell)
|
||||
/* This has extra tests to account for STARTUP_STATE == 2, which is for
|
||||
-c command but has been extended to command and process substitution
|
||||
(basically any time you call parse_and_execute in a subshell). */
|
||||
/* ssh_reading_startup_files will never be non-zero unless someone goes
|
||||
and uncomments SSH_SOURCE_BASHRC in config-top.h */
|
||||
int
|
||||
should_suppress_fork (command)
|
||||
COMMAND *command;
|
||||
should_suppress_fork (COMMAND *command)
|
||||
{
|
||||
int subshell;
|
||||
|
||||
@@ -112,12 +129,13 @@ should_suppress_fork (command)
|
||||
return (startup_state == 2 && parse_and_execute_level == 1 &&
|
||||
*bash_input.location.string == '\0' &&
|
||||
parser_expanding_alias () == 0 &&
|
||||
job_control_active_p () == 0 &&
|
||||
ssh_reading_startup_files == 0 &&
|
||||
should_optimize_fork (command, subshell));
|
||||
}
|
||||
|
||||
int
|
||||
can_optimize_connection (command)
|
||||
COMMAND *command;
|
||||
can_optimize_connection (COMMAND *command)
|
||||
{
|
||||
return (*bash_input.location.string == '\0' &&
|
||||
parser_expanding_alias () == 0 &&
|
||||
@@ -126,8 +144,7 @@ can_optimize_connection (command)
|
||||
}
|
||||
|
||||
void
|
||||
optimize_connection_fork (command)
|
||||
COMMAND *command;
|
||||
optimize_connection_fork (COMMAND *command)
|
||||
{
|
||||
if (command->type == cm_connection &&
|
||||
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
|
||||
@@ -141,8 +158,7 @@ optimize_connection_fork (command)
|
||||
}
|
||||
|
||||
void
|
||||
optimize_subshell_command (command)
|
||||
COMMAND *command;
|
||||
optimize_subshell_command (COMMAND *command)
|
||||
{
|
||||
if (should_optimize_fork (command, 0))
|
||||
{
|
||||
@@ -160,8 +176,7 @@ optimize_subshell_command (command)
|
||||
}
|
||||
|
||||
void
|
||||
optimize_shell_function (command)
|
||||
COMMAND *command;
|
||||
optimize_shell_function (COMMAND *command)
|
||||
{
|
||||
COMMAND *fc;
|
||||
|
||||
@@ -180,8 +195,7 @@ optimize_shell_function (command)
|
||||
}
|
||||
|
||||
int
|
||||
can_optimize_cat_file (command)
|
||||
COMMAND *command;
|
||||
can_optimize_cat_file (COMMAND *command)
|
||||
{
|
||||
return (command->type == cm_simple && !command->redirects &&
|
||||
(command->flags & CMD_TIME_PIPELINE) == 0 &&
|
||||
@@ -194,8 +208,7 @@ can_optimize_cat_file (command)
|
||||
|
||||
/* How to force parse_and_execute () to clean up after itself. */
|
||||
void
|
||||
parse_and_execute_cleanup (old_running_trap)
|
||||
int old_running_trap;
|
||||
parse_and_execute_cleanup (int old_running_trap)
|
||||
{
|
||||
if (running_trap > 0)
|
||||
{
|
||||
@@ -215,10 +228,7 @@ parse_and_execute_cleanup (old_running_trap)
|
||||
}
|
||||
|
||||
static void
|
||||
parse_prologue (string, flags, tag)
|
||||
char *string;
|
||||
int flags;
|
||||
char *tag;
|
||||
parse_prologue (char *string, int flags, char *tag)
|
||||
{
|
||||
char *orig_string, *lastcom;
|
||||
int x;
|
||||
@@ -232,14 +242,15 @@ parse_prologue (string, flags, tag)
|
||||
unwind_protect_int (line_number);
|
||||
unwind_protect_int (line_number_for_err_trap);
|
||||
unwind_protect_int (loop_level);
|
||||
unwind_protect_int (executing_list);
|
||||
unwind_protect_int (interrupt_execution);
|
||||
unwind_protect_int (comsub_ignore_return);
|
||||
unwind_protect_int (builtin_ignoring_errexit);
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
unwind_protect_int (interactive);
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (parse_and_execute_level == 0)
|
||||
add_unwind_protect (set_history_remembering, (char *)NULL);
|
||||
add_unwind_protect (uw_set_history_remembering, (char *)NULL);
|
||||
else
|
||||
unwind_protect_int (remember_on_history); /* can be used in scripts */
|
||||
# if defined (BANG_HISTORY)
|
||||
@@ -250,18 +261,18 @@ parse_prologue (string, flags, tag)
|
||||
if (interactive_shell)
|
||||
{
|
||||
x = get_current_prompt_level ();
|
||||
add_unwind_protect (set_current_prompt_level, x);
|
||||
add_unwind_protect (uw_set_current_prompt_level, (void *) (intptr_t) x);
|
||||
}
|
||||
|
||||
if (the_printed_command_except_trap)
|
||||
{
|
||||
lastcom = savestring (the_printed_command_except_trap);
|
||||
add_unwind_protect (restore_lastcom, lastcom);
|
||||
add_unwind_protect (uw_restore_lastcom, lastcom);
|
||||
}
|
||||
|
||||
add_unwind_protect (pop_stream, (char *)NULL);
|
||||
add_unwind_protect (uw_pop_stream, (char *)NULL);
|
||||
if (parser_expanding_alias ())
|
||||
add_unwind_protect (parser_restore_alias, (char *)NULL);
|
||||
add_unwind_protect (uw_parser_restore_alias, (char *)NULL);
|
||||
|
||||
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
|
||||
add_unwind_protect (xfree, orig_string);
|
||||
@@ -294,12 +305,9 @@ parse_prologue (string, flags, tag)
|
||||
*/
|
||||
|
||||
int
|
||||
parse_and_execute (string, from_file, flags)
|
||||
char *string;
|
||||
const char *from_file;
|
||||
int flags;
|
||||
parse_and_execute (char *string, const char *from_file, int flags)
|
||||
{
|
||||
int code, lreset;
|
||||
int code, lreset, ignore_return;
|
||||
volatile int should_jump_to_top_level, last_result;
|
||||
COMMAND *volatile command;
|
||||
volatile sigset_t pe_sigmask;
|
||||
@@ -309,6 +317,8 @@ parse_and_execute (string, from_file, flags)
|
||||
parse_and_execute_level++;
|
||||
|
||||
lreset = flags & SEVAL_RESETLINE;
|
||||
ignore_return = (this_shell_builtin == eval_builtin || this_shell_builtin == source_builtin) &&
|
||||
builtin_ignoring_errexit;
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
/* If we longjmp and are going to go on, use this to restore signal mask */
|
||||
@@ -408,6 +418,7 @@ parse_and_execute (string, from_file, flags)
|
||||
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;
|
||||
@@ -461,6 +472,8 @@ parse_and_execute (string, from_file, flags)
|
||||
should_jump_to_top_level = 0;
|
||||
last_result = last_command_exit_value = EX_BADUSAGE;
|
||||
set_pipestatus_from_exit (last_command_exit_value);
|
||||
dispose_command (command);
|
||||
global_command = (COMMAND *)NULL;
|
||||
reset_parser ();
|
||||
break;
|
||||
}
|
||||
@@ -468,14 +481,17 @@ parse_and_execute (string, from_file, flags)
|
||||
|
||||
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
|
||||
begin_unwind_frame ("pe_dispose");
|
||||
add_unwind_protect (dispose_fd_bitmap, bitmap);
|
||||
add_unwind_protect (dispose_command, command); /* XXX */
|
||||
add_unwind_protect (uw_dispose_fd_bitmap, bitmap);
|
||||
add_unwind_protect (uw_dispose_command, command); /* XXX */
|
||||
|
||||
global_command = (COMMAND *)NULL;
|
||||
|
||||
if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return)
|
||||
command->flags |= CMD_IGNORE_RETURN;
|
||||
|
||||
if (ignore_return)
|
||||
command->flags |= CMD_IGNORE_RETURN;
|
||||
|
||||
#if defined (ONESHOT)
|
||||
/*
|
||||
* IF
|
||||
@@ -522,7 +538,7 @@ parse_and_execute (string, from_file, flags)
|
||||
the global value of the flag (expaliases_flag) changes). */
|
||||
local_expalias = expand_aliases;
|
||||
local_alflag = expaliases_flag;
|
||||
if (subshell_environment & SUBSHELL_COMSUB)
|
||||
if ((subshell_environment & SUBSHELL_COMSUB) || executing_funsub)
|
||||
expand_aliases = expaliases_flag;
|
||||
|
||||
/* See if this is a candidate for $( <file ). */
|
||||
@@ -543,7 +559,7 @@ parse_and_execute (string, from_file, flags)
|
||||
discard_unwind_frame ("pe_dispose");
|
||||
|
||||
/* If the global value didn't change, we restore what we had. */
|
||||
if ((subshell_environment & SUBSHELL_COMSUB) && local_alflag == expaliases_flag)
|
||||
if (((subshell_environment & SUBSHELL_COMSUB) || executing_funsub) && local_alflag == expaliases_flag)
|
||||
expand_aliases = local_expalias;
|
||||
|
||||
if (flags & SEVAL_ONECMD)
|
||||
@@ -599,12 +615,7 @@ parse_and_execute (string, from_file, flags)
|
||||
command substitutions during parsing to obey Posix rules about finding
|
||||
the end of the command and balancing parens. */
|
||||
int
|
||||
parse_string (string, from_file, flags, cmdp, endp)
|
||||
char *string;
|
||||
const char *from_file;
|
||||
int flags;
|
||||
COMMAND **cmdp;
|
||||
char **endp;
|
||||
parse_string (char *string, const char *from_file, int flags, COMMAND **cmdp, char **endp)
|
||||
{
|
||||
int code, nc;
|
||||
volatile int should_jump_to_top_level;
|
||||
@@ -612,6 +623,7 @@ parse_string (string, from_file, flags, cmdp, endp)
|
||||
char *ostring;
|
||||
volatile sigset_t ps_sigmask;
|
||||
|
||||
/* unwind-protects common to this and parse_and_execute */
|
||||
parse_prologue (string, flags, PS_TAG);
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
@@ -727,12 +739,10 @@ out:
|
||||
}
|
||||
|
||||
int
|
||||
open_redir_file (r, fnp)
|
||||
REDIRECT *r;
|
||||
char **fnp;
|
||||
open_redir_file (REDIRECT *r, char **fnp)
|
||||
{
|
||||
char *fn;
|
||||
int fd, rval;
|
||||
int fd;
|
||||
|
||||
if (r->instruction != r_input_direction)
|
||||
return -1;
|
||||
@@ -753,7 +763,7 @@ open_redir_file (r, fnp)
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
file_error (fn);
|
||||
internal_error ("%s: %s", fn, strerror (errno));
|
||||
free (fn);
|
||||
if (fnp)
|
||||
*fnp = 0;
|
||||
@@ -762,6 +772,9 @@ open_redir_file (r, fnp)
|
||||
|
||||
if (fnp)
|
||||
*fnp = fn;
|
||||
else
|
||||
free (fn);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
@@ -769,8 +782,7 @@ open_redir_file (r, fnp)
|
||||
returning errors as appropriate, then just cats the file to the standard
|
||||
output. */
|
||||
static int
|
||||
cat_file (r)
|
||||
REDIRECT *r;
|
||||
cat_file (REDIRECT *r)
|
||||
{
|
||||
char *fn;
|
||||
int fd, rval;
|
||||
@@ -788,10 +800,7 @@ cat_file (r)
|
||||
}
|
||||
|
||||
int
|
||||
evalstring (string, from_file, flags)
|
||||
char *string;
|
||||
const char *from_file;
|
||||
int flags;
|
||||
evalstring (char *string, const char *from_file, int flags)
|
||||
{
|
||||
volatile int r, rflag, rcatch;
|
||||
volatile int was_trap;
|
||||
|
||||
+7
-8
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2021,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -85,8 +85,7 @@ int no_exit_on_failed_exec;
|
||||
/* If the user wants this to look like a login shell, then
|
||||
prepend a `-' onto NAME and return the new name. */
|
||||
static char *
|
||||
mkdashname (name)
|
||||
char *name;
|
||||
mkdashname (char *name)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
@@ -97,15 +96,15 @@ mkdashname (name)
|
||||
}
|
||||
|
||||
int
|
||||
exec_builtin (list)
|
||||
WORD_LIST *list;
|
||||
exec_builtin (WORD_LIST *list)
|
||||
{
|
||||
int exit_value = EXECUTION_FAILURE;
|
||||
int exit_value;
|
||||
int cleanenv, login, opt, orig_job_control;
|
||||
char *argv0, *command, **args, **env, *newname, *com2;
|
||||
|
||||
cleanenv = login = orig_job_control = 0;
|
||||
exec_argv0 = argv0 = (char *)NULL;
|
||||
exit_value = EXECUTION_FAILURE;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "cla:")) != -1)
|
||||
@@ -225,12 +224,11 @@ exec_builtin (list)
|
||||
default_tty_job_signals (); /* undo initialize_job_signals */
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
#if defined (BUFFERED_INPUT)
|
||||
if (default_buffered_input >= 0)
|
||||
sync_buffered_stream (default_buffered_input);
|
||||
#endif
|
||||
|
||||
exit_value = shell_execve (command, args, env);
|
||||
opt = errno;
|
||||
|
||||
/* We have to set this to NULL because shell_execve has called realloc()
|
||||
to stuff more items at the front of the array, which may have caused
|
||||
@@ -243,6 +241,7 @@ exec_builtin (list)
|
||||
goto failed_exec;
|
||||
else if (executable_file (command) == 0)
|
||||
{
|
||||
errno = opt;
|
||||
builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
|
||||
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
|
||||
}
|
||||
|
||||
+8
-11
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -48,14 +48,11 @@ $END
|
||||
#include "common.h"
|
||||
#include "builtext.h" /* for jobs_builtin */
|
||||
|
||||
extern int check_jobs_at_exit;
|
||||
|
||||
static int exit_or_logout PARAMS((WORD_LIST *));
|
||||
static int exit_or_logout (WORD_LIST *);
|
||||
static int sourced_logout;
|
||||
|
||||
int
|
||||
exit_builtin (list)
|
||||
WORD_LIST *list;
|
||||
exit_builtin (WORD_LIST *list)
|
||||
{
|
||||
CHECK_HELPOPT (list);
|
||||
|
||||
@@ -79,8 +76,7 @@ $END
|
||||
|
||||
/* How to logout. */
|
||||
int
|
||||
logout_builtin (list)
|
||||
WORD_LIST *list;
|
||||
logout_builtin (WORD_LIST *list)
|
||||
{
|
||||
CHECK_HELPOPT (list);
|
||||
|
||||
@@ -94,8 +90,7 @@ logout_builtin (list)
|
||||
}
|
||||
|
||||
static int
|
||||
exit_or_logout (list)
|
||||
WORD_LIST *list;
|
||||
exit_or_logout (WORD_LIST *list)
|
||||
{
|
||||
int exit_value;
|
||||
|
||||
@@ -145,6 +140,8 @@ exit_or_logout (list)
|
||||
(list == 0), use the exit status we saved before running the trap
|
||||
commands (trap_saved_exit_value). */
|
||||
exit_value = (running_trap == 1 && list == 0) ? trap_saved_exit_value : get_exitstat (list);
|
||||
if (exit_value > EX_SHERRBASE) /* some kind of error */
|
||||
return (exit_value);
|
||||
|
||||
bash_logout ();
|
||||
|
||||
@@ -156,7 +153,7 @@ exit_or_logout (list)
|
||||
}
|
||||
|
||||
void
|
||||
bash_logout ()
|
||||
bash_logout (void)
|
||||
{
|
||||
/* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
|
||||
if (login_shell && sourced_logout++ == 0 && subshell_environment == 0)
|
||||
|
||||
+58
-39
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -45,6 +45,8 @@ A useful alias to use with this is r='fc -s', so that typing `r cc'
|
||||
runs the last command beginning with `cc' and typing `r' re-executes
|
||||
the last command.
|
||||
|
||||
The history builtin also operates on the history list.
|
||||
|
||||
Exit Status:
|
||||
Returns success or status of executed command; non-zero if an error occurs.
|
||||
$END
|
||||
@@ -94,9 +96,11 @@ extern int errno;
|
||||
#define HN_LISTING 0x01
|
||||
#define HN_FIRST 0x02
|
||||
|
||||
extern int unlink PARAMS((const char *));
|
||||
#ifndef HAVE_UNISTD_H
|
||||
extern int unlink (const char *);
|
||||
#endif
|
||||
|
||||
extern FILE *sh_mktmpfp PARAMS((char *, int, char **));
|
||||
extern FILE *sh_mktmpfp (char *, int, char **);
|
||||
|
||||
extern int suppress_debug_trap_verbose;
|
||||
|
||||
@@ -154,22 +158,28 @@ typedef struct repl {
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
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 *));
|
||||
static char *fc_dosubs (char *, REPL *);
|
||||
static char *fc_gethist (char *, HIST_ENTRY **, int);
|
||||
static int fc_gethnum (char *, HIST_ENTRY **, int);
|
||||
static int fc_number (WORD_LIST *);
|
||||
static void fc_replhist (char *);
|
||||
#ifdef INCLUDE_UNUSED
|
||||
static char *fc_readline PARAMS((FILE *));
|
||||
static void fc_addhist PARAMS((char *));
|
||||
static char *fc_readline (FILE *);
|
||||
static void fc_addhist (char *);
|
||||
#endif
|
||||
|
||||
static void
|
||||
set_verbose_flag ()
|
||||
uw_set_verbose_flag (void *ignore)
|
||||
{
|
||||
echo_input_at_read = verbose_flag;
|
||||
}
|
||||
|
||||
static void
|
||||
uw_unlink (void *fn)
|
||||
{
|
||||
unlink ((const char *)fn);
|
||||
}
|
||||
|
||||
/* String to execute on a file that we want to edit. */
|
||||
#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
|
||||
#if defined (STRICT_POSIX)
|
||||
@@ -179,8 +189,7 @@ set_verbose_flag ()
|
||||
#endif
|
||||
|
||||
int
|
||||
fc_builtin (list)
|
||||
WORD_LIST *list;
|
||||
fc_builtin (WORD_LIST *list)
|
||||
{
|
||||
register int i;
|
||||
register char *sep;
|
||||
@@ -279,6 +288,15 @@ fc_builtin (list)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (posixly_correct && list && list->next)
|
||||
{
|
||||
builtin_error (_("too many arguments"));
|
||||
if (rlist)
|
||||
FREE_RLIST ();
|
||||
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (rlist)
|
||||
{
|
||||
newcom = fc_dosubs (command, rlist);
|
||||
@@ -515,8 +533,8 @@ fc_builtin (list)
|
||||
will be echoed as they are read by the parser. */
|
||||
begin_unwind_frame ("fc builtin");
|
||||
add_unwind_protect (xfree, fn);
|
||||
add_unwind_protect (unlink, fn);
|
||||
add_unwind_protect (set_verbose_flag, (char *)NULL);
|
||||
add_unwind_protect (uw_unlink, fn);
|
||||
add_unwind_protect (uw_set_verbose_flag, (char *)NULL);
|
||||
unwind_protect_int (suppress_debug_trap_verbose);
|
||||
echo_input_at_read = 1;
|
||||
suppress_debug_trap_verbose = 1;
|
||||
@@ -529,8 +547,7 @@ fc_builtin (list)
|
||||
|
||||
/* Return 1 if LIST->word->word is a legal number for fc's use. */
|
||||
static int
|
||||
fc_number (list)
|
||||
WORD_LIST *list;
|
||||
fc_number (WORD_LIST *list)
|
||||
{
|
||||
char *s;
|
||||
|
||||
@@ -539,7 +556,7 @@ fc_number (list)
|
||||
s = list->word->word;
|
||||
if (*s == '-')
|
||||
s++;
|
||||
return (legal_number (s, (intmax_t *)NULL));
|
||||
return (valid_number (s, (intmax_t *)NULL));
|
||||
}
|
||||
|
||||
/* Return an absolute index into HLIST which corresponds to COMMAND. If
|
||||
@@ -549,14 +566,12 @@ fc_number (list)
|
||||
are executing them. If MODE includes HN_FIRST we are looking for the
|
||||
first history number specification. */
|
||||
static int
|
||||
fc_gethnum (command, hlist, mode)
|
||||
char *command;
|
||||
HIST_ENTRY **hlist;
|
||||
int mode;
|
||||
fc_gethnum (char *command, HIST_ENTRY **hlist, int mode)
|
||||
{
|
||||
int sign, n, clen, rh;
|
||||
register int i, j, last_hist, real_last, listing;
|
||||
register char *s;
|
||||
int sign, n, rh;
|
||||
size_t clen;
|
||||
int i, j, last_hist, real_last, listing;
|
||||
char *s;
|
||||
|
||||
listing = mode & HN_LISTING;
|
||||
sign = 1;
|
||||
@@ -654,10 +669,7 @@ fc_gethnum (command, hlist, mode)
|
||||
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, mode)
|
||||
char *command;
|
||||
HIST_ENTRY **hlist;
|
||||
int mode;
|
||||
fc_gethist (char *command, HIST_ENTRY **hlist, int mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -677,10 +689,12 @@ fc_gethist (command, hlist, mode)
|
||||
one at a time. This can read unlimited length lines. The
|
||||
caller should free the storage. */
|
||||
static char *
|
||||
fc_readline (stream)
|
||||
FILE *stream;
|
||||
fc_readline (FILE *stream)
|
||||
{
|
||||
register int c;
|
||||
#ifdef __MSYS__
|
||||
register int d;
|
||||
#endif
|
||||
int line_len = 0, lindex = 0;
|
||||
char *line = (char *)NULL;
|
||||
|
||||
@@ -689,6 +703,11 @@ fc_readline (stream)
|
||||
if ((lindex + 2) >= line_len)
|
||||
line = (char *)xrealloc (line, (line_len += 128));
|
||||
|
||||
#ifdef __MSYS__
|
||||
if (d == '\r')
|
||||
lindex--;
|
||||
#endif
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
line[lindex++] = '\n';
|
||||
@@ -697,6 +716,10 @@ fc_readline (stream)
|
||||
}
|
||||
else
|
||||
line[lindex++] = c;
|
||||
|
||||
#ifdef __MSYS__
|
||||
d = c;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!lindex)
|
||||
@@ -721,9 +744,7 @@ fc_readline (stream)
|
||||
Return a pointer to a malloc'ed string which contains the substituted
|
||||
command. */
|
||||
static char *
|
||||
fc_dosubs (command, subs)
|
||||
char *command;
|
||||
REPL *subs;
|
||||
fc_dosubs (char *command, REPL *subs)
|
||||
{
|
||||
register char *new, *t;
|
||||
register REPL *r;
|
||||
@@ -742,10 +763,9 @@ fc_dosubs (command, subs)
|
||||
become the history entry, and that `fc' should never appear in the
|
||||
history list. This way you can do `r' to your heart's content. */
|
||||
static void
|
||||
fc_replhist (command)
|
||||
char *command;
|
||||
fc_replhist (char *command)
|
||||
{
|
||||
int n;
|
||||
size_t n;
|
||||
|
||||
if (command == 0 || *command == '\0')
|
||||
return;
|
||||
@@ -764,8 +784,7 @@ fc_replhist (command)
|
||||
#ifdef INCLUDE_UNUSED
|
||||
/* Add LINE to the history, after removing a single trailing newline. */
|
||||
static void
|
||||
fc_addhist (line)
|
||||
char *line;
|
||||
fc_addhist (char *line)
|
||||
{
|
||||
register int n;
|
||||
|
||||
|
||||
+5
-9
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -52,12 +52,11 @@ $END
|
||||
#include "bashgetopt.h"
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
static int fg_bg PARAMS((WORD_LIST *, int));
|
||||
static int fg_bg (WORD_LIST *, int);
|
||||
|
||||
/* How to bring a job into the foreground. */
|
||||
int
|
||||
fg_builtin (list)
|
||||
WORD_LIST *list;
|
||||
fg_builtin (WORD_LIST *list)
|
||||
{
|
||||
int fg_bit;
|
||||
register WORD_LIST *t;
|
||||
@@ -101,8 +100,7 @@ $END
|
||||
#if defined (JOB_CONTROL)
|
||||
/* How to put a job into the background. */
|
||||
int
|
||||
bg_builtin (list)
|
||||
WORD_LIST *list;
|
||||
bg_builtin (WORD_LIST *list)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -135,9 +133,7 @@ bg_builtin (list)
|
||||
|
||||
/* How to put a job into the foreground/background. */
|
||||
static int
|
||||
fg_bg (list, foreground)
|
||||
WORD_LIST *list;
|
||||
int foreground;
|
||||
fg_bg (WORD_LIST *list, int foreground)
|
||||
{
|
||||
sigset_t set, oset;
|
||||
int job, status, old_async_pid;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* gen-helpfiles - create files containing builtin help text */
|
||||
|
||||
/* Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -72,10 +72,6 @@
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if !defined (__STDC__) && !defined (strcpy)
|
||||
extern char *strcpy ();
|
||||
#endif /* !__STDC__ && !strcpy */
|
||||
|
||||
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
||||
|
||||
/* Flag values that builtins can have. */
|
||||
@@ -99,15 +95,13 @@ char *helpfile_directory;
|
||||
|
||||
/* Forward declarations. */
|
||||
|
||||
int write_helpfiles PARAMS((struct builtin *));
|
||||
int write_helpfiles (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 necessary. */
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int arg_index = 1;
|
||||
|
||||
@@ -138,10 +132,7 @@ main (argc, argv)
|
||||
internationalization (gettext) and the single-string vs. multiple-strings
|
||||
issues. */
|
||||
void
|
||||
write_documentation (stream, documentation, indentation)
|
||||
FILE *stream;
|
||||
char *documentation;
|
||||
int indentation;
|
||||
write_documentation (FILE *stream, char *documentation, int indentation)
|
||||
{
|
||||
if (stream == 0)
|
||||
return;
|
||||
@@ -151,8 +142,7 @@ write_documentation (stream, documentation, indentation)
|
||||
}
|
||||
|
||||
int
|
||||
write_helpfiles (builtins)
|
||||
struct builtin *builtins;
|
||||
write_helpfiles (struct builtin *builtins)
|
||||
{
|
||||
char *helpfile, *bname, *fname;
|
||||
FILE *helpfp;
|
||||
|
||||
+9
-18
@@ -1,6 +1,6 @@
|
||||
/* getopt.c - getopt for Bash. Used by the getopt builtin. */
|
||||
|
||||
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2009,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -111,10 +111,7 @@ int sh_badopt = 0;
|
||||
#define NEEDARG(x) fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], x)
|
||||
|
||||
int
|
||||
sh_getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
sh_getopt (int argc, char *const *argv, const char *optstring)
|
||||
{
|
||||
char c, *temp;
|
||||
|
||||
@@ -216,10 +213,9 @@ sh_getopt (argc, argv, optstring)
|
||||
}
|
||||
|
||||
void
|
||||
sh_getopt_restore_state (argv)
|
||||
char **argv;
|
||||
sh_getopt_restore_state (char **argv)
|
||||
{
|
||||
if (nextchar)
|
||||
if (nextchar && argv && argv[sh_curopt])
|
||||
nextchar = argv[sh_curopt] + sh_charindex;
|
||||
}
|
||||
|
||||
@@ -233,14 +229,13 @@ sh_getopt_alloc_istate ()
|
||||
}
|
||||
|
||||
void
|
||||
sh_getopt_dispose_istate (gs)
|
||||
sh_getopt_state_t *gs;
|
||||
sh_getopt_dispose_istate (sh_getopt_state_t *gs)
|
||||
{
|
||||
free (gs);
|
||||
}
|
||||
|
||||
sh_getopt_state_t *
|
||||
sh_getopt_save_istate ()
|
||||
sh_getopt_save_istate (void)
|
||||
{
|
||||
sh_getopt_state_t *ret;
|
||||
|
||||
@@ -257,8 +252,7 @@ sh_getopt_save_istate ()
|
||||
}
|
||||
|
||||
void
|
||||
sh_getopt_restore_istate (state)
|
||||
sh_getopt_state_t *state;
|
||||
sh_getopt_restore_istate (sh_getopt_state_t *state)
|
||||
{
|
||||
sh_optarg = state->gs_optarg;
|
||||
sh_optind = state->gs_optind;
|
||||
@@ -271,8 +265,7 @@ sh_getopt_restore_istate (state)
|
||||
|
||||
#if 0
|
||||
void
|
||||
sh_getopt_debug_restore_state (argv)
|
||||
char **argv;
|
||||
sh_getopt_debug_restore_state (char **argv)
|
||||
{
|
||||
if (nextchar && nextchar != argv[sh_curopt] + sh_charindex)
|
||||
{
|
||||
@@ -288,9 +281,7 @@ sh_getopt_debug_restore_state (argv)
|
||||
the above definition of `sh_getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int digit_sh_optind = 0;
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
/* getopt.h - declarations for getopt. */
|
||||
|
||||
/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2022 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 PARAMS((int, char *const *, const char *));
|
||||
extern int sh_getopt (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 PARAMS((char **));
|
||||
extern void sh_getopt_restore_state (char **);
|
||||
|
||||
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_alloc_istate (void);
|
||||
extern void sh_getopt_dispose_istate (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 *));
|
||||
extern sh_getopt_state_t *sh_getopt_save_istate (void);
|
||||
extern void sh_getopt_restore_istate (sh_getopt_state_t *);
|
||||
|
||||
#endif /* _SH_GETOPT_H */
|
||||
|
||||
+14
-27
@@ -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-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -86,23 +86,21 @@ $END
|
||||
#define G_INVALID_OPT -2
|
||||
#define G_ARG_MISSING -3
|
||||
|
||||
static int getopts_unbind_variable PARAMS((char *));
|
||||
static int getopts_bind_variable PARAMS((char *, char *));
|
||||
static int dogetopts PARAMS((int, char **));
|
||||
static int getopts_unbind_variable (char *);
|
||||
static int getopts_bind_variable (char *, char *);
|
||||
static int dogetopts (int, char **);
|
||||
|
||||
/* getopts_reset is magic code for when OPTIND is reset. N is the
|
||||
value that has just been assigned to OPTIND. */
|
||||
void
|
||||
getopts_reset (newind)
|
||||
int newind;
|
||||
getopts_reset (int newind)
|
||||
{
|
||||
sh_optind = newind;
|
||||
sh_badopt = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getopts_unbind_variable (name)
|
||||
char *name;
|
||||
getopts_unbind_variable (char *name)
|
||||
{
|
||||
#if 0
|
||||
return (unbind_variable (name));
|
||||
@@ -112,12 +110,11 @@ getopts_unbind_variable (name)
|
||||
}
|
||||
|
||||
static int
|
||||
getopts_bind_variable (name, value)
|
||||
char *name, *value;
|
||||
getopts_bind_variable (char *name, char *value)
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
if (legal_identifier (name))
|
||||
if (valid_identifier (name))
|
||||
{
|
||||
v = bind_variable (name, value, 0);
|
||||
if (v && (readonly_p (v) || noassign_p (v)))
|
||||
@@ -159,9 +156,7 @@ getopts_bind_variable (name, value)
|
||||
*/
|
||||
|
||||
static int
|
||||
dogetopts (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
dogetopts (int argc, char **argv)
|
||||
{
|
||||
int ret, special_error, old_opterr, i, n;
|
||||
char strval[2], numval[16];
|
||||
@@ -312,29 +307,21 @@ dogetopts (argc, argv)
|
||||
|
||||
/* The getopts builtin. Build an argv, and call dogetopts with it. */
|
||||
int
|
||||
getopts_builtin (list)
|
||||
WORD_LIST *list;
|
||||
getopts_builtin (WORD_LIST *list)
|
||||
{
|
||||
char **av;
|
||||
int ac, ret;
|
||||
|
||||
if (no_options (list))
|
||||
return (EX_USAGE);
|
||||
list = loptend; /* skip over possible `--' */
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_usage ();
|
||||
return EX_USAGE;
|
||||
}
|
||||
|
||||
reset_internal_getopt ();
|
||||
if ((ret = internal_getopt (list, "")) != -1)
|
||||
{
|
||||
if (ret == GETOPT_HELP)
|
||||
builtin_help ();
|
||||
else
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
av = make_builtin_argv (list, &ac);
|
||||
ret = dogetopts (ac, av);
|
||||
free ((char *)av);
|
||||
|
||||
+23
-25
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -68,20 +68,17 @@ $END
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
extern int dot_found_in_search;
|
||||
|
||||
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));
|
||||
static int add_hashed_command (char *, int);
|
||||
static int print_hash_info (BUCKET_CONTENTS *);
|
||||
static int print_portable_hash_info (BUCKET_CONTENTS *);
|
||||
static int print_hashed_commands (int);
|
||||
static int list_hashed_filename_targets (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
|
||||
commands. */
|
||||
int
|
||||
hash_builtin (list)
|
||||
WORD_LIST *list;
|
||||
hash_builtin (WORD_LIST *list)
|
||||
{
|
||||
int expunge_hash_table, list_targets, list_portably, delete, opt;
|
||||
char *w, *pathname;
|
||||
@@ -126,11 +123,19 @@ hash_builtin (list)
|
||||
if (list == 0 && (delete || list_targets))
|
||||
{
|
||||
sh_needarg (delete ? "-d" : "-t");
|
||||
return (EXECUTION_FAILURE);
|
||||
return (sh_chkwrite (EXECUTION_FAILURE));
|
||||
}
|
||||
|
||||
/* It's an error to specify a pathname to hash to, but no name to hash. */
|
||||
if (pathname && list == 0)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
/* We want hash -r to be silent, but hash -- to print hashing info, so
|
||||
we test expunge_hash_table. */
|
||||
|
||||
if (list == 0 && expunge_hash_table == 0)
|
||||
{
|
||||
opt = print_hashed_commands (list_portably);
|
||||
@@ -147,7 +152,7 @@ hash_builtin (list)
|
||||
/* If someone runs `hash -r -t xyz' he will be disappointed. */
|
||||
if (list_targets)
|
||||
return (list_hashed_filename_targets (list, list_portably));
|
||||
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted && pathname)
|
||||
{
|
||||
@@ -206,9 +211,7 @@ hash_builtin (list)
|
||||
}
|
||||
|
||||
static int
|
||||
add_hashed_command (w, quiet)
|
||||
char *w;
|
||||
int quiet;
|
||||
add_hashed_command (char *w, int quiet)
|
||||
{
|
||||
int rv;
|
||||
char *full_path;
|
||||
@@ -233,16 +236,14 @@ add_hashed_command (w, quiet)
|
||||
|
||||
/* Print information about current hashed info. */
|
||||
static int
|
||||
print_hash_info (item)
|
||||
BUCKET_CONTENTS *item;
|
||||
print_hash_info (BUCKET_CONTENTS *item)
|
||||
{
|
||||
printf ("%4d\t%s\n", item->times_found, pathdata(item)->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
print_portable_hash_info (item)
|
||||
BUCKET_CONTENTS *item;
|
||||
print_portable_hash_info (BUCKET_CONTENTS *item)
|
||||
{
|
||||
char *fp, *fn;
|
||||
|
||||
@@ -257,8 +258,7 @@ print_portable_hash_info (item)
|
||||
}
|
||||
|
||||
static int
|
||||
print_hashed_commands (fmt)
|
||||
int fmt;
|
||||
print_hashed_commands (int fmt)
|
||||
{
|
||||
if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
|
||||
return (0);
|
||||
@@ -270,9 +270,7 @@ print_hashed_commands (fmt)
|
||||
}
|
||||
|
||||
static int
|
||||
list_hashed_filename_targets (list, fmt)
|
||||
WORD_LIST *list;
|
||||
int fmt;
|
||||
list_hashed_filename_targets (WORD_LIST *list, int fmt)
|
||||
{
|
||||
int all_found, multiple;
|
||||
char *target;
|
||||
@@ -301,5 +299,5 @@ list_hashed_filename_targets (list, fmt)
|
||||
free (target);
|
||||
}
|
||||
|
||||
return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
return (sh_chkwrite (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE));
|
||||
}
|
||||
|
||||
+26
-47
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -58,7 +58,7 @@ $END
|
||||
#include <errno.h>
|
||||
|
||||
#include <filecntl.h>
|
||||
#include <stddef.h>
|
||||
#include "../bashansi.h"
|
||||
|
||||
#include "../bashintl.h"
|
||||
|
||||
@@ -79,22 +79,22 @@ extern int errno;
|
||||
extern const char * const bash_copyright;
|
||||
extern const char * const bash_license;
|
||||
|
||||
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));
|
||||
static void show_builtin_command_help (void);
|
||||
static int open_helpfile (const char *);
|
||||
static void show_desc (char *, int);
|
||||
static void show_manpage (char *, int);
|
||||
static void show_longdoc (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
|
||||
specified. */
|
||||
int
|
||||
help_builtin (list)
|
||||
WORD_LIST *list;
|
||||
help_builtin (WORD_LIST *list)
|
||||
{
|
||||
register int i;
|
||||
char *pattern, *name;
|
||||
int plen, match_found, sflag, dflag, mflag, m, pass, this_found;
|
||||
int match_found, sflag, dflag, mflag, m, pass, this_found;
|
||||
size_t plen;
|
||||
|
||||
dflag = sflag = mflag = 0;
|
||||
reset_internal_getopt ();
|
||||
@@ -190,30 +190,21 @@ help_builtin (list)
|
||||
}
|
||||
|
||||
void
|
||||
builtin_help ()
|
||||
builtin_help (void)
|
||||
{
|
||||
int ind;
|
||||
ptrdiff_t d;
|
||||
|
||||
current_builtin = builtin_address_internal (this_command_name, 0);
|
||||
if (current_builtin == 0)
|
||||
return;
|
||||
|
||||
d = current_builtin - shell_builtins;
|
||||
|
||||
#if defined (__STDC__)
|
||||
ind = (int)d;
|
||||
#else
|
||||
ind = (int)d / sizeof (struct builtin);
|
||||
#endif
|
||||
|
||||
ind = current_builtin - shell_builtins;
|
||||
printf ("%s: %s\n", this_command_name, _(shell_builtins[ind].short_doc));
|
||||
show_longdoc (ind);
|
||||
}
|
||||
|
||||
static int
|
||||
open_helpfile (name)
|
||||
char *name;
|
||||
open_helpfile (const char *name)
|
||||
{
|
||||
int fd;
|
||||
|
||||
@@ -230,8 +221,7 @@ open_helpfile (name)
|
||||
used, the long_doc array contains one string -- the full pathname of the
|
||||
help file for this builtin. */
|
||||
static void
|
||||
show_longdoc (i)
|
||||
int i;
|
||||
show_longdoc (int i)
|
||||
{
|
||||
register int j;
|
||||
char * const *doc;
|
||||
@@ -253,15 +243,13 @@ show_longdoc (i)
|
||||
}
|
||||
|
||||
static void
|
||||
show_desc (name, i)
|
||||
char *name;
|
||||
int i;
|
||||
show_desc (char *name, int i)
|
||||
{
|
||||
register int j, r;
|
||||
char **doc, *line;
|
||||
char * const *doc, *line;
|
||||
int fd, usefile;
|
||||
|
||||
doc = (char **)shell_builtins[i].long_doc;
|
||||
doc = shell_builtins[i].long_doc;
|
||||
|
||||
usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
|
||||
if (usefile)
|
||||
@@ -292,15 +280,14 @@ show_desc (name, i)
|
||||
|
||||
/* Print builtin help in pseudo-manpage format. */
|
||||
static void
|
||||
show_manpage (name, i)
|
||||
char *name;
|
||||
int i;
|
||||
show_manpage (char *name, int i)
|
||||
{
|
||||
register int j;
|
||||
char **doc, *line;
|
||||
char * const *doc;
|
||||
char *line;
|
||||
int fd, usefile;
|
||||
|
||||
doc = (char **)shell_builtins[i].long_doc;
|
||||
doc = shell_builtins[i].long_doc;
|
||||
|
||||
usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
|
||||
if (usefile)
|
||||
@@ -366,14 +353,10 @@ show_manpage (name, i)
|
||||
}
|
||||
|
||||
static void
|
||||
dispcolumn (i, buf, bufsize, width, height)
|
||||
int i;
|
||||
char *buf;
|
||||
size_t bufsize;
|
||||
int width, height;
|
||||
dispcolumn (int i, char *buf, size_t bufsize, int width, int height)
|
||||
{
|
||||
int j;
|
||||
int dispcols;
|
||||
size_t dispcols;
|
||||
char *helpdoc;
|
||||
|
||||
/* first column */
|
||||
@@ -408,11 +391,7 @@ dispcolumn (i, buf, bufsize, width, height)
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static void
|
||||
wdispcolumn (i, buf, bufsize, width, height)
|
||||
int i;
|
||||
char *buf;
|
||||
size_t bufsize;
|
||||
int width, height;
|
||||
wdispcolumn (int i, char *buf, size_t bufsize, int width, int height)
|
||||
{
|
||||
int j;
|
||||
int dispcols, dispchars;
|
||||
@@ -513,9 +492,9 @@ wdispcolumn (i, buf, bufsize, width, height)
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
static void
|
||||
show_builtin_command_help ()
|
||||
show_builtin_command_help (void)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
int height, width;
|
||||
char *t, blurb[128];
|
||||
|
||||
|
||||
+29
-21
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -46,7 +46,11 @@ Options:
|
||||
-s append the ARGs to the history list as a single entry
|
||||
|
||||
If FILENAME is given, it is used as the history file. Otherwise,
|
||||
if HISTFILE has a value, that is used, else ~/.bash_history.
|
||||
if HISTFILE has a value, that is used. If FILENAME is not supplied
|
||||
and HISTFILE is unset or null, the -a, -n, -r, and -w options have
|
||||
no effect and return success.
|
||||
|
||||
The fc builtin also operates on the history list.
|
||||
|
||||
If the HISTTIMEFORMAT variable is set and not null, its value is used
|
||||
as a format string for strftime(3) to print the time stamp associated
|
||||
@@ -86,10 +90,10 @@ $END
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
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 *));
|
||||
static char *histtime (HIST_ENTRY *, const char *);
|
||||
static int display_history (WORD_LIST *);
|
||||
static void push_history (WORD_LIST *);
|
||||
static int expand_and_print_history (WORD_LIST *);
|
||||
|
||||
#define AFLAG 0x01
|
||||
#define RFLAG 0x02
|
||||
@@ -105,8 +109,7 @@ static int expand_and_print_history PARAMS((WORD_LIST *));
|
||||
#endif
|
||||
|
||||
int
|
||||
history_builtin (list)
|
||||
WORD_LIST *list;
|
||||
history_builtin (WORD_LIST *list)
|
||||
{
|
||||
int flags, opt, result, old_history_lines, obase, ind;
|
||||
char *filename, *delete_arg, *range;
|
||||
@@ -186,7 +189,7 @@ history_builtin (list)
|
||||
{
|
||||
intmax_t delete_start, delete_end;
|
||||
*range++ = '\0';
|
||||
if (legal_number (delete_arg, &delete_start) == 0 || legal_number (range, &delete_end) == 0)
|
||||
if (valid_number (delete_arg, &delete_start) == 0 || valid_number (range, &delete_end) == 0)
|
||||
{
|
||||
range[-1] = '-';
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
@@ -223,9 +226,9 @@ history_builtin (list)
|
||||
}
|
||||
else if (flags & DFLAG)
|
||||
{
|
||||
if (legal_number (delete_arg, &delete_offset) == 0)
|
||||
if (valid_number (delete_arg, &delete_offset) == 0)
|
||||
{
|
||||
sh_erange (delete_arg, _("history position"));
|
||||
sh_invalidnum (delete_arg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
/* check for negative offsets, count back from end of list */
|
||||
@@ -268,6 +271,16 @@ history_builtin (list)
|
||||
filename = list ? list->word->word : get_string_value ("HISTFILE");
|
||||
result = EXECUTION_SUCCESS;
|
||||
|
||||
if (filename == 0 || *filename == 0)
|
||||
{
|
||||
if (interactive_shell == 0 || interactive)
|
||||
if (list && filename == list->word->word)
|
||||
builtin_error (_("empty filename"));
|
||||
else
|
||||
builtin_error (_("%s: parameter null or not set"), "HISTFILE");
|
||||
return (interactive ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted && strchr (filename, '/'))
|
||||
{
|
||||
@@ -322,9 +335,7 @@ history_builtin (list)
|
||||
#define histdata(i) (hlist[(i)]->data)
|
||||
|
||||
static char *
|
||||
histtime (hlist, histtimefmt)
|
||||
HIST_ENTRY *hlist;
|
||||
const char *histtimefmt;
|
||||
histtime (HIST_ENTRY *hlist, const char *histtimefmt)
|
||||
{
|
||||
static char timestr[TIMELEN_MAX];
|
||||
time_t t;
|
||||
@@ -343,8 +354,7 @@ histtime (hlist, histtimefmt)
|
||||
}
|
||||
|
||||
static int
|
||||
display_history (list)
|
||||
WORD_LIST *list;
|
||||
display_history (WORD_LIST *list)
|
||||
{
|
||||
register int i;
|
||||
intmax_t limit;
|
||||
@@ -354,7 +364,7 @@ display_history (list)
|
||||
if (list)
|
||||
{
|
||||
if (get_numeric_arg (list, 0, &limit) == 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
return (EX_USAGE);
|
||||
|
||||
if (limit < 0)
|
||||
limit = -limit;
|
||||
@@ -395,8 +405,7 @@ display_history (list)
|
||||
/* Remove the last entry in the history list and add each argument in
|
||||
LIST to the history. */
|
||||
static void
|
||||
push_history (list)
|
||||
WORD_LIST *list;
|
||||
push_history (WORD_LIST *list)
|
||||
{
|
||||
char *s;
|
||||
|
||||
@@ -432,8 +441,7 @@ push_history (list)
|
||||
|
||||
#if defined (BANG_HISTORY)
|
||||
static int
|
||||
expand_and_print_history (list)
|
||||
WORD_LIST *list;
|
||||
expand_and_print_history (WORD_LIST *list)
|
||||
{
|
||||
char *s;
|
||||
int r, result;
|
||||
|
||||
+16
-11
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -61,6 +61,7 @@ $END
|
||||
#include "../shell.h"
|
||||
#include "../jobs.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../parser.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -68,7 +69,7 @@ $END
|
||||
#define JSTATE_RUNNING 0x1
|
||||
#define JSTATE_STOPPED 0x2
|
||||
|
||||
static int execute_list_with_replacements PARAMS((WORD_LIST *));
|
||||
static int execute_list_with_replacements (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.
|
||||
@@ -79,8 +80,7 @@ static int execute_list_with_replacements PARAMS((WORD_LIST *));
|
||||
group leader and execute the command. The -r and -s options mean
|
||||
to print info about running and stopped jobs only, respectively. */
|
||||
int
|
||||
jobs_builtin (list)
|
||||
WORD_LIST *list;
|
||||
jobs_builtin (WORD_LIST *list)
|
||||
{
|
||||
int form, execute, state, opt, any_failed, job;
|
||||
sigset_t set, oset;
|
||||
@@ -136,6 +136,9 @@ jobs_builtin (list)
|
||||
{
|
||||
case JSTATE_ANY:
|
||||
list_all_jobs (form);
|
||||
/* POSIX says to remove terminated jobs from the list after the jobs
|
||||
builtin reports their status. */
|
||||
notify_and_cleanup (); /* the notify part will be a no-op */
|
||||
break;
|
||||
case JSTATE_RUNNING:
|
||||
list_running_jobs (form);
|
||||
@@ -163,12 +166,15 @@ jobs_builtin (list)
|
||||
UNBLOCK_CHILD (oset);
|
||||
list = list->next;
|
||||
}
|
||||
/* POSIX says to remove terminated jobs from the list after the jobs
|
||||
builtin reports their status. */
|
||||
notify_and_cleanup ();
|
||||
|
||||
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
execute_list_with_replacements (list)
|
||||
WORD_LIST *list;
|
||||
execute_list_with_replacements (WORD_LIST *list)
|
||||
{
|
||||
register WORD_LIST *l;
|
||||
int job, result;
|
||||
@@ -195,13 +201,13 @@ execute_list_with_replacements (list)
|
||||
/* Next make a new simple command and execute it. */
|
||||
begin_unwind_frame ("jobs_builtin");
|
||||
|
||||
command = make_bare_simple_command ();
|
||||
command = make_bare_simple_command (line_number);
|
||||
command->value.Simple->words = copy_word_list (list);
|
||||
command->value.Simple->redirects = (REDIRECT *)NULL;
|
||||
command->flags |= CMD_INHIBIT_EXPANSION;
|
||||
command->value.Simple->flags |= CMD_INHIBIT_EXPANSION;
|
||||
|
||||
add_unwind_protect (dispose_command, command);
|
||||
add_unwind_protect (uw_dispose_command, command);
|
||||
result = execute_command (command);
|
||||
dispose_command (command);
|
||||
|
||||
@@ -231,8 +237,7 @@ $END
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
int
|
||||
disown_builtin (list)
|
||||
WORD_LIST *list;
|
||||
disown_builtin (WORD_LIST *list)
|
||||
{
|
||||
int opt, job, retval, nohup_only, running_jobs, all_jobs;
|
||||
sigset_t set, oset;
|
||||
@@ -275,7 +280,7 @@ disown_builtin (list)
|
||||
do
|
||||
{
|
||||
BLOCK_CHILD (set, oset);
|
||||
job = (list && legal_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value)
|
||||
job = (list && valid_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value)
|
||||
? get_job_by_pid ((pid_t) pid_value, 0, 0)
|
||||
: get_job_spec (list);
|
||||
|
||||
|
||||
+5
-8
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 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 PARAMS((pid_t, int));
|
||||
static void kill_error (pid_t, int);
|
||||
|
||||
#if !defined (CONTINUE_AFTER_KILL_ERROR)
|
||||
# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
|
||||
@@ -82,8 +82,7 @@ static void kill_error PARAMS((pid_t, int));
|
||||
kill -KILL %1? No, if you fill up the process table this way you
|
||||
can still kill some. */
|
||||
int
|
||||
kill_builtin (list)
|
||||
WORD_LIST *list;
|
||||
kill_builtin (WORD_LIST *list)
|
||||
{
|
||||
int sig, any_succeeded, listing, saw_signal, dflags;
|
||||
char *sigspec, *word;
|
||||
@@ -190,7 +189,7 @@ use_sigspec:
|
||||
word++;
|
||||
|
||||
/* Use the entire argument in case of minus sign presence. */
|
||||
if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
|
||||
if (*word && valid_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
|
||||
{
|
||||
pid = (pid_t) pid_value;
|
||||
|
||||
@@ -263,9 +262,7 @@ use_sigspec:
|
||||
}
|
||||
|
||||
static void
|
||||
kill_error (pid, e)
|
||||
pid_t pid;
|
||||
int e;
|
||||
kill_error (pid_t pid, int e)
|
||||
{
|
||||
char *x;
|
||||
|
||||
|
||||
+2
-4
@@ -80,8 +80,7 @@ $END
|
||||
|
||||
/* Arithmetic LET function. */
|
||||
int
|
||||
let_builtin (list)
|
||||
WORD_LIST *list;
|
||||
let_builtin (WORD_LIST *list)
|
||||
{
|
||||
intmax_t ret;
|
||||
int expok;
|
||||
@@ -110,8 +109,7 @@ let_builtin (list)
|
||||
|
||||
#ifdef INCLUDE_UNUSED
|
||||
int
|
||||
exp_builtin (list)
|
||||
WORD_LIST *list;
|
||||
exp_builtin (WORD_LIST *list)
|
||||
{
|
||||
char *exp;
|
||||
intmax_t ret;
|
||||
|
||||
+15
-28
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -92,7 +92,7 @@ extern int errno;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
|
||||
static int run_callback PARAMS((const char *, unsigned int, const char *));
|
||||
static int run_callback (const char *, unsigned int, const char *);
|
||||
|
||||
#define DEFAULT_ARRAY_NAME "MAPFILE"
|
||||
#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
|
||||
@@ -104,13 +104,8 @@ static int run_callback PARAMS((const char *, unsigned int, const char *));
|
||||
#define MAPF_CLEARARRAY 0x01
|
||||
#define MAPF_CHOP 0x02
|
||||
|
||||
static int delim;
|
||||
|
||||
static int
|
||||
run_callback (callback, curindex, curline)
|
||||
const char *callback;
|
||||
unsigned int curindex;
|
||||
const char *curline;
|
||||
run_callback (const char *callback, unsigned int curindex, const char *curline)
|
||||
{
|
||||
unsigned int execlen;
|
||||
char *execstr, *qline;
|
||||
@@ -134,9 +129,7 @@ run_callback (callback, curindex, curline)
|
||||
}
|
||||
|
||||
static void
|
||||
do_chop(line, delim)
|
||||
char *line;
|
||||
unsigned char delim;
|
||||
do_chop(char *line, unsigned char delim)
|
||||
{
|
||||
int length;
|
||||
|
||||
@@ -146,12 +139,8 @@ do_chop(line, delim)
|
||||
}
|
||||
|
||||
static int
|
||||
mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, delim, flags)
|
||||
int fd;
|
||||
long line_count_goal, origin, nskip, callback_quantum;
|
||||
char *callback, *array_name;
|
||||
int delim;
|
||||
int flags;
|
||||
mapfile (int fd, long line_count_goal, long origin, long nskip, long callback_quantum,
|
||||
char *callback, char *array_name, int delim, int flags)
|
||||
{
|
||||
char *line;
|
||||
size_t line_length;
|
||||
@@ -231,10 +220,9 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
|
||||
}
|
||||
|
||||
int
|
||||
mapfile_builtin (list)
|
||||
WORD_LIST *list;
|
||||
mapfile_builtin (WORD_LIST *list)
|
||||
{
|
||||
int opt, code, fd, flags;
|
||||
int opt, code, fd, flags, delim;
|
||||
intmax_t intval;
|
||||
long lines, origin, nskip, callback_quantum;
|
||||
char *array_name, *callback;
|
||||
@@ -255,7 +243,7 @@ mapfile_builtin (list)
|
||||
delim = *list_optarg;
|
||||
break;
|
||||
case 'u':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
code = valid_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (int)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
|
||||
@@ -272,7 +260,7 @@ mapfile_builtin (list)
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
code = valid_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid line count"), list_optarg);
|
||||
@@ -283,7 +271,7 @@ mapfile_builtin (list)
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
code = valid_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid array origin"), list_optarg);
|
||||
@@ -300,7 +288,7 @@ mapfile_builtin (list)
|
||||
callback = list_optarg;
|
||||
break;
|
||||
case 'c':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
code = valid_number (list_optarg, &intval);
|
||||
if (code == 0 || intval <= 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid callback quantum"), list_optarg);
|
||||
@@ -310,7 +298,7 @@ mapfile_builtin (list)
|
||||
callback_quantum = intval;
|
||||
break;
|
||||
case 's':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
code = valid_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid line count"), list_optarg);
|
||||
@@ -342,7 +330,7 @@ mapfile_builtin (list)
|
||||
else
|
||||
array_name = list->word->word;
|
||||
|
||||
if (legal_identifier (array_name) == 0)
|
||||
if (valid_identifier (array_name) == 0)
|
||||
{
|
||||
sh_invalidid (array_name);
|
||||
return (EXECUTION_FAILURE);
|
||||
@@ -354,8 +342,7 @@ mapfile_builtin (list)
|
||||
#else
|
||||
|
||||
int
|
||||
mapfile_builtin (list)
|
||||
WORD_LIST *list;
|
||||
mapfile_builtin (WORD_LIST *list)
|
||||
{
|
||||
builtin_error (_("array variable support required"));
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
+99
-177
@@ -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-2022 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -59,11 +59,8 @@
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
static char *xmalloc (), *xrealloc ();
|
||||
|
||||
#if !defined (__STDC__) && !defined (strcpy)
|
||||
extern char *strcpy ();
|
||||
#endif /* !__STDC__ && !strcpy */
|
||||
static void *xmalloc (size_t);
|
||||
static void *xrealloc (void *, size_t);
|
||||
|
||||
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
|
||||
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
||||
@@ -175,13 +172,14 @@ char *localvar_builtins[] =
|
||||
/* The builtin commands that are special to the POSIX search order. */
|
||||
char *posix_builtins[] =
|
||||
{
|
||||
"alias", "bg", "cd", "command", "false", "fc", "fg", "getopts", "jobs",
|
||||
"kill", "newgrp", "pwd", "read", "true", "umask", "unalias", "wait",
|
||||
"alias", "bg", "cd", "command", "false", "fc", "fg", "getopts", "hash",
|
||||
"jobs", "kill", "newgrp", "pwd", "read", "true", "type", "ulimit",
|
||||
"umask", "unalias", "wait",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
/* The builtin commands that can take array references as arguments and pay
|
||||
attention to `assoc_expand_once'. These are the ones that don't assign
|
||||
attention to `array_expand_once'. These are the ones that don't assign
|
||||
values, but need to avoid double expansions. */
|
||||
char *arrayvar_builtins[] =
|
||||
{
|
||||
@@ -191,47 +189,47 @@ char *arrayvar_builtins[] =
|
||||
};
|
||||
|
||||
/* Forward declarations. */
|
||||
static int is_special_builtin ();
|
||||
static int is_assignment_builtin ();
|
||||
static int is_localvar_builtin ();
|
||||
static int is_posix_builtin ();
|
||||
static int is_arrayvar_builtin ();
|
||||
static int is_special_builtin (char *);
|
||||
static int is_assignment_builtin (char *);
|
||||
static int is_localvar_builtin (char *);
|
||||
static int is_posix_builtin (char *);
|
||||
static int is_arrayvar_builtin (char *);
|
||||
|
||||
#if !defined (HAVE_RENAME)
|
||||
static int rename ();
|
||||
static int rename (char *, char *);
|
||||
#endif
|
||||
|
||||
void extract_info ();
|
||||
void extract_info (char *, FILE *, FILE *);
|
||||
|
||||
void file_error ();
|
||||
void line_error ();
|
||||
void file_error (char *);
|
||||
void line_error (DEF_FILE *, char *, char *, char *);
|
||||
|
||||
void write_file_headers ();
|
||||
void write_file_footers ();
|
||||
void write_ifdefs ();
|
||||
void write_endifs ();
|
||||
void write_documentation ();
|
||||
void write_longdocs ();
|
||||
void write_builtins ();
|
||||
void write_file_headers (FILE *, FILE *);
|
||||
void write_file_footers (FILE *, FILE *);
|
||||
void write_ifdefs (FILE *, char **);
|
||||
void write_endifs (FILE *, char **);
|
||||
void write_documentation (FILE *, char **, int, int);
|
||||
void write_dummy_declarations (FILE *, ARRAY *);
|
||||
void write_longdocs (FILE *, ARRAY *);
|
||||
void write_builtins (DEF_FILE *, FILE *, FILE *);
|
||||
|
||||
int write_helpfiles ();
|
||||
int write_helpfiles (ARRAY *);
|
||||
|
||||
void free_defs ();
|
||||
void add_documentation ();
|
||||
static int _find_in_table (char *, char **);
|
||||
|
||||
void must_be_building ();
|
||||
void remove_trailing_whitespace ();
|
||||
void free_defs (DEF_FILE *);
|
||||
void add_documentation (DEF_FILE *, char *);
|
||||
|
||||
void must_be_building (char *, DEF_FILE *);
|
||||
void remove_trailing_whitespace (char *);
|
||||
|
||||
#define document_name(b) ((b)->docname ? (b)->docname : (b)->name)
|
||||
|
||||
|
||||
/* For each file mentioned on the command line, process it and
|
||||
write the information to STRUCTFILE and EXTERNFILE, while
|
||||
creating the production file if necessary. */
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int arg_index = 1;
|
||||
FILE *structfile, *externfile;
|
||||
@@ -384,8 +382,7 @@ main (argc, argv)
|
||||
/* Make a new array, and return a pointer to it. The array will
|
||||
contain elements of size WIDTH, and is initialized to no elements. */
|
||||
ARRAY *
|
||||
array_create (width)
|
||||
int width;
|
||||
array_create (int width)
|
||||
{
|
||||
ARRAY *array;
|
||||
|
||||
@@ -404,8 +401,7 @@ array_create (width)
|
||||
|
||||
/* Copy the array of strings in ARRAY. */
|
||||
ARRAY *
|
||||
copy_string_array (array)
|
||||
ARRAY *array;
|
||||
copy_string_array (ARRAY *array)
|
||||
{
|
||||
register int i;
|
||||
ARRAY *copy;
|
||||
@@ -431,9 +427,7 @@ copy_string_array (array)
|
||||
|
||||
/* Add ELEMENT to ARRAY, growing the array if necessary. */
|
||||
void
|
||||
array_add (element, array)
|
||||
char *element;
|
||||
ARRAY *array;
|
||||
array_add (char *element, ARRAY *array)
|
||||
{
|
||||
if (array->sindex + 2 > array->size)
|
||||
array->array = (char **)xrealloc
|
||||
@@ -445,8 +439,7 @@ array_add (element, array)
|
||||
|
||||
/* Free an allocated array and data pointer. */
|
||||
void
|
||||
array_free (array)
|
||||
ARRAY *array;
|
||||
array_free (ARRAY *array)
|
||||
{
|
||||
if (array->array)
|
||||
free (array->array);
|
||||
@@ -461,8 +454,7 @@ array_free (array)
|
||||
/* **************************************************************** */
|
||||
|
||||
/* The definition of a function. */
|
||||
typedef int Function ();
|
||||
typedef int mk_handler_func_t PARAMS((char *, DEF_FILE *, char *));
|
||||
typedef int mk_handler_func_t (char *, DEF_FILE *, char *);
|
||||
|
||||
/* Structure handles processor directives. */
|
||||
typedef struct {
|
||||
@@ -470,14 +462,14 @@ typedef struct {
|
||||
mk_handler_func_t *function;
|
||||
} HANDLER_ENTRY;
|
||||
|
||||
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 *));
|
||||
extern int builtin_handler (char *, DEF_FILE *, char *);
|
||||
extern int function_handler (char *, DEF_FILE *, char *);
|
||||
extern int short_doc_handler (char *, DEF_FILE *, char *);
|
||||
extern int comment_handler (char *, DEF_FILE *, char *);
|
||||
extern int depends_on_handler (char *, DEF_FILE *, char *);
|
||||
extern int produces_handler (char *, DEF_FILE *, char *);
|
||||
extern int end_handler (char *, DEF_FILE *, char *);
|
||||
extern int docname_handler (char *, DEF_FILE *, char *);
|
||||
|
||||
HANDLER_ENTRY handlers[] = {
|
||||
{ "BUILTIN", builtin_handler },
|
||||
@@ -494,8 +486,7 @@ HANDLER_ENTRY handlers[] = {
|
||||
|
||||
/* Return the entry in the table of handlers for NAME. */
|
||||
HANDLER_ENTRY *
|
||||
find_directive (directive)
|
||||
char *directive;
|
||||
find_directive (char *directive)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -524,9 +515,7 @@ int output_cpp_line_info = 0;
|
||||
builtins found in each $BUILTIN. Plain text found before the $PRODUCES
|
||||
is ignored, as is "$$ comment text". */
|
||||
void
|
||||
extract_info (filename, structfile, externfile)
|
||||
char *filename;
|
||||
FILE *structfile, *externfile;
|
||||
extract_info (char *filename, FILE *structfile, FILE *externfile)
|
||||
{
|
||||
register int i;
|
||||
DEF_FILE *defs;
|
||||
@@ -609,7 +598,7 @@ extract_info (filename, structfile, externfile)
|
||||
|
||||
if (!handler)
|
||||
{
|
||||
line_error (defs, "Unknown directive `%s'", directive);
|
||||
line_error (defs, "Unknown directive `%s'", directive, "");
|
||||
free (directive);
|
||||
continue;
|
||||
}
|
||||
@@ -666,8 +655,7 @@ extract_info (filename, structfile, externfile)
|
||||
#define free_safely(x) if (x) free (x)
|
||||
|
||||
static void
|
||||
free_builtin (builtin)
|
||||
BUILTIN_DESC *builtin;
|
||||
free_builtin (BUILTIN_DESC *builtin)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -689,8 +677,7 @@ free_builtin (builtin)
|
||||
|
||||
/* Free all of the memory allocated to a DEF_FILE. */
|
||||
void
|
||||
free_defs (defs)
|
||||
DEF_FILE *defs;
|
||||
free_defs (DEF_FILE *defs)
|
||||
{
|
||||
register int i;
|
||||
register BUILTIN_DESC *builtin;
|
||||
@@ -722,8 +709,7 @@ free_defs (defs)
|
||||
/* Strip surrounding whitespace from STRING, and
|
||||
return a pointer to the start of it. */
|
||||
char *
|
||||
strip_whitespace (string)
|
||||
char *string;
|
||||
strip_whitespace (char *string)
|
||||
{
|
||||
while (whitespace (*string))
|
||||
string++;
|
||||
@@ -734,8 +720,7 @@ strip_whitespace (string)
|
||||
|
||||
/* Remove only the trailing whitespace from STRING. */
|
||||
void
|
||||
remove_trailing_whitespace (string)
|
||||
char *string;
|
||||
remove_trailing_whitespace (char *string)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -752,35 +737,29 @@ remove_trailing_whitespace (string)
|
||||
DEFS is the DEF_FILE in which the directive is found.
|
||||
If there is no argument, produce an error. */
|
||||
char *
|
||||
get_arg (for_whom, defs, string)
|
||||
char *for_whom, *string;
|
||||
DEF_FILE *defs;
|
||||
get_arg (char *for_whom, DEF_FILE *defs, char *string)
|
||||
{
|
||||
char *new;
|
||||
|
||||
new = strip_whitespace (string);
|
||||
|
||||
if (!*new)
|
||||
line_error (defs, "%s requires an argument", for_whom);
|
||||
line_error (defs, "%s requires an argument", for_whom, "");
|
||||
|
||||
return (savestring (new));
|
||||
}
|
||||
|
||||
/* Error if not building a builtin. */
|
||||
void
|
||||
must_be_building (directive, defs)
|
||||
char *directive;
|
||||
DEF_FILE *defs;
|
||||
must_be_building (char *directive, DEF_FILE *defs)
|
||||
{
|
||||
if (!building_builtin)
|
||||
line_error (defs, "%s must be inside of a $BUILTIN block", directive);
|
||||
line_error (defs, "%s must be inside of a $BUILTIN block", directive, "");
|
||||
}
|
||||
|
||||
/* Return the current builtin. */
|
||||
BUILTIN_DESC *
|
||||
current_builtin (directive, defs)
|
||||
char *directive;
|
||||
DEF_FILE *defs;
|
||||
current_builtin (char *directive, DEF_FILE *defs)
|
||||
{
|
||||
must_be_building (directive, defs);
|
||||
if (defs->builtins)
|
||||
@@ -792,9 +771,7 @@ current_builtin (directive, defs)
|
||||
/* Add LINE to the long documentation for the current builtin.
|
||||
Ignore blank lines until the first non-blank line has been seen. */
|
||||
void
|
||||
add_documentation (defs, line)
|
||||
DEF_FILE *defs;
|
||||
char *line;
|
||||
add_documentation (DEF_FILE *defs, char *line)
|
||||
{
|
||||
register BUILTIN_DESC *builtin;
|
||||
|
||||
@@ -813,10 +790,7 @@ add_documentation (defs, line)
|
||||
|
||||
/* How to handle the $BUILTIN directive. */
|
||||
int
|
||||
builtin_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
builtin_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
BUILTIN_DESC *new;
|
||||
char *name;
|
||||
@@ -824,7 +798,7 @@ builtin_handler (self, defs, arg)
|
||||
/* If we are already building a builtin, we cannot start a new one. */
|
||||
if (building_builtin)
|
||||
{
|
||||
line_error (defs, "%s found before $END", self);
|
||||
line_error (defs, "%s found before $END", self, "");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -865,10 +839,7 @@ builtin_handler (self, defs, arg)
|
||||
|
||||
/* How to handle the $FUNCTION directive. */
|
||||
int
|
||||
function_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
function_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
register BUILTIN_DESC *builtin;
|
||||
|
||||
@@ -876,7 +847,7 @@ function_handler (self, defs, arg)
|
||||
|
||||
if (builtin == 0)
|
||||
{
|
||||
line_error (defs, "syntax error: no current builtin for $FUNCTION directive");
|
||||
line_error (defs, "syntax error: no current builtin for $FUNCTION directive", "", "");
|
||||
exit (1);
|
||||
}
|
||||
if (builtin->function)
|
||||
@@ -890,10 +861,7 @@ function_handler (self, defs, arg)
|
||||
|
||||
/* How to handle the $DOCNAME directive. */
|
||||
int
|
||||
docname_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
docname_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
register BUILTIN_DESC *builtin;
|
||||
|
||||
@@ -910,10 +878,7 @@ docname_handler (self, defs, arg)
|
||||
|
||||
/* How to handle the $SHORT_DOC directive. */
|
||||
int
|
||||
short_doc_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
short_doc_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
register BUILTIN_DESC *builtin;
|
||||
|
||||
@@ -930,20 +895,14 @@ short_doc_handler (self, defs, arg)
|
||||
|
||||
/* How to handle the $COMMENT directive. */
|
||||
int
|
||||
comment_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
comment_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* How to handle the $DEPENDS_ON directive. */
|
||||
int
|
||||
depends_on_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
depends_on_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
register BUILTIN_DESC *builtin;
|
||||
char *dependent;
|
||||
@@ -961,10 +920,7 @@ depends_on_handler (self, defs, arg)
|
||||
|
||||
/* How to handle the $PRODUCES directive. */
|
||||
int
|
||||
produces_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
produces_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
/* If just hacking documentation, don't change any of the production
|
||||
files. */
|
||||
@@ -995,10 +951,7 @@ produces_handler (self, defs, arg)
|
||||
|
||||
/* How to handle the $END directive. */
|
||||
int
|
||||
end_handler (self, defs, arg)
|
||||
char *self;
|
||||
DEF_FILE *defs;
|
||||
char *arg;
|
||||
end_handler (char *self, DEF_FILE *defs, char *arg)
|
||||
{
|
||||
must_be_building (self, defs);
|
||||
building_builtin = 0;
|
||||
@@ -1013,9 +966,7 @@ end_handler (self, defs, arg)
|
||||
|
||||
/* Produce an error for DEFS with FORMAT and ARGS. */
|
||||
void
|
||||
line_error (defs, format, arg1, arg2)
|
||||
DEF_FILE *defs;
|
||||
char *format, *arg1, *arg2;
|
||||
line_error (DEF_FILE *defs, char *format, char *arg1, char *arg2)
|
||||
{
|
||||
if (defs->filename[0] != '/')
|
||||
fprintf (stderr, "%s", error_directory ? error_directory : "./");
|
||||
@@ -1027,8 +978,7 @@ line_error (defs, format, arg1, arg2)
|
||||
|
||||
/* Print error message for FILENAME. */
|
||||
void
|
||||
file_error (filename)
|
||||
char *filename;
|
||||
file_error (char *filename)
|
||||
{
|
||||
perror (filename);
|
||||
exit (2);
|
||||
@@ -1040,30 +990,27 @@ file_error (filename)
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static void memory_error_and_abort ();
|
||||
static void memory_error_and_abort (void);
|
||||
|
||||
static char *
|
||||
xmalloc (bytes)
|
||||
int bytes;
|
||||
static void *
|
||||
xmalloc (size_t bytes)
|
||||
{
|
||||
char *temp = (char *)malloc (bytes);
|
||||
void *temp = malloc (bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ();
|
||||
return (temp);
|
||||
}
|
||||
|
||||
static char *
|
||||
xrealloc (pointer, bytes)
|
||||
char *pointer;
|
||||
int bytes;
|
||||
static void *
|
||||
xrealloc (void *pointer, size_t bytes)
|
||||
{
|
||||
char *temp;
|
||||
void *temp;
|
||||
|
||||
if (!pointer)
|
||||
temp = (char *)malloc (bytes);
|
||||
temp = malloc (bytes);
|
||||
else
|
||||
temp = (char *)realloc (pointer, bytes);
|
||||
temp = realloc (pointer, bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ();
|
||||
@@ -1072,7 +1019,7 @@ xrealloc (pointer, bytes)
|
||||
}
|
||||
|
||||
static void
|
||||
memory_error_and_abort ()
|
||||
memory_error_and_abort (void)
|
||||
{
|
||||
fprintf (stderr, "mkbuiltins: out of virtual memory\n");
|
||||
abort ();
|
||||
@@ -1087,8 +1034,7 @@ memory_error_and_abort ()
|
||||
/* Return a pointer to a newly allocated builtin which is
|
||||
an exact copy of BUILTIN. */
|
||||
BUILTIN_DESC *
|
||||
copy_builtin (builtin)
|
||||
BUILTIN_DESC *builtin;
|
||||
copy_builtin (BUILTIN_DESC *builtin)
|
||||
{
|
||||
BUILTIN_DESC *new;
|
||||
|
||||
@@ -1109,8 +1055,7 @@ copy_builtin (builtin)
|
||||
|
||||
/* How to save away a builtin. */
|
||||
void
|
||||
save_builtin (builtin)
|
||||
BUILTIN_DESC *builtin;
|
||||
save_builtin (BUILTIN_DESC *builtin)
|
||||
{
|
||||
BUILTIN_DESC *newbuiltin;
|
||||
|
||||
@@ -1187,8 +1132,7 @@ char *structfile_footer[] = {
|
||||
/* Write out any necessary opening information for
|
||||
STRUCTFILE and EXTERNFILE. */
|
||||
void
|
||||
write_file_headers (structfile, externfile)
|
||||
FILE *structfile, *externfile;
|
||||
write_file_headers (FILE *structfile, FILE *externfile)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1214,8 +1158,7 @@ write_file_headers (structfile, externfile)
|
||||
/* Write out any necessary closing information for
|
||||
STRUCTFILE and EXTERNFILE. */
|
||||
void
|
||||
write_file_footers (structfile, externfile)
|
||||
FILE *structfile, *externfile;
|
||||
write_file_footers (FILE *structfile, FILE *externfile)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1230,9 +1173,7 @@ write_file_footers (structfile, externfile)
|
||||
/* Write out the information accumulated in DEFS to
|
||||
STRUCTFILE and EXTERNFILE. */
|
||||
void
|
||||
write_builtins (defs, structfile, externfile)
|
||||
DEF_FILE *defs;
|
||||
FILE *structfile, *externfile;
|
||||
write_builtins (DEF_FILE *defs, FILE *structfile, FILE *externfile)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1258,7 +1199,7 @@ write_builtins (defs, structfile, externfile)
|
||||
if (externfile)
|
||||
{
|
||||
if (builtin->function)
|
||||
fprintf (externfile, "extern int %s PARAMS((WORD_LIST *));\n",
|
||||
fprintf (externfile, "extern int %s (WORD_LIST *);\n",
|
||||
builtin->function);
|
||||
|
||||
fprintf (externfile, "extern char * const %s_doc[];\n",
|
||||
@@ -1336,9 +1277,7 @@ write_builtins (defs, structfile, externfile)
|
||||
|
||||
/* Write out the long documentation strings in BUILTINS to STREAM. */
|
||||
void
|
||||
write_longdocs (stream, builtins)
|
||||
FILE *stream;
|
||||
ARRAY *builtins;
|
||||
write_longdocs (FILE *stream, ARRAY *builtins)
|
||||
{
|
||||
register int i;
|
||||
register BUILTIN_DESC *builtin;
|
||||
@@ -1375,9 +1314,7 @@ write_longdocs (stream, builtins)
|
||||
}
|
||||
|
||||
void
|
||||
write_dummy_declarations (stream, builtins)
|
||||
FILE *stream;
|
||||
ARRAY *builtins;
|
||||
write_dummy_declarations (FILE *stream, ARRAY *builtins)
|
||||
{
|
||||
register int i;
|
||||
BUILTIN_DESC *builtin;
|
||||
@@ -1401,9 +1338,7 @@ write_dummy_declarations (stream, builtins)
|
||||
If a define is preceded by an `!', then the sense of the test is
|
||||
reversed. */
|
||||
void
|
||||
write_ifdefs (stream, defines)
|
||||
FILE *stream;
|
||||
char **defines;
|
||||
write_ifdefs (FILE *stream, char **defines)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1432,9 +1367,7 @@ write_ifdefs (stream, defines)
|
||||
STREAM is the stream to write the information to.
|
||||
DEFINES is a null terminated array of define names. */
|
||||
void
|
||||
write_endifs (stream, defines)
|
||||
FILE *stream;
|
||||
char **defines;
|
||||
write_endifs (FILE *stream, char **defines)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1459,10 +1392,7 @@ write_endifs (stream, defines)
|
||||
internationalization (gettext) and the single-string vs. multiple-strings
|
||||
issues. */
|
||||
void
|
||||
write_documentation (stream, documentation, indentation, flags)
|
||||
FILE *stream;
|
||||
char **documentation;
|
||||
int indentation, flags;
|
||||
write_documentation (FILE *stream, char **documentation, int indentation, int flags)
|
||||
{
|
||||
register int i, j;
|
||||
register char *line;
|
||||
@@ -1590,8 +1520,7 @@ write_documentation (stream, documentation, indentation, flags)
|
||||
}
|
||||
|
||||
int
|
||||
write_helpfiles (builtins)
|
||||
ARRAY *builtins;
|
||||
write_helpfiles (ARRAY *builtins)
|
||||
{
|
||||
char *helpfile, *bname;
|
||||
FILE *helpfp;
|
||||
@@ -1632,8 +1561,7 @@ write_helpfiles (builtins)
|
||||
}
|
||||
|
||||
static int
|
||||
_find_in_table (name, name_table)
|
||||
char *name, *name_table[];
|
||||
_find_in_table (char *name, char **name_table)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -1644,44 +1572,38 @@ _find_in_table (name, name_table)
|
||||
}
|
||||
|
||||
static int
|
||||
is_special_builtin (name)
|
||||
char *name;
|
||||
is_special_builtin (char *name)
|
||||
{
|
||||
return (_find_in_table (name, special_builtins));
|
||||
}
|
||||
|
||||
static int
|
||||
is_assignment_builtin (name)
|
||||
char *name;
|
||||
is_assignment_builtin (char *name)
|
||||
{
|
||||
return (_find_in_table (name, assignment_builtins));
|
||||
}
|
||||
|
||||
static int
|
||||
is_localvar_builtin (name)
|
||||
char *name;
|
||||
is_localvar_builtin (char *name)
|
||||
{
|
||||
return (_find_in_table (name, localvar_builtins));
|
||||
}
|
||||
|
||||
static int
|
||||
is_posix_builtin (name)
|
||||
char *name;
|
||||
is_posix_builtin (char *name)
|
||||
{
|
||||
return (_find_in_table (name, posix_builtins));
|
||||
}
|
||||
|
||||
static int
|
||||
is_arrayvar_builtin (name)
|
||||
char *name;
|
||||
is_arrayvar_builtin (char *name)
|
||||
{
|
||||
return (_find_in_table (name, arrayvar_builtins));
|
||||
}
|
||||
|
||||
#if !defined (HAVE_RENAME)
|
||||
static int
|
||||
rename (from, to)
|
||||
char *from, *to;
|
||||
rename (char *from, char *to)
|
||||
{
|
||||
unlink (to);
|
||||
if (link (from, to) < 0)
|
||||
|
||||
+547
-246
File diff suppressed because it is too large
Load Diff
+3
-6
@@ -1,6 +1,6 @@
|
||||
/* psize.c - Find pipe size. */
|
||||
|
||||
/* Copyright (C) 1987, 1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987, 1991, 2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -48,17 +48,14 @@ extern int errno;
|
||||
int nw;
|
||||
|
||||
sighandler
|
||||
sigpipe (sig)
|
||||
int sig;
|
||||
sigpipe (int sig)
|
||||
{
|
||||
fprintf (stderr, "%d\n", nw);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char buf[128];
|
||||
register int i;
|
||||
|
||||
+53
-46
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -116,6 +116,10 @@ $END
|
||||
#include <config.h>
|
||||
|
||||
#if defined (PUSHD_AND_POPD)
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
# include "builtins.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined (HAVE_SYS_PARAM_H)
|
||||
# include <sys/param.h>
|
||||
@@ -140,10 +144,6 @@ $END
|
||||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
# include "builtins.h"
|
||||
#endif
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
@@ -152,17 +152,17 @@ extern int errno;
|
||||
static char **pushd_directory_list = (char **)NULL;
|
||||
|
||||
/* Number of existing slots in this list. */
|
||||
static int directory_list_size;
|
||||
static size_t directory_list_size;
|
||||
|
||||
/* Offset to the end of the list. */
|
||||
static int directory_list_offset;
|
||||
|
||||
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 *));
|
||||
static void pushd_error (int, char *);
|
||||
static void clear_directory_stack (void);
|
||||
static int cd_to_string (char *);
|
||||
static int change_to_temp (char *);
|
||||
static void add_dirstack_element (char *);
|
||||
static int get_dirstack_index (intmax_t, int, int *);
|
||||
|
||||
#define NOCD 0x01
|
||||
#define ROTATE 0x02
|
||||
@@ -170,8 +170,7 @@ static int get_dirstack_index PARAMS((intmax_t, int, int *));
|
||||
#define CLEARSTAK 0x08
|
||||
|
||||
int
|
||||
pushd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
pushd_builtin (WORD_LIST *list)
|
||||
{
|
||||
WORD_LIST *orig_list;
|
||||
char *temp, *current_directory, *top;
|
||||
@@ -228,7 +227,7 @@ pushd_builtin (list)
|
||||
break;
|
||||
else if (((direction = list->word->word[0]) == '+') || direction == '-')
|
||||
{
|
||||
if (legal_number (list->word->word + 1, &num) == 0)
|
||||
if (valid_number (list->word->word + 1, &num) == 0)
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
@@ -316,8 +315,7 @@ pushd_builtin (list)
|
||||
If LIST is non-null it should consist of a word +N or -N, which says
|
||||
what element to delete from the stack. The default is the top one. */
|
||||
int
|
||||
popd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
popd_builtin (WORD_LIST *list)
|
||||
{
|
||||
register int i;
|
||||
intmax_t which;
|
||||
@@ -341,7 +339,7 @@ popd_builtin (list)
|
||||
}
|
||||
else if (((direction = list->word->word[0]) == '+') || direction == '-')
|
||||
{
|
||||
if (legal_number (list->word->word + 1, &which) == 0)
|
||||
if (valid_number (list->word->word + 1, &which) == 0)
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
@@ -365,6 +363,30 @@ popd_builtin (list)
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If we didn't find `which' but there are arguments remaining, assume we
|
||||
got `--' */
|
||||
if (which_word == 0 && list)
|
||||
{
|
||||
if (((direction = list->word->word[0]) == '+') || direction == '-')
|
||||
{
|
||||
if (valid_number (list->word->word + 1, &which) == 0)
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
which_word = list->word->word;
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin_error (_("%s: invalid argument"), list->word->word);
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (which > directory_list_offset || (which < -directory_list_offset) || (directory_list_offset == 0 && which == 0))
|
||||
{
|
||||
pushd_error (directory_list_offset, which_word ? which_word : "");
|
||||
@@ -406,8 +428,7 @@ popd_builtin (list)
|
||||
|
||||
/* Print the current list of directories on the directory stack. */
|
||||
int
|
||||
dirs_builtin (list)
|
||||
WORD_LIST *list;
|
||||
dirs_builtin (WORD_LIST *list)
|
||||
{
|
||||
int flags, desired_index, index_flag, vflag;
|
||||
intmax_t i;
|
||||
@@ -440,7 +461,7 @@ dirs_builtin (list)
|
||||
else if (*list->word->word == '+' || *list->word->word == '-')
|
||||
{
|
||||
int sign;
|
||||
if (legal_number (w = list->word->word + 1, &i) == 0)
|
||||
if (valid_number (w = list->word->word + 1, &i) == 0)
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
@@ -516,9 +537,7 @@ dirs_builtin (list)
|
||||
}
|
||||
|
||||
static void
|
||||
pushd_error (offset, arg)
|
||||
int offset;
|
||||
char *arg;
|
||||
pushd_error (int offset, char *arg)
|
||||
{
|
||||
if (offset == 0)
|
||||
builtin_error (_("directory stack empty"));
|
||||
@@ -527,7 +546,7 @@ pushd_error (offset, arg)
|
||||
}
|
||||
|
||||
static void
|
||||
clear_directory_stack ()
|
||||
clear_directory_stack (void)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -540,8 +559,7 @@ clear_directory_stack ()
|
||||
so if the result is EXECUTION_FAILURE then an error message has already
|
||||
been printed. */
|
||||
static int
|
||||
cd_to_string (name)
|
||||
char *name;
|
||||
cd_to_string (char *name)
|
||||
{
|
||||
WORD_LIST *tlist;
|
||||
WORD_LIST *dir;
|
||||
@@ -555,8 +573,7 @@ cd_to_string (name)
|
||||
}
|
||||
|
||||
static int
|
||||
change_to_temp (temp)
|
||||
char *temp;
|
||||
change_to_temp (char *temp)
|
||||
{
|
||||
int tt;
|
||||
|
||||
@@ -569,8 +586,7 @@ change_to_temp (temp)
|
||||
}
|
||||
|
||||
static void
|
||||
add_dirstack_element (dir)
|
||||
char *dir;
|
||||
add_dirstack_element (char *dir)
|
||||
{
|
||||
if (directory_list_offset == directory_list_size)
|
||||
pushd_directory_list = strvec_resize (pushd_directory_list, directory_list_size += 10);
|
||||
@@ -578,9 +594,7 @@ add_dirstack_element (dir)
|
||||
}
|
||||
|
||||
static int
|
||||
get_dirstack_index (ind, sign, indexp)
|
||||
intmax_t ind;
|
||||
int sign, *indexp;
|
||||
get_dirstack_index (intmax_t ind, int sign, int *indexp)
|
||||
{
|
||||
if (indexp)
|
||||
*indexp = sign > 0 ? 1 : 2;
|
||||
@@ -603,8 +617,7 @@ get_dirstack_index (ind, sign, indexp)
|
||||
|
||||
/* Used by the tilde expansion code. */
|
||||
char *
|
||||
get_dirstack_from_string (string)
|
||||
char *string;
|
||||
get_dirstack_from_string (char *string)
|
||||
{
|
||||
int ind, sign, index_flag;
|
||||
intmax_t i;
|
||||
@@ -615,7 +628,7 @@ get_dirstack_from_string (string)
|
||||
sign = (*string == '-') ? -1 : 1;
|
||||
string++;
|
||||
}
|
||||
if (legal_number (string, &i) == 0)
|
||||
if (valid_number (string, &i) == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
index_flag = 0;
|
||||
@@ -630,9 +643,7 @@ get_dirstack_from_string (string)
|
||||
|
||||
#ifdef INCLUDE_UNUSED
|
||||
char *
|
||||
get_dirstack_element (ind, sign)
|
||||
intmax_t ind;
|
||||
int sign;
|
||||
get_dirstack_element (intmax_t ind, int sign)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -643,10 +654,7 @@ get_dirstack_element (ind, sign)
|
||||
#endif
|
||||
|
||||
void
|
||||
set_dirstack_element (ind, sign, value)
|
||||
intmax_t ind;
|
||||
int sign;
|
||||
char *value;
|
||||
set_dirstack_element (intmax_t ind, int sign, char *value)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -658,8 +666,7 @@ set_dirstack_element (ind, sign, value)
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
get_directory_stack (flags)
|
||||
int flags;
|
||||
get_directory_stack (int flags)
|
||||
{
|
||||
register int i;
|
||||
WORD_LIST *ret;
|
||||
|
||||
+143
-101
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -22,7 +22,7 @@ $PRODUCES read.c
|
||||
|
||||
$BUILTIN read
|
||||
$FUNCTION read_builtin
|
||||
$SHORT_DOC read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
|
||||
$SHORT_DOC read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
|
||||
Read a line from the standard input and split it into fields.
|
||||
|
||||
Reads a single line from the standard input, or from file descriptor FD
|
||||
@@ -41,6 +41,8 @@ Options:
|
||||
-d delim continue until the first character of DELIM is read, rather
|
||||
than newline
|
||||
-e use Readline to obtain the line
|
||||
-E use Readline to obtain the line and use the bash default
|
||||
completion instead of Readline's default completion
|
||||
-i text use TEXT as the initial text for Readline
|
||||
-n nchars return after reading NCHARS characters rather than waiting
|
||||
for a newline, but honor a delimiter if fewer than
|
||||
@@ -86,7 +88,6 @@ $END
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include "../bashintl.h"
|
||||
@@ -103,9 +104,7 @@ $END
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
|
||||
#if defined (BUFFERED_INPUT)
|
||||
# include "input.h"
|
||||
#endif
|
||||
#include "input.h"
|
||||
|
||||
#include "shmbutil.h"
|
||||
#include "timer.h"
|
||||
@@ -121,28 +120,29 @@ struct ttsave
|
||||
};
|
||||
|
||||
#if defined (READLINE)
|
||||
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 *));
|
||||
static void set_readline_timeout PARAMS((sh_timer *t, time_t, long));
|
||||
static void uw_reset_attempted_completion_function (void *);
|
||||
static int set_itext (void);
|
||||
static char *edit_line (char *, char *, unsigned char, int);
|
||||
static void set_eol_delim (int);
|
||||
static void reset_eol_delim (void *);
|
||||
static void set_readline_timeout (sh_timer *t, time_t, long);
|
||||
static void uw_bashline_reset_event_hook (void *);
|
||||
#endif
|
||||
static SHELL_VAR *bind_read_variable PARAMS((char *, char *, int));
|
||||
static SHELL_VAR *bind_read_variable (char *, char *, int);
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static int read_mbchar PARAMS((int, char *, int, int, int));
|
||||
static int read_mbchar (int, char *, int, int, int);
|
||||
#endif
|
||||
static void ttyrestore PARAMS((struct ttsave *));
|
||||
static void ttyrestore (struct ttsave *);
|
||||
static void uw_ttyrestore (void *);
|
||||
|
||||
static sighandler sigalrm PARAMS((int));
|
||||
static void reset_timeout PARAMS((void));
|
||||
static sighandler sigalrm (int);
|
||||
static void reset_timeout (void);
|
||||
static void uw_reset_timeout (void *);
|
||||
|
||||
/* Try this to see what the rest of the shell can do with the information. */
|
||||
sh_timer *read_timeout;
|
||||
|
||||
static int reading, tty_modified;
|
||||
static SigHandler *old_alrm;
|
||||
static unsigned char delim;
|
||||
|
||||
static struct ttsave termsave;
|
||||
|
||||
@@ -153,8 +153,7 @@ static struct ttsave termsave;
|
||||
/* Set a flag that check_read_timeout can check. This relies on zread or
|
||||
read_builtin calling trap.c:check_signals() (which calls check_read_timeout()) */
|
||||
static sighandler
|
||||
sigalrm (s)
|
||||
int s;
|
||||
sigalrm (int s)
|
||||
{
|
||||
/* Display warning if this is called without read_timeout set? */
|
||||
if (read_timeout)
|
||||
@@ -162,7 +161,7 @@ sigalrm (s)
|
||||
}
|
||||
|
||||
static void
|
||||
reset_timeout ()
|
||||
reset_timeout (void)
|
||||
{
|
||||
/* Cancel alarm before restoring signal handler. */
|
||||
if (read_timeout)
|
||||
@@ -173,24 +172,33 @@ reset_timeout ()
|
||||
read_timeout = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
uw_reset_timeout (void *ignore)
|
||||
{
|
||||
reset_timeout ();
|
||||
}
|
||||
|
||||
void
|
||||
check_read_timeout ()
|
||||
check_read_timeout (void)
|
||||
{
|
||||
if (read_timeout && shtimer_chktimeout (read_timeout))
|
||||
sh_longjmp (read_timeout->jmpenv, 1);
|
||||
}
|
||||
|
||||
int
|
||||
read_builtin_timeout (fd)
|
||||
int fd;
|
||||
read_builtin_timeout (int fd)
|
||||
{
|
||||
if ((read_timeout == 0) ||
|
||||
(read_timeout->fd != fd) ||
|
||||
(read_timeout->tmout.tv_sec == 0 && read_timeout->tmout.tv_usec == 0))
|
||||
return 0;
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
return ((read_timeout->flags & SHTIMER_ALARM) ? shtimer_alrm (read_timeout)
|
||||
: shtimer_select (read_timeout));
|
||||
#else
|
||||
return (shtimer_alrm (read_timeout));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Read the value of the shell variables whose names follow.
|
||||
@@ -200,20 +208,23 @@ read_builtin_timeout (fd)
|
||||
gets the remainder of the words on the line. If no variables
|
||||
are mentioned in LIST, then the default variable is $REPLY. */
|
||||
int
|
||||
read_builtin (list)
|
||||
WORD_LIST *list;
|
||||
read_builtin (WORD_LIST *list)
|
||||
{
|
||||
register char *varname;
|
||||
int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag;
|
||||
char *varname;
|
||||
int nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag;
|
||||
size_t size;
|
||||
volatile int i;
|
||||
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
|
||||
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd;
|
||||
int edit, use_bash_completion;
|
||||
int raw, nchars, silent, have_timeout, ignore_delim, fd;
|
||||
int free_ifs;
|
||||
int lastsig, t_errno;
|
||||
int mb_cur_max;
|
||||
unsigned int tmsec, tmusec;
|
||||
long ival, uval;
|
||||
intmax_t intval;
|
||||
char c;
|
||||
unsigned char delim;
|
||||
char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
|
||||
char *e, *t, *t1, *ps2, *tofree;
|
||||
struct stat tsb;
|
||||
@@ -239,6 +250,8 @@ read_builtin (list)
|
||||
USE_VAR(input_is_pipe);
|
||||
/* USE_VAR(raw); */
|
||||
USE_VAR(edit);
|
||||
USE_VAR(use_bash_completion);
|
||||
USE_VAR(delim);
|
||||
USE_VAR(tmsec);
|
||||
USE_VAR(tmusec);
|
||||
USE_VAR(nchars);
|
||||
@@ -260,6 +273,7 @@ read_builtin (list)
|
||||
|
||||
i = 0; /* Index into the string that we are reading. */
|
||||
raw = edit = 0; /* Not reading raw input by default. */
|
||||
use_bash_completion = 0;
|
||||
silent = 0;
|
||||
arrayname = prompt = (char *)NULL;
|
||||
fd = 0; /* file descriptor to read from */
|
||||
@@ -276,7 +290,7 @@ read_builtin (list)
|
||||
ignore_delim = nflag = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:N:")) != -1)
|
||||
while ((opt = internal_getopt (list, "Eersa:d:i:n:p:t:u:N:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
@@ -294,6 +308,12 @@ read_builtin (list)
|
||||
edit = 1;
|
||||
#endif
|
||||
break;
|
||||
case 'E':
|
||||
#if defined (READLINE)
|
||||
edit = use_bash_completion = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
#if defined (READLINE)
|
||||
itext = list_optarg;
|
||||
@@ -323,7 +343,7 @@ read_builtin (list)
|
||||
delim = -1;
|
||||
case 'n':
|
||||
nflag = 1;
|
||||
code = legal_number (list_optarg, &intval);
|
||||
code = valid_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (int)intval)
|
||||
{
|
||||
sh_invalidnum (list_optarg);
|
||||
@@ -333,7 +353,7 @@ read_builtin (list)
|
||||
nchars = intval;
|
||||
break;
|
||||
case 'u':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
code = valid_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (int)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
|
||||
@@ -368,10 +388,10 @@ read_builtin (list)
|
||||
#if defined (ARRAY_VARS)
|
||||
if (list)
|
||||
SET_VFLAGS (list->word->flags, vflags, bindflags);
|
||||
if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
|
||||
if (list && valid_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
|
||||
#else
|
||||
bindflags = 0;
|
||||
if (list && legal_identifier (list->word->word) == 0)
|
||||
if (list && valid_identifier (list->word->word) == 0)
|
||||
#endif
|
||||
{
|
||||
sh_invalidid (list->word->word);
|
||||
@@ -383,18 +403,27 @@ read_builtin (list)
|
||||
delim = -1;
|
||||
|
||||
/* IF IFS is unset, we use the default of " \t\n". */
|
||||
ifs_chars = getifs ();
|
||||
if (ifs_chars == 0) /* XXX - shouldn't happen */
|
||||
ifs_chars = "";
|
||||
free_ifs = 0;
|
||||
/* If we want to read exactly NCHARS chars, don't split on IFS */
|
||||
if (ignore_delim)
|
||||
ifs_chars = "";
|
||||
else
|
||||
{
|
||||
ifs_chars = getifs ();
|
||||
if (ifs_chars == 0) /* XXX - shouldn't happen */
|
||||
ifs_chars = "";
|
||||
else
|
||||
free_ifs = 1;
|
||||
}
|
||||
for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++)
|
||||
skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL;
|
||||
|
||||
input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
|
||||
input_string[0] = '\0';
|
||||
|
||||
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
||||
saw_escape = 0; /* Non-zero is count of escape chars we added */
|
||||
|
||||
/* More input and options validation */
|
||||
if (nflag == 1 && nchars == 0)
|
||||
{
|
||||
@@ -420,14 +449,14 @@ read_builtin (list)
|
||||
sigemptyset (&chldset);
|
||||
sigprocmask (SIG_BLOCK, (sigset_t *)0, &chldset);
|
||||
sigaddset (&chldset, SIGCHLD);
|
||||
sigemptyset (&prevset);
|
||||
sigprocmask (SIG_SETMASK, (sigset_t *)0, &prevset);
|
||||
#endif
|
||||
|
||||
begin_unwind_frame ("read_builtin");
|
||||
|
||||
#if defined (BUFFERED_INPUT)
|
||||
if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd))
|
||||
sync_buffered_stream (default_buffered_input);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
input_is_tty = isatty (fd);
|
||||
@@ -436,7 +465,7 @@ read_builtin (list)
|
||||
#endif
|
||||
if (input_is_tty == 0)
|
||||
#ifndef __CYGWIN__
|
||||
input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
|
||||
input_is_pipe = fd_ispipe (fd);
|
||||
#else
|
||||
input_is_pipe = 1;
|
||||
#endif
|
||||
@@ -457,9 +486,6 @@ read_builtin (list)
|
||||
add_unwind_protect (xfree, rlbuf);
|
||||
#endif
|
||||
|
||||
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
||||
saw_escape = 0; /* Non-zero signifies that we saw an escape char */
|
||||
|
||||
if (tmsec > 0 || tmusec > 0)
|
||||
{
|
||||
/* Turn off the timeout if stdin is a regular file (e.g. from
|
||||
@@ -473,7 +499,7 @@ read_builtin (list)
|
||||
read_timeout = shtimer_alloc ();
|
||||
read_timeout->flags = SHTIMER_LONGJMP;
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
#if defined (HAVE_SELECT) || defined (HAVE_PSELECT)
|
||||
read_timeout->flags |= (edit || posixly_correct) ? SHTIMER_ALARM : SHTIMER_SELECT;
|
||||
#else
|
||||
read_timeout->flags |= SHTIMER_ALARM;
|
||||
@@ -489,7 +515,9 @@ read_builtin (list)
|
||||
if (code)
|
||||
{
|
||||
reset_timeout ();
|
||||
#if defined (SIGCHLD)
|
||||
sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0);
|
||||
#endif
|
||||
|
||||
/* Tricky. The top of the unwind-protect stack is the free of
|
||||
input_string. We want to run all the rest and use input_string,
|
||||
@@ -512,12 +540,12 @@ read_builtin (list)
|
||||
}
|
||||
if (interactive_shell == 0)
|
||||
initialize_terminating_signals ();
|
||||
add_unwind_protect (reset_timeout, (char *)NULL);
|
||||
add_unwind_protect (uw_reset_timeout, NULL);
|
||||
#if defined (READLINE)
|
||||
if (edit)
|
||||
{
|
||||
add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
|
||||
add_unwind_protect (bashline_reset_event_hook, (char *)NULL);
|
||||
add_unwind_protect (uw_reset_attempted_completion_function, NULL);
|
||||
add_unwind_protect (uw_bashline_reset_event_hook, NULL);
|
||||
set_readline_timeout (read_timeout, tmsec, tmusec);
|
||||
}
|
||||
else
|
||||
@@ -541,7 +569,7 @@ read_builtin (list)
|
||||
if (delim != '\n')
|
||||
{
|
||||
set_eol_delim (delim);
|
||||
add_unwind_protect (reset_eol_delim, (char *)NULL);
|
||||
add_unwind_protect (reset_eol_delim, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -558,7 +586,7 @@ read_builtin (list)
|
||||
if (i < 0)
|
||||
sh_ttyerror (1);
|
||||
tty_modified = 1;
|
||||
add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
|
||||
add_unwind_protect (uw_ttyrestore, &termsave);
|
||||
if (interactive_shell == 0)
|
||||
initialize_terminating_signals ();
|
||||
}
|
||||
@@ -576,7 +604,7 @@ read_builtin (list)
|
||||
sh_ttyerror (1);
|
||||
|
||||
tty_modified = 1;
|
||||
add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
|
||||
add_unwind_protect (uw_ttyrestore, &termsave);
|
||||
if (interactive_shell == 0)
|
||||
initialize_terminating_signals ();
|
||||
}
|
||||
@@ -614,10 +642,6 @@ read_builtin (list)
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
#if defined (__CYGWIN__) && defined (O_TEXT)
|
||||
setmode (0, O_TEXT);
|
||||
#endif
|
||||
|
||||
ps2 = 0;
|
||||
for (print_ps2 = eof = retval = 0;;)
|
||||
{
|
||||
@@ -639,7 +663,7 @@ read_builtin (list)
|
||||
if (rlbuf == 0)
|
||||
{
|
||||
reading = 1;
|
||||
rlbuf = edit_line (prompt ? prompt : "", itext);
|
||||
rlbuf = edit_line (prompt ? prompt : "", itext, delim, use_bash_completion);
|
||||
reading = 0;
|
||||
rlind = 0;
|
||||
}
|
||||
@@ -690,9 +714,9 @@ read_builtin (list)
|
||||
|
||||
if (retval <= 0)
|
||||
{
|
||||
int t;
|
||||
int x;
|
||||
|
||||
t = errno;
|
||||
x = errno;
|
||||
if (retval < 0 && errno == EINTR)
|
||||
{
|
||||
check_signals (); /* in case we didn't call zread via zreadc */
|
||||
@@ -709,7 +733,7 @@ read_builtin (list)
|
||||
ttyrestore (&termsave); /* fix terminal before exiting */
|
||||
CHECK_TERMSIG;
|
||||
eof = 1;
|
||||
errno = t; /* preserve it for the error message below */
|
||||
errno = x; /* preserve it for the error message below */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -724,13 +748,13 @@ read_builtin (list)
|
||||
/* XXX -- use i + mb_cur_max (at least 4) for multibyte/read_mbchar */
|
||||
if (i + (mb_cur_max > 4 ? mb_cur_max : 4) >= size)
|
||||
{
|
||||
char *t;
|
||||
t = (char *)xrealloc (input_string, size += 128);
|
||||
char *x;
|
||||
x = (char *)xrealloc (input_string, size += 128);
|
||||
|
||||
/* Only need to change unwind-protect if input_string changes */
|
||||
if (t != input_string)
|
||||
if (x != input_string)
|
||||
{
|
||||
input_string = t;
|
||||
input_string = x;
|
||||
remove_unwind_protect ();
|
||||
add_unwind_protect (xfree, input_string);
|
||||
}
|
||||
@@ -741,11 +765,14 @@ read_builtin (list)
|
||||
if (pass_next)
|
||||
{
|
||||
pass_next = 0;
|
||||
if (c == '\n')
|
||||
if (c == '\n' || c == '\0')
|
||||
{
|
||||
if (skip_ctlesc == 0 && i > 0)
|
||||
i--; /* back up over the CTLESC */
|
||||
if (interactive && input_is_tty && raw == 0)
|
||||
{
|
||||
i--; /* back up over the CTLESC */
|
||||
saw_escape--; /* one fewer CTLESC in the input */
|
||||
}
|
||||
if (interactive && input_is_tty && raw == 0 && c == '\n')
|
||||
print_ps2 = 1;
|
||||
}
|
||||
else
|
||||
@@ -815,6 +842,17 @@ add_char:
|
||||
if (nchars > 0 && nr >= nchars)
|
||||
break;
|
||||
}
|
||||
/* Back up over trailing CTLESC if the input ends with an unescaped
|
||||
backslash */
|
||||
if (pass_next && skip_ctlesc == 0)
|
||||
{
|
||||
i--;
|
||||
saw_escape--; /* that CTLESC is no longer in the input */
|
||||
}
|
||||
/* I don't think this clause ever tests true. */
|
||||
if (skip_ctlnul && saw_escape && i == 1 && input_string[0] == CTLNUL)
|
||||
saw_escape = 0; /* Avoid dequoting bare CTLNUL */
|
||||
|
||||
input_string[i] = '\0';
|
||||
check_read_timeout ();
|
||||
|
||||
@@ -843,7 +881,7 @@ add_char:
|
||||
if (nchars > 0)
|
||||
rl_num_chars_to_read = 0;
|
||||
if (delim != '\n')
|
||||
reset_eol_delim ((char *)NULL);
|
||||
reset_eol_delim (NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -923,7 +961,7 @@ assign_vars:
|
||||
else
|
||||
var = bind_variable ("REPLY", input_string, 0);
|
||||
if (var == 0 || readonly_p (var) || noassign_p (var))
|
||||
retval = EXECUTION_FAILURE;
|
||||
retval = EX_MISCERROR;
|
||||
else
|
||||
VUNSETATTR (var, att_invisible);
|
||||
|
||||
@@ -945,9 +983,9 @@ assign_vars:
|
||||
varname = list->word->word;
|
||||
#if defined (ARRAY_VARS)
|
||||
SET_VFLAGS (list->word->flags, vflags, bindflags);
|
||||
if (legal_identifier (varname) == 0 && valid_array_reference (varname, vflags) == 0)
|
||||
if (valid_identifier (varname) == 0 && valid_array_reference (varname, vflags) == 0)
|
||||
#else
|
||||
if (legal_identifier (varname) == 0)
|
||||
if (valid_identifier (varname) == 0)
|
||||
#endif
|
||||
{
|
||||
sh_invalidid (varname);
|
||||
@@ -984,7 +1022,7 @@ assign_vars:
|
||||
if (var == 0)
|
||||
{
|
||||
free (orig_input_string);
|
||||
return (EXECUTION_FAILURE);
|
||||
return (EX_MISCERROR);
|
||||
}
|
||||
|
||||
stupidly_hack_special_variables (varname);
|
||||
@@ -994,9 +1032,9 @@ assign_vars:
|
||||
/* Now assign the rest of the line to the last variable argument. */
|
||||
#if defined (ARRAY_VARS)
|
||||
SET_VFLAGS (list->word->flags, vflags, bindflags);
|
||||
if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
|
||||
if (valid_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
|
||||
#else
|
||||
if (legal_identifier (list->word->word) == 0)
|
||||
if (valid_identifier (list->word->word) == 0)
|
||||
#endif
|
||||
{
|
||||
sh_invalidid (list->word->word);
|
||||
@@ -1044,6 +1082,8 @@ assign_vars:
|
||||
else
|
||||
retval = EXECUTION_FAILURE;
|
||||
|
||||
if (free_ifs)
|
||||
free (ifs_chars);
|
||||
FREE (tofree);
|
||||
free (orig_input_string);
|
||||
|
||||
@@ -1051,9 +1091,7 @@ assign_vars:
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
bind_read_variable (name, value, flags)
|
||||
char *name, *value;
|
||||
int flags;
|
||||
bind_read_variable (char *name, char *value, int flags)
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
@@ -1064,10 +1102,7 @@ bind_read_variable (name, value, flags)
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static int
|
||||
read_mbchar (fd, string, ind, ch, unbuffered)
|
||||
int fd;
|
||||
char *string;
|
||||
int ind, ch, unbuffered;
|
||||
read_mbchar (int fd, char *string, int ind, int ch, int unbuffered)
|
||||
{
|
||||
char mbchar[MB_LEN_MAX + 1];
|
||||
int i, n, r;
|
||||
@@ -1116,22 +1151,27 @@ mbchar_return:
|
||||
|
||||
|
||||
static void
|
||||
ttyrestore (ttp)
|
||||
struct ttsave *ttp;
|
||||
ttyrestore (struct ttsave *ttp)
|
||||
{
|
||||
ttsetattr (ttp->fd, &(ttp->attrs));
|
||||
tty_modified = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
uw_ttyrestore (void *ttp)
|
||||
{
|
||||
ttyrestore (ttp);
|
||||
}
|
||||
|
||||
void
|
||||
read_tty_cleanup ()
|
||||
read_tty_cleanup (void)
|
||||
{
|
||||
if (tty_modified)
|
||||
ttyrestore (&termsave);
|
||||
}
|
||||
|
||||
int
|
||||
read_tty_modified ()
|
||||
read_tty_modified (void)
|
||||
{
|
||||
return (tty_modified);
|
||||
}
|
||||
@@ -1142,15 +1182,20 @@ static rl_hook_func_t *old_startup_hook;
|
||||
static char *deftext;
|
||||
|
||||
static void
|
||||
reset_attempted_completion_function (cp)
|
||||
char *cp;
|
||||
uw_reset_attempted_completion_function (void *cp)
|
||||
{
|
||||
if (rl_attempted_completion_function == 0 && old_attempted_completion_function)
|
||||
rl_attempted_completion_function = old_attempted_completion_function;
|
||||
}
|
||||
|
||||
static void
|
||||
uw_bashline_reset_event_hook (void *ignore)
|
||||
{
|
||||
bashline_reset_event_hook ();
|
||||
}
|
||||
|
||||
static int
|
||||
set_itext ()
|
||||
set_itext (void)
|
||||
{
|
||||
int r1, r2;
|
||||
|
||||
@@ -1168,18 +1213,19 @@ set_itext ()
|
||||
}
|
||||
|
||||
static char *
|
||||
edit_line (p, itext)
|
||||
char *p;
|
||||
char *itext;
|
||||
edit_line (char *p, char *itext, unsigned char delim, int keep_completion_func)
|
||||
{
|
||||
char *ret;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
if (bash_readline_initialized == 0)
|
||||
initialize_readline ();
|
||||
|
||||
old_attempted_completion_function = rl_attempted_completion_function;
|
||||
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
|
||||
/* If we don't indicate that we want to keep the attempted completion
|
||||
function, reset it so we use the default readline word completion. */
|
||||
if (keep_completion_func == 0)
|
||||
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
|
||||
bashline_set_event_hook ();
|
||||
if (itext)
|
||||
{
|
||||
@@ -1190,7 +1236,8 @@ edit_line (p, itext)
|
||||
|
||||
ret = readline (p);
|
||||
|
||||
rl_attempted_completion_function = old_attempted_completion_function;
|
||||
if (keep_completion_func == 0)
|
||||
rl_attempted_completion_function = old_attempted_completion_function;
|
||||
old_attempted_completion_function = (rl_completion_func_t *)NULL;
|
||||
bashline_reset_event_hook ();
|
||||
|
||||
@@ -1212,10 +1259,7 @@ edit_line (p, itext)
|
||||
}
|
||||
|
||||
static void
|
||||
set_readline_timeout (t, sec, usec)
|
||||
sh_timer *t;
|
||||
time_t sec;
|
||||
long usec;
|
||||
set_readline_timeout (sh_timer *t, time_t sec, long usec)
|
||||
{
|
||||
t->tmout.tv_sec = sec;
|
||||
t->tmout.tv_usec = usec;
|
||||
@@ -1230,8 +1274,7 @@ static rl_command_func_t *old_newline_func;
|
||||
static unsigned char delim_char;
|
||||
|
||||
static void
|
||||
set_eol_delim (c)
|
||||
int c;
|
||||
set_eol_delim (int c)
|
||||
{
|
||||
Keymap cmap;
|
||||
|
||||
@@ -1257,8 +1300,7 @@ set_eol_delim (c)
|
||||
}
|
||||
|
||||
static void
|
||||
reset_eol_delim (cp)
|
||||
char *cp;
|
||||
reset_eol_delim (void *ignore)
|
||||
{
|
||||
Keymap cmap;
|
||||
|
||||
|
||||
@@ -19,6 +19,16 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$BUILTIN !
|
||||
$DOCNAME bang
|
||||
$SHORT_DOC ! PIPELINE
|
||||
Execute PIPELINE, which can be a simple command, and negate PIPELINE's
|
||||
return status.
|
||||
|
||||
Exit Status:
|
||||
The logical negation of PIPELINE's return status.
|
||||
$END
|
||||
|
||||
$BUILTIN for
|
||||
$SHORT_DOC for NAME [in WORDS ... ] ; do COMMANDS; done
|
||||
Execute commands for each member in a list.
|
||||
|
||||
+8
-3
@@ -1,7 +1,7 @@
|
||||
This file is return.def, from which is created return.c.
|
||||
It implements the builtin "return" in Bash.
|
||||
|
||||
Copyright (C) 1987-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -54,12 +54,17 @@ $END
|
||||
specified as an argument. if no argument is given, then the last
|
||||
exit status is used. */
|
||||
int
|
||||
return_builtin (list)
|
||||
WORD_LIST *list;
|
||||
return_builtin (WORD_LIST *list)
|
||||
{
|
||||
CHECK_HELPOPT (list);
|
||||
|
||||
return_catch_value = get_exitstat (list);
|
||||
/* return is a special builtin, so non-interactive shells in posix mode
|
||||
exit on an invalid numeric argument. We have to do it this way because
|
||||
the return_catch targets aren't set up to deal with EXITSHELL, so we
|
||||
just jump_to_top_level directly. */
|
||||
if (interactive_shell == 0 && posixly_correct && executing_command_builtin == 0 && return_catch_value > EX_SHERRBASE)
|
||||
return (return_catch_value);
|
||||
|
||||
if (return_catch_flag)
|
||||
sh_longjmp (return_catch, 1);
|
||||
|
||||
+96
-77
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -141,6 +141,10 @@ Options:
|
||||
- Assign any remaining arguments to the positional parameters.
|
||||
The -x and -v options are turned off.
|
||||
|
||||
If -o is supplied with no option-name, set prints the current shell
|
||||
option settings. If +o is supplied with no option-name, set prints a
|
||||
series of set commands to recreate the current option settings.
|
||||
|
||||
Using + rather than - causes these flags to be turned off. The
|
||||
flags can also be used upon invocation of the shell. The current
|
||||
set of flags may be found in $-. The remaining n ARGs are positional
|
||||
@@ -151,24 +155,24 @@ Exit Status:
|
||||
Returns success unless an invalid option is given.
|
||||
$END
|
||||
|
||||
typedef int setopt_set_func_t PARAMS((int, char *));
|
||||
typedef int setopt_get_func_t PARAMS((char *));
|
||||
typedef int setopt_set_func_t (int, char *);
|
||||
typedef int setopt_get_func_t (char *);
|
||||
|
||||
static int find_minus_o_option PARAMS((char *));
|
||||
static int find_minus_o_option (char *);
|
||||
|
||||
static void print_minus_o_option PARAMS((char *, int, int));
|
||||
static void print_all_shell_variables PARAMS((void));
|
||||
static void print_minus_o_option (char *, int, int);
|
||||
static void print_all_shell_variables (void);
|
||||
|
||||
static int set_ignoreeof PARAMS((int, char *));
|
||||
static int set_posix_mode PARAMS((int, char *));
|
||||
static int set_ignoreeof (int, char *);
|
||||
static int set_posix_mode (int, char *);
|
||||
|
||||
#if defined (READLINE)
|
||||
static int set_edit_mode PARAMS((int, char *));
|
||||
static int get_edit_mode PARAMS((char *));
|
||||
static int set_edit_mode (int, char *);
|
||||
static int get_edit_mode (char *);
|
||||
#endif
|
||||
|
||||
#if defined (HISTORY)
|
||||
static int bash_set_history PARAMS((int, char *));
|
||||
static int bash_set_history (int, char *);
|
||||
#endif
|
||||
|
||||
static const char * const on = "on";
|
||||
@@ -245,8 +249,7 @@ const struct {
|
||||
: (*o_options[i].variable = (onoff == FLAG_ON)))
|
||||
|
||||
static int
|
||||
find_minus_o_option (name)
|
||||
char *name;
|
||||
find_minus_o_option (char *name)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -257,8 +260,7 @@ find_minus_o_option (name)
|
||||
}
|
||||
|
||||
int
|
||||
minus_o_option_value (name)
|
||||
char *name;
|
||||
minus_o_option_value (char *name)
|
||||
{
|
||||
register int i;
|
||||
int *on_or_off;
|
||||
@@ -279,9 +281,7 @@ minus_o_option_value (name)
|
||||
#define MINUS_O_FORMAT "%-15s\t%s\n"
|
||||
|
||||
static void
|
||||
print_minus_o_option (name, value, pflag)
|
||||
char *name;
|
||||
int value, pflag;
|
||||
print_minus_o_option (char *name, int value, int pflag)
|
||||
{
|
||||
if (pflag == 0)
|
||||
printf (MINUS_O_FORMAT, name, value ? on : off);
|
||||
@@ -290,8 +290,7 @@ print_minus_o_option (name, value, pflag)
|
||||
}
|
||||
|
||||
void
|
||||
list_minus_o_opts (mode, reusable)
|
||||
int mode, reusable;
|
||||
list_minus_o_opts (int mode, int reusable)
|
||||
{
|
||||
register int i;
|
||||
int *on_or_off, value;
|
||||
@@ -317,7 +316,7 @@ list_minus_o_opts (mode, reusable)
|
||||
}
|
||||
|
||||
char **
|
||||
get_minus_o_opts ()
|
||||
get_minus_o_opts (void)
|
||||
{
|
||||
char **ret;
|
||||
int i;
|
||||
@@ -330,10 +329,11 @@ get_minus_o_opts ()
|
||||
}
|
||||
|
||||
char *
|
||||
get_current_options ()
|
||||
get_current_options (void)
|
||||
{
|
||||
char *temp;
|
||||
int i, posixopts;
|
||||
int i;
|
||||
size_t posixopts;
|
||||
|
||||
posixopts = num_posix_options (); /* shopts modified by posix mode */
|
||||
/* Make the buffer big enough to hold the set -o options and the shopt
|
||||
@@ -355,8 +355,7 @@ get_current_options ()
|
||||
}
|
||||
|
||||
void
|
||||
set_current_options (bitmap)
|
||||
const char *bitmap;
|
||||
set_current_options (const char *bitmap)
|
||||
{
|
||||
int i, v, cv, *on_or_off;
|
||||
|
||||
@@ -388,9 +387,7 @@ set_current_options (bitmap)
|
||||
}
|
||||
|
||||
static int
|
||||
set_ignoreeof (on_or_off, option_name)
|
||||
int on_or_off;
|
||||
char *option_name;
|
||||
set_ignoreeof (int on_or_off, char *option_name)
|
||||
{
|
||||
ignoreeof = on_or_off == FLAG_ON;
|
||||
unbind_variable_noref ("ignoreeof");
|
||||
@@ -403,9 +400,7 @@ set_ignoreeof (on_or_off, option_name)
|
||||
}
|
||||
|
||||
static int
|
||||
set_posix_mode (on_or_off, option_name)
|
||||
int on_or_off;
|
||||
char *option_name;
|
||||
set_posix_mode (int on_or_off, char *option_name)
|
||||
{
|
||||
/* short-circuit on no-op */
|
||||
if ((on_or_off == FLAG_ON && posixly_correct) ||
|
||||
@@ -424,9 +419,7 @@ set_posix_mode (on_or_off, option_name)
|
||||
#if defined (READLINE)
|
||||
/* Magic. This code `knows' how readline handles rl_editing_mode. */
|
||||
static int
|
||||
set_edit_mode (on_or_off, option_name)
|
||||
int on_or_off;
|
||||
char *option_name;
|
||||
set_edit_mode (int on_or_off, char *option_name)
|
||||
{
|
||||
int isemacs;
|
||||
|
||||
@@ -434,7 +427,7 @@ set_edit_mode (on_or_off, option_name)
|
||||
{
|
||||
rl_variable_bind ("editing-mode", option_name);
|
||||
|
||||
if (interactive)
|
||||
if (interactive && command_execution_string == 0)
|
||||
with_input_from_stdin ();
|
||||
no_line_editing = 0;
|
||||
}
|
||||
@@ -443,7 +436,7 @@ set_edit_mode (on_or_off, option_name)
|
||||
isemacs = rl_editing_mode == 1;
|
||||
if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
|
||||
{
|
||||
if (interactive)
|
||||
if (interactive && command_execution_string == 0)
|
||||
with_input_from_stream (stdin, "stdin");
|
||||
no_line_editing = 1;
|
||||
}
|
||||
@@ -452,8 +445,7 @@ set_edit_mode (on_or_off, option_name)
|
||||
}
|
||||
|
||||
static int
|
||||
get_edit_mode (name)
|
||||
char *name;
|
||||
get_edit_mode (char *name)
|
||||
{
|
||||
return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
|
||||
: no_line_editing == 0 && rl_editing_mode == 0);
|
||||
@@ -462,9 +454,7 @@ get_edit_mode (name)
|
||||
|
||||
#if defined (HISTORY)
|
||||
static int
|
||||
bash_set_history (on_or_off, option_name)
|
||||
int on_or_off;
|
||||
char *option_name;
|
||||
bash_set_history (int on_or_off, char *option_name)
|
||||
{
|
||||
if (on_or_off == FLAG_ON)
|
||||
{
|
||||
@@ -483,9 +473,7 @@ bash_set_history (on_or_off, option_name)
|
||||
#endif
|
||||
|
||||
int
|
||||
set_minus_o_option (on_or_off, option_name)
|
||||
int on_or_off;
|
||||
char *option_name;
|
||||
set_minus_o_option (int on_or_off, char *option_name)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -515,7 +503,7 @@ set_minus_o_option (on_or_off, option_name)
|
||||
}
|
||||
|
||||
static void
|
||||
print_all_shell_variables ()
|
||||
print_all_shell_variables (void)
|
||||
{
|
||||
SHELL_VAR **vars;
|
||||
|
||||
@@ -540,11 +528,12 @@ print_all_shell_variables ()
|
||||
}
|
||||
|
||||
void
|
||||
set_shellopts ()
|
||||
set_shellopts (void)
|
||||
{
|
||||
char *value;
|
||||
char tflag[N_O_OPTIONS];
|
||||
int vsize, i, vptr, *ip, exported;
|
||||
int i, *ip, exported;
|
||||
size_t vsize, vptr;
|
||||
SHELL_VAR *v;
|
||||
|
||||
for (vsize = i = 0; o_options[i].name; i++)
|
||||
@@ -584,17 +573,12 @@ set_shellopts ()
|
||||
|
||||
v = find_variable ("SHELLOPTS");
|
||||
|
||||
/* Turn off the read-only attribute so we can bind the new value, and
|
||||
note whether or not the variable was exported. */
|
||||
if (v)
|
||||
{
|
||||
VUNSETATTR (v, att_readonly);
|
||||
exported = exported_p (v);
|
||||
}
|
||||
else
|
||||
exported = 0;
|
||||
/* Note whether or not the variable was exported so we can adjust after the
|
||||
assignment. */
|
||||
exported = v ? exported_p (v) : 0;
|
||||
|
||||
v = bind_variable ("SHELLOPTS", value, 0);
|
||||
/* ASS_FORCE so we don't have to temporarily turn off readonly */
|
||||
v = bind_variable ("SHELLOPTS", value, ASS_FORCE);
|
||||
|
||||
/* Turn the read-only attribute back on, and turn off the export attribute
|
||||
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
|
||||
@@ -607,8 +591,7 @@ set_shellopts ()
|
||||
}
|
||||
|
||||
void
|
||||
parse_shellopts (value)
|
||||
char *value;
|
||||
parse_shellopts (char *value)
|
||||
{
|
||||
char *vname;
|
||||
int vptr;
|
||||
@@ -622,8 +605,7 @@ parse_shellopts (value)
|
||||
}
|
||||
|
||||
void
|
||||
initialize_shell_options (no_shellopts)
|
||||
int no_shellopts;
|
||||
initialize_shell_options (int no_shellopts)
|
||||
{
|
||||
char *temp;
|
||||
SHELL_VAR *var;
|
||||
@@ -651,11 +633,13 @@ initialize_shell_options (no_shellopts)
|
||||
called from execute_cmd.c:initialize_subshell() when setting up a subshell
|
||||
to run an executable shell script without a leading `#!'. */
|
||||
void
|
||||
reset_shell_options ()
|
||||
reset_shell_options (void)
|
||||
{
|
||||
pipefail_opt = 0;
|
||||
ignoreeof = 0;
|
||||
|
||||
interactive_comments = 1;
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
posixly_correct = 1;
|
||||
#else
|
||||
@@ -671,8 +655,7 @@ reset_shell_options ()
|
||||
then print out the values of the variables instead. If LIST contains
|
||||
non-flags, then set $1 - $9 to the successive words of LIST. */
|
||||
int
|
||||
set_builtin (list)
|
||||
WORD_LIST *list;
|
||||
set_builtin (WORD_LIST *list)
|
||||
{
|
||||
int on_or_off, flag_name, force_assignment, opts_changed, rv, r;
|
||||
register char *arg;
|
||||
@@ -830,15 +813,26 @@ $END
|
||||
|
||||
#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
|
||||
|
||||
#define RESTORE_NAME() \
|
||||
do { \
|
||||
tname = name + strlen (name); \
|
||||
if (tname == t - 1) /* probably a paranoid check */ \
|
||||
{ \
|
||||
tname[0] = '['; \
|
||||
t[strlen (t)] = ']'; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
unset_builtin (list)
|
||||
WORD_LIST *list;
|
||||
unset_builtin (WORD_LIST *list)
|
||||
{
|
||||
int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
|
||||
int global_unset_func, global_unset_var, vflags, base_vflags, valid_id;
|
||||
int posix_utility_error;
|
||||
char *name, *tname;
|
||||
|
||||
unset_function = unset_variable = unset_array = nameref = any_failed = 0;
|
||||
unset_function = unset_variable = unset_array = nameref = 0;
|
||||
posix_utility_error = any_failed = 0;
|
||||
global_unset_func = global_unset_var = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
@@ -873,7 +867,7 @@ unset_builtin (list)
|
||||
nameref = 0;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
base_vflags = assoc_expand_once ? VA_NOEXPAND : 0;
|
||||
base_vflags = array_expand_once ? VA_NOEXPAND : 0;
|
||||
#endif
|
||||
|
||||
while (list)
|
||||
@@ -891,23 +885,26 @@ unset_builtin (list)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
vflags = builtin_arrayref_flags (list->word, base_vflags);
|
||||
#endif
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
unset_array = 0;
|
||||
/* XXX valid array reference second arg was 0 */
|
||||
if (!unset_function && nameref == 0 && tokenize_array_reference (name, vflags, &t))
|
||||
/* XXX tokenize_array_reference modifies NAME if it succeeds */
|
||||
if (unset_function == 0 && nameref == 0 && tokenize_array_reference (name, vflags, &t))
|
||||
unset_array = 1;
|
||||
#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);
|
||||
valid_id = valid_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)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (unset_array)
|
||||
RESTORE_NAME ();
|
||||
#endif
|
||||
unset_variable = unset_array = 0;
|
||||
unset_function = 1;
|
||||
}
|
||||
@@ -918,6 +915,7 @@ unset_builtin (list)
|
||||
if (unset_function == 0 && valid_id == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
posix_utility_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
@@ -930,6 +928,7 @@ unset_builtin (list)
|
||||
if (var && unset_function == 0 && non_unsettable_p (var))
|
||||
{
|
||||
builtin_error (_("%s: cannot unset"), name);
|
||||
posix_utility_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
@@ -941,8 +940,20 @@ unset_builtin (list)
|
||||
find a function after unsuccessfully searching for a variable,
|
||||
note that we're acting on a function now as if -f were
|
||||
supplied. The readonly check below takes care of it. */
|
||||
if (var == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0)
|
||||
if (var == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
/* We modified NAME in the call to tokenize_array_reference, so we
|
||||
need to restore it here. We turned the original `[' and `]' into
|
||||
NULL, to isolate the array name and subscript. This only happens
|
||||
if tokenize_array_reference succeeds with a non-NULL subscript
|
||||
pointer, and UNSET_ARRAY is set to 1 only in this case. */
|
||||
if (unset_array)
|
||||
{
|
||||
RESTORE_NAME();
|
||||
unset_array = 0;
|
||||
}
|
||||
#endif
|
||||
if (var = find_function (name))
|
||||
unset_function = 1;
|
||||
}
|
||||
@@ -952,6 +963,7 @@ unset_builtin (list)
|
||||
{
|
||||
builtin_error (_("%s: cannot unset: readonly %s"),
|
||||
var->name, unset_function ? "function" : "variable");
|
||||
posix_utility_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
@@ -987,6 +999,7 @@ unset_builtin (list)
|
||||
int len;
|
||||
|
||||
tname = savestring (nameref_cell (var));
|
||||
tem = 0;
|
||||
if (var = array_variable_part (tname, 0, &t, &len))
|
||||
{
|
||||
/* change to what unbind_array_element now expects */
|
||||
@@ -1000,16 +1013,22 @@ unset_builtin (list)
|
||||
#endif
|
||||
tem = unbind_variable (nameref_cell (var));
|
||||
}
|
||||
else if (posixly_correct && var && tempvar_p (var))
|
||||
tem = posix_unbind_tempvar (name);
|
||||
else
|
||||
tem = unbind_variable (name);
|
||||
}
|
||||
else if (posixly_correct && unset_function == 0 && nameref == 0 && var && tempvar_p (var))
|
||||
tem = posix_unbind_tempvar (name);
|
||||
else
|
||||
tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
|
||||
|
||||
/* This is what Posix.2 says: ``If neither -f nor -v
|
||||
is specified, the name refers to a variable; if a variable by
|
||||
that name does not exist, a function by that name, if any,
|
||||
shall be unset.'' */
|
||||
that name does not exist, it is unspecified whether a function
|
||||
by that name, if any, shall be unset.'' The unspecified part is a
|
||||
recent addition, so we continue to try to unset a shell function if
|
||||
we don't find a variable named NAME. */
|
||||
if (tem == -1 && nameref == 0 && unset_function == 0 && unset_variable == 0)
|
||||
tem = unbind_func (name);
|
||||
|
||||
@@ -1024,5 +1043,5 @@ unset_builtin (list)
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
|
||||
return (any_failed ? (posix_utility_error ? EX_UTILERROR : EXECUTION_FAILURE) : EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
+54
-46
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -38,16 +38,16 @@ $PRODUCES setattr.c
|
||||
#include "../flags.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "builtext.h"
|
||||
|
||||
extern sh_builtin_func_t *this_shell_builtin;
|
||||
|
||||
#ifdef ARRAY_VARS
|
||||
extern int declare_builtin PARAMS((WORD_LIST *));
|
||||
#endif
|
||||
|
||||
#define READONLY_OR_EXPORT \
|
||||
(this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
|
||||
|
||||
#define SPECIAL_LOCAL(n) \
|
||||
(this_shell_builtin == local_builtin && n[0] == '-' && n[1] == 0)
|
||||
|
||||
$BUILTIN export
|
||||
$FUNCTION export_builtin
|
||||
$SHORT_DOC export [-fn] [name[=value] ...] or export -p
|
||||
@@ -73,8 +73,7 @@ $END
|
||||
exported attribute from variables named in LIST. An argument of
|
||||
-f indicates that the names present in LIST refer to functions. */
|
||||
int
|
||||
export_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
export_builtin (WORD_LIST *list)
|
||||
{
|
||||
return (set_or_show_attributes (list, att_exported, 0));
|
||||
}
|
||||
@@ -104,8 +103,7 @@ $END
|
||||
/* For each variable name in LIST, make that variable readonly. Given an
|
||||
empty LIST, print out all existing readonly variables. */
|
||||
int
|
||||
readonly_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
readonly_builtin (WORD_LIST *list)
|
||||
{
|
||||
return (set_or_show_attributes (list, att_readonly, 0));
|
||||
}
|
||||
@@ -120,12 +118,10 @@ readonly_builtin (list)
|
||||
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
|
||||
remaining names in LIST (doesn't work for readonly). */
|
||||
int
|
||||
set_or_show_attributes (list, attribute, nodefs)
|
||||
register WORD_LIST *list;
|
||||
int attribute, nodefs;
|
||||
set_or_show_attributes (WORD_LIST *list, int attribute, int nodefs)
|
||||
{
|
||||
register SHELL_VAR *var;
|
||||
int assign, undo, any_failed, assign_error, opt;
|
||||
int assign, undo, any_failed, assign_error, util_error, opt, retval;
|
||||
int functions_only, arrays_only, assoc_only;
|
||||
int aflags;
|
||||
char *name;
|
||||
@@ -137,7 +133,9 @@ set_or_show_attributes (list, attribute, nodefs)
|
||||
#endif
|
||||
|
||||
functions_only = arrays_only = assoc_only = 0;
|
||||
undo = any_failed = assign_error = 0;
|
||||
undo = any_failed = assign_error = util_error = 0;
|
||||
retval = EXECUTION_SUCCESS;
|
||||
|
||||
/* Read arguments from the front of the list. */
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, ATTROPTS)) != -1)
|
||||
@@ -215,11 +213,16 @@ set_or_show_attributes (list, attribute, nodefs)
|
||||
}
|
||||
}
|
||||
|
||||
if (legal_identifier (name) == 0)
|
||||
if (valid_identifier (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
if (assign)
|
||||
assign_error++;
|
||||
else if (posixly_correct)
|
||||
{
|
||||
util_error++;
|
||||
break; /* exit immediately on bad identifier */
|
||||
}
|
||||
else
|
||||
any_failed++;
|
||||
list = list->next;
|
||||
@@ -342,16 +345,21 @@ set_or_show_attributes (list, attribute, nodefs)
|
||||
}
|
||||
}
|
||||
|
||||
return (assign_error ? EX_BADASSIGN
|
||||
: ((any_failed == 0) ? EXECUTION_SUCCESS
|
||||
: EXECUTION_FAILURE));
|
||||
/* various failure modes */
|
||||
if (assign_error)
|
||||
retval = EX_BADASSIGN;
|
||||
else if (util_error) /* only posix mode sets this */
|
||||
retval = EX_UTILERROR;
|
||||
else if (any_failed)
|
||||
retval = EXECUTION_FAILURE;
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* Show all variable variables (v == 1) or functions (v == 0) with
|
||||
attributes. */
|
||||
int
|
||||
show_all_var_attributes (v, nodefs)
|
||||
int v, nodefs;
|
||||
show_all_var_attributes (int v, int nodefs)
|
||||
{
|
||||
SHELL_VAR **variable_list, *var;
|
||||
int any_failed;
|
||||
@@ -378,8 +386,7 @@ show_all_var_attributes (v, nodefs)
|
||||
/* Show all local variable variables with their attributes. This shows unset
|
||||
local variables (all_local_variables called with 0 argument). */
|
||||
int
|
||||
show_local_var_attributes (v, nodefs)
|
||||
int v, nodefs;
|
||||
show_local_var_attributes (int v, int nodefs)
|
||||
{
|
||||
SHELL_VAR **variable_list, *var;
|
||||
int any_failed;
|
||||
@@ -403,11 +410,9 @@ show_local_var_attributes (v, nodefs)
|
||||
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Fill in FLAGS with attribute characters */
|
||||
int
|
||||
var_attribute_string (var, pattr, flags)
|
||||
SHELL_VAR *var;
|
||||
int pattr;
|
||||
char *flags; /* filled in with attributes */
|
||||
var_attribute_string (SHELL_VAR *var, int pattr, char *flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -476,9 +481,7 @@ var_attribute_string (var, pattr, flags)
|
||||
or `readonly') instead of `declare', and doesn't print function defs
|
||||
when called by `export' or `readonly'. */
|
||||
int
|
||||
show_var_attributes (var, pattr, nodefs)
|
||||
SHELL_VAR *var;
|
||||
int pattr, nodefs;
|
||||
show_var_attributes (SHELL_VAR *var, int pattr, int nodefs)
|
||||
{
|
||||
char flags[MAX_ATTRIBUTES], *x;
|
||||
int i;
|
||||
@@ -533,9 +536,7 @@ show_var_attributes (var, pattr, nodefs)
|
||||
}
|
||||
|
||||
int
|
||||
show_name_attributes (name, nodefs)
|
||||
char *name;
|
||||
int nodefs;
|
||||
show_name_attributes (char *name, int nodefs)
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
@@ -551,9 +552,7 @@ show_name_attributes (name, nodefs)
|
||||
}
|
||||
|
||||
int
|
||||
show_localname_attributes (name, nodefs)
|
||||
char *name;
|
||||
int nodefs;
|
||||
show_localname_attributes (char *name, int nodefs)
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
@@ -561,7 +560,11 @@ show_localname_attributes (name, nodefs)
|
||||
|
||||
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);
|
||||
/* There is no equivalent `declare -'. */
|
||||
if (STREQ (var->name, "-"))
|
||||
printf ("local -\n");
|
||||
else
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
@@ -569,9 +572,7 @@ show_localname_attributes (name, nodefs)
|
||||
}
|
||||
|
||||
int
|
||||
show_func_attributes (name, nodefs)
|
||||
char *name;
|
||||
int nodefs;
|
||||
show_func_attributes (char *name, int nodefs)
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
@@ -586,10 +587,10 @@ show_func_attributes (name, nodefs)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* This is only called by readonly/export, so we can implement posix-mode
|
||||
semantics for special variables. */
|
||||
void
|
||||
set_var_attribute (name, attribute, undo)
|
||||
char *name;
|
||||
int attribute, undo;
|
||||
set_var_attribute (char *name, int attribute, int undo)
|
||||
{
|
||||
SHELL_VAR *var, *tv, *v, *refvar;
|
||||
char *tvalue;
|
||||
@@ -598,10 +599,8 @@ set_var_attribute (name, attribute, undo)
|
||||
var = find_variable (name);
|
||||
else
|
||||
{
|
||||
/* var=value readonly var */
|
||||
tv = find_tempenv_variable (name);
|
||||
/* XXX -- need to handle case where tv is a temp variable in a
|
||||
function-scope context, since function_env has been merged into
|
||||
the local variables table. */
|
||||
if (tv && tempvar_p (tv))
|
||||
{
|
||||
tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
|
||||
@@ -640,6 +639,9 @@ set_var_attribute (name, attribute, undo)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle case where var is a temp variable in a function-scope
|
||||
context, since function_env has been merged into the local
|
||||
variables table (see below). */
|
||||
var = find_variable_notempenv (name);
|
||||
if (var == 0)
|
||||
{
|
||||
@@ -659,7 +661,13 @@ set_var_attribute (name, attribute, undo)
|
||||
if (var)
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
else if (var->context != 0)
|
||||
/* We don't want to do this for local variables or variables we found
|
||||
in previous temporary environment contexts. */
|
||||
#if 0
|
||||
else if (var->context != 0 && local_p (var) == 0)
|
||||
#else
|
||||
else if (var->context != 0 && local_p (var) == 0 && tempvar_p (var) == 0)
|
||||
#endif
|
||||
VSETATTR (var, att_propagate);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-5
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -54,8 +54,7 @@ int print_shift_error;
|
||||
anything in it, it is a number which says where to start the
|
||||
shifting. Return > 0 if `times' > $#, otherwise 0. */
|
||||
int
|
||||
shift_builtin (list)
|
||||
WORD_LIST *list;
|
||||
shift_builtin (WORD_LIST *list)
|
||||
{
|
||||
intmax_t times;
|
||||
int itimes, nargs;
|
||||
@@ -63,12 +62,15 @@ shift_builtin (list)
|
||||
CHECK_HELPOPT (list);
|
||||
|
||||
if (get_numeric_arg (list, 0, ×) == 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
return (EX_USAGE);
|
||||
|
||||
if (times == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
else if (times < 0)
|
||||
{
|
||||
/* skip over `--' option to get the right error message */
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
sh_erange (list ? list->word->word : NULL, _("shift count"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
@@ -76,7 +78,13 @@ shift_builtin (list)
|
||||
if (times > nargs)
|
||||
{
|
||||
if (print_shift_error)
|
||||
sh_erange (list ? list->word->word : NULL, _("shift count"));
|
||||
{
|
||||
/* skip over `--' option to get the right error message */
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
|
||||
sh_erange (list ? list->word->word : NULL, _("shift count"));
|
||||
}
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else if (times == nargs)
|
||||
|
||||
+69
-111
@@ -1,7 +1,7 @@
|
||||
This file is shopt.def, from which is created shopt.c.
|
||||
It implements the Bash `shopt' builtin.
|
||||
|
||||
Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -109,7 +109,7 @@ extern int force_fignore;
|
||||
extern int dircomplete_spelling, dircomplete_expand;
|
||||
extern int complete_fullquote;
|
||||
|
||||
extern int enable_hostname_completion PARAMS((int));
|
||||
extern int enable_hostname_completion (int);
|
||||
#endif
|
||||
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
@@ -122,7 +122,6 @@ extern int debugging_mode;
|
||||
#endif
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
extern int assoc_expand_once;
|
||||
extern int array_expand_once;
|
||||
int expand_once_flag;
|
||||
#endif
|
||||
@@ -131,33 +130,33 @@ int expand_once_flag;
|
||||
extern int syslog_history;
|
||||
#endif
|
||||
|
||||
static void shopt_error PARAMS((char *));
|
||||
static void shopt_error (char *);
|
||||
|
||||
static int set_shellopts_after_change PARAMS((char *, int));
|
||||
static int set_compatibility_level PARAMS((char *, int));
|
||||
static int set_shellopts_after_change (char *, int);
|
||||
static int set_compatibility_level (char *, int);
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
static int set_restricted_shell PARAMS((char *, int));
|
||||
static int set_restricted_shell (char *, int);
|
||||
#endif
|
||||
|
||||
#if defined (READLINE)
|
||||
static int shopt_enable_hostname_completion PARAMS((char *, int));
|
||||
static int shopt_set_complete_direxpand PARAMS((char *, int));
|
||||
static int shopt_enable_hostname_completion (char *, int);
|
||||
static int shopt_set_complete_direxpand (char *, int);
|
||||
#endif
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static int set_assoc_expand PARAMS((char *, int));
|
||||
static int set_array_expand (char *, int);
|
||||
#endif
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
int extglob_flag = EXTGLOB_DEFAULT;
|
||||
static int shopt_set_extglob PARAMS((char *, int));
|
||||
static int shopt_set_extglob (char *, int);
|
||||
#endif
|
||||
|
||||
int expaliases_flag = 0;
|
||||
static int shopt_set_expaliases PARAMS((char *, int));
|
||||
static int shopt_set_expaliases (char *, int);
|
||||
|
||||
static int shopt_set_debug_mode PARAMS((char *, int));
|
||||
static int shopt_set_debug_mode (char *, int);
|
||||
|
||||
static int shopt_login_shell;
|
||||
static int shopt_compat31;
|
||||
@@ -168,7 +167,7 @@ static int shopt_compat42;
|
||||
static int shopt_compat43;
|
||||
static int shopt_compat44;
|
||||
|
||||
typedef int shopt_set_func_t PARAMS((char *, int));
|
||||
typedef int shopt_set_func_t (char *, int);
|
||||
|
||||
/* If you add a new variable name here, make sure to set the default value
|
||||
appropriately in reset_shopt_options. */
|
||||
@@ -180,7 +179,8 @@ static struct {
|
||||
} shopt_vars[] = {
|
||||
{ "autocd", &autocd, (shopt_set_func_t *)NULL },
|
||||
#if defined (ARRAY_VARS)
|
||||
{ "assoc_expand_once", &expand_once_flag, set_assoc_expand },
|
||||
{ "array_expand_once", &expand_once_flag, set_array_expand },
|
||||
{ "assoc_expand_once", &expand_once_flag, set_array_expand },
|
||||
#endif
|
||||
{ "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
|
||||
{ "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
|
||||
@@ -276,14 +276,14 @@ static struct {
|
||||
static const char * const on = "on";
|
||||
static const char * const off = "off";
|
||||
|
||||
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));
|
||||
static int find_shopt (char *);
|
||||
static int toggle_shopts (int, WORD_LIST *, int);
|
||||
static void print_shopt (char *, int, int);
|
||||
static int list_shopts (WORD_LIST *, int);
|
||||
static int list_some_shopts (int, int);
|
||||
static int list_shopt_o_options (WORD_LIST *, int);
|
||||
static int list_some_o_options (int, int);
|
||||
static int set_shopt_o_options (int, WORD_LIST *, int);
|
||||
|
||||
#define SFLAG 0x01
|
||||
#define UFLAG 0x02
|
||||
@@ -292,8 +292,7 @@ static int set_shopt_o_options PARAMS((int, WORD_LIST *, int));
|
||||
#define PFLAG 0x10
|
||||
|
||||
int
|
||||
shopt_builtin (list)
|
||||
WORD_LIST *list;
|
||||
shopt_builtin (WORD_LIST *list)
|
||||
{
|
||||
int opt, flags, rval;
|
||||
|
||||
@@ -351,7 +350,7 @@ shopt_builtin (list)
|
||||
/* Reset the options managed by `shopt' to the values they would have at
|
||||
shell startup. Variables from shopt_vars. */
|
||||
void
|
||||
reset_shopt_options ()
|
||||
reset_shopt_options (void)
|
||||
{
|
||||
autocd = cdable_vars = cdspelling = 0;
|
||||
check_hashed_filenames = CHECKHASH_DEFAULT;
|
||||
@@ -375,7 +374,7 @@ reset_shopt_options ()
|
||||
source_uses_path = promptvars = 1;
|
||||
varassign_redir_autoclose = 0;
|
||||
singlequote_translations = 0;
|
||||
patsub_replacement = 1;
|
||||
patsub_replacement = PATSUB_REPLACE_DEFAULT;
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
check_jobs_at_exit = 0;
|
||||
@@ -384,9 +383,10 @@ reset_shopt_options ()
|
||||
#if defined (EXTENDED_GLOB)
|
||||
extended_glob = extglob_flag = EXTGLOB_DEFAULT;
|
||||
#endif
|
||||
glob_always_skip_dot_and_dotdot = 1; /* new default as of bash-5.2 */
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
expand_once_flag = assoc_expand_once = 0;
|
||||
expand_once_flag = array_expand_once = 0;
|
||||
#endif
|
||||
|
||||
#if defined (HISTORY)
|
||||
@@ -430,12 +430,15 @@ reset_shopt_options ()
|
||||
xpg_echo = 0;
|
||||
#endif /* DEFAULT_ECHO_TO_XPG */
|
||||
|
||||
#if defined (DEBUGGER)
|
||||
debugging_mode = 0;
|
||||
#endif
|
||||
|
||||
shopt_login_shell = login_shell;
|
||||
}
|
||||
|
||||
static int
|
||||
find_shopt (name)
|
||||
char *name;
|
||||
find_shopt (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -446,17 +449,13 @@ find_shopt (name)
|
||||
}
|
||||
|
||||
static void
|
||||
shopt_error (s)
|
||||
char *s;
|
||||
shopt_error (char *s)
|
||||
{
|
||||
builtin_error (_("%s: invalid shell option name"), s);
|
||||
}
|
||||
|
||||
static int
|
||||
toggle_shopts (mode, list, quiet)
|
||||
int mode;
|
||||
WORD_LIST *list;
|
||||
int quiet;
|
||||
toggle_shopts (int mode, WORD_LIST *list, int quiet)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int ind, rval;
|
||||
@@ -485,9 +484,7 @@ toggle_shopts (mode, list, quiet)
|
||||
}
|
||||
|
||||
static void
|
||||
print_shopt (name, val, flags)
|
||||
char *name;
|
||||
int val, flags;
|
||||
print_shopt (char *name, int val, int flags)
|
||||
{
|
||||
if (flags & PFLAG)
|
||||
printf ("shopt %s %s\n", val ? "-s" : "-u", name);
|
||||
@@ -498,9 +495,7 @@ print_shopt (name, val, flags)
|
||||
/* List the values of all or any of the `shopt' options. Returns 0 if
|
||||
all were listed or all variables queried were on; 1 otherwise. */
|
||||
static int
|
||||
list_shopts (list, flags)
|
||||
WORD_LIST *list;
|
||||
int flags;
|
||||
list_shopts (WORD_LIST *list, int flags)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int i, val, rval;
|
||||
@@ -536,8 +531,7 @@ list_shopts (list, flags)
|
||||
}
|
||||
|
||||
static int
|
||||
list_some_shopts (mode, flags)
|
||||
int mode, flags;
|
||||
list_some_shopts (int mode, int flags)
|
||||
{
|
||||
int val, i;
|
||||
|
||||
@@ -551,9 +545,7 @@ list_some_shopts (mode, flags)
|
||||
}
|
||||
|
||||
static int
|
||||
list_shopt_o_options (list, flags)
|
||||
WORD_LIST *list;
|
||||
int flags;
|
||||
list_shopt_o_options (WORD_LIST *list, int flags)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int val, rval;
|
||||
@@ -588,8 +580,7 @@ list_shopt_o_options (list, flags)
|
||||
}
|
||||
|
||||
static int
|
||||
list_some_o_options (mode, flags)
|
||||
int mode, flags;
|
||||
list_some_o_options (int mode, int flags)
|
||||
{
|
||||
if ((flags & QFLAG) == 0)
|
||||
list_minus_o_opts (mode, (flags & PFLAG));
|
||||
@@ -597,10 +588,7 @@ list_some_o_options (mode, flags)
|
||||
}
|
||||
|
||||
static int
|
||||
set_shopt_o_options (mode, list, quiet)
|
||||
int mode;
|
||||
WORD_LIST *list;
|
||||
int quiet;
|
||||
set_shopt_o_options (int mode, WORD_LIST *list, int quiet)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int rval;
|
||||
@@ -617,18 +605,14 @@ set_shopt_o_options (mode, list, quiet)
|
||||
/* If we set or unset interactive_comments with shopt, make sure the
|
||||
change is reflected in $SHELLOPTS. */
|
||||
static int
|
||||
set_shellopts_after_change (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
set_shellopts_after_change (char *option_name, int mode)
|
||||
{
|
||||
set_shellopts ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
shopt_set_debug_mode (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
shopt_set_debug_mode (char *option_name, int mode)
|
||||
{
|
||||
#if defined (DEBUGGER)
|
||||
error_trace_mode = function_trace_mode = debugging_mode;
|
||||
@@ -640,9 +624,7 @@ shopt_set_debug_mode (option_name, mode)
|
||||
}
|
||||
|
||||
static int
|
||||
shopt_set_expaliases (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
shopt_set_expaliases (char *option_name, int mode)
|
||||
{
|
||||
expand_aliases = expaliases_flag;
|
||||
return 0;
|
||||
@@ -650,9 +632,7 @@ shopt_set_expaliases (option_name, mode)
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
static int
|
||||
shopt_set_extglob (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
shopt_set_extglob (char *option_name, int mode)
|
||||
{
|
||||
extended_glob = extglob_flag;
|
||||
return 0;
|
||||
@@ -661,26 +641,21 @@ shopt_set_extglob (option_name, mode)
|
||||
|
||||
#if defined (READLINE)
|
||||
static int
|
||||
shopt_enable_hostname_completion (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
shopt_enable_hostname_completion (char *option_name, int mode)
|
||||
{
|
||||
return (enable_hostname_completion (mode));
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
set_compatibility_level (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
set_compatibility_level (char *option_name, int mode)
|
||||
{
|
||||
int ind, oldval;
|
||||
char *rhs;
|
||||
|
||||
/* If we're unsetting one of the compatibility options, make sure the
|
||||
current value is in the range of the compatNN space. */
|
||||
if (mode == 0)
|
||||
oldval = shell_compatibility_level;
|
||||
oldval = (mode == 0) ? shell_compatibility_level : 0;
|
||||
|
||||
/* If we're setting something, redo some of the work we did above in
|
||||
toggle_shopt(). Unset everything and reset the appropriate option
|
||||
@@ -725,7 +700,7 @@ set_compatibility_level (option_name, mode)
|
||||
/* Set and unset the various compatibility options from the value of
|
||||
shell_compatibility_level; used by sv_shcompat */
|
||||
void
|
||||
set_compatibility_opts ()
|
||||
set_compatibility_opts (void)
|
||||
{
|
||||
shopt_compat31 = shopt_compat32 = 0;
|
||||
shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
|
||||
@@ -755,9 +730,7 @@ set_compatibility_opts ()
|
||||
|
||||
#if defined (READLINE)
|
||||
static int
|
||||
shopt_set_complete_direxpand (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
shopt_set_complete_direxpand (char *option_name, int mode)
|
||||
{
|
||||
set_directory_hook ();
|
||||
return 0;
|
||||
@@ -768,9 +741,7 @@ shopt_set_complete_direxpand (option_name, mode)
|
||||
/* Don't allow the value of restricted_shell to be modified. */
|
||||
|
||||
static int
|
||||
set_restricted_shell (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
set_restricted_shell (char *option_name, int mode)
|
||||
{
|
||||
static int save_restricted = -1;
|
||||
|
||||
@@ -784,19 +755,18 @@ set_restricted_shell (option_name, mode)
|
||||
|
||||
/* Not static so shell.c can call it to initialize shopt_login_shell */
|
||||
int
|
||||
set_login_shell (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
set_login_shell (char *option_name, int mode)
|
||||
{
|
||||
shopt_login_shell = login_shell != 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
char **
|
||||
get_shopt_options ()
|
||||
get_shopt_options (void)
|
||||
{
|
||||
char **ret;
|
||||
int n, i;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
|
||||
ret = strvec_create (n + 1);
|
||||
@@ -812,9 +782,7 @@ get_shopt_options ()
|
||||
* REUSABLE is 1 if we want to print output in a form that may be reused.
|
||||
*/
|
||||
int
|
||||
shopt_setopt (name, mode)
|
||||
char *name;
|
||||
int mode;
|
||||
shopt_setopt (char *name, int mode)
|
||||
{
|
||||
WORD_LIST *wl;
|
||||
int r;
|
||||
@@ -826,9 +794,7 @@ shopt_setopt (name, mode)
|
||||
}
|
||||
|
||||
int
|
||||
shopt_listopt (name, reusable)
|
||||
char *name;
|
||||
int reusable;
|
||||
shopt_listopt (char *name, int reusable)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -847,11 +813,12 @@ shopt_listopt (name, reusable)
|
||||
}
|
||||
|
||||
void
|
||||
set_bashopts ()
|
||||
set_bashopts (void)
|
||||
{
|
||||
char *value;
|
||||
char tflag[N_SHOPT_OPTIONS];
|
||||
int vsize, i, vptr, *ip, exported;
|
||||
int i, exported;
|
||||
size_t vsize, vptr;
|
||||
SHELL_VAR *v;
|
||||
|
||||
for (vsize = i = 0; shopt_vars[i].name; i++)
|
||||
@@ -882,17 +849,12 @@ set_bashopts ()
|
||||
|
||||
v = find_variable ("BASHOPTS");
|
||||
|
||||
/* Turn off the read-only attribute so we can bind the new value, and
|
||||
note whether or not the variable was exported. */
|
||||
if (v)
|
||||
{
|
||||
VUNSETATTR (v, att_readonly);
|
||||
exported = exported_p (v);
|
||||
}
|
||||
else
|
||||
exported = 0;
|
||||
/* Note whether or not the variable was exported so we can adjust after the
|
||||
assignment. */
|
||||
exported = v ? exported_p (v) : 0;
|
||||
|
||||
v = bind_variable ("BASHOPTS", value, 0);
|
||||
/* ASS_FORCE so we don't have to temporarily turn off readonly */
|
||||
v = bind_variable ("BASHOPTS", value, ASS_FORCE);
|
||||
|
||||
/* Turn the read-only attribute back on, and turn off the export attribute
|
||||
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
|
||||
@@ -905,8 +867,7 @@ set_bashopts ()
|
||||
}
|
||||
|
||||
void
|
||||
parse_bashopts (value)
|
||||
char *value;
|
||||
parse_bashopts (char *value)
|
||||
{
|
||||
char *vname;
|
||||
int vptr, ind;
|
||||
@@ -926,8 +887,7 @@ parse_bashopts (value)
|
||||
}
|
||||
|
||||
void
|
||||
initialize_bashopts (no_bashopts)
|
||||
int no_bashopts;
|
||||
initialize_bashopts (int no_bashopts)
|
||||
{
|
||||
char *temp;
|
||||
SHELL_VAR *var;
|
||||
@@ -953,14 +913,12 @@ initialize_bashopts (no_bashopts)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static int
|
||||
set_assoc_expand (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
set_array_expand (char *option_name, int mode)
|
||||
{
|
||||
#if 0 /* leave this disabled */
|
||||
if (shell_compatibility_level <= 51)
|
||||
#endif
|
||||
assoc_expand_once = expand_once_flag;
|
||||
array_expand_once = expand_once_flag;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
+6
-7
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 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 PARAMS((void));
|
||||
static void uw_maybe_pop_dollar_vars (void *);
|
||||
|
||||
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
|
||||
int source_uses_path = 1;
|
||||
@@ -96,7 +96,7 @@ int source_searches_cwd = 1;
|
||||
not executing a shell function, we leave the new values alone and free
|
||||
the saved values. */
|
||||
static void
|
||||
maybe_pop_dollar_vars ()
|
||||
uw_maybe_pop_dollar_vars (void *ignore)
|
||||
{
|
||||
if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
|
||||
dispose_saved_dollar_vars ();
|
||||
@@ -113,8 +113,7 @@ maybe_pop_dollar_vars ()
|
||||
take place in there. So, I open the file, place it into a large string,
|
||||
close the file, and then execute the string. */
|
||||
int
|
||||
source_builtin (list)
|
||||
WORD_LIST *list;
|
||||
source_builtin (WORD_LIST *list)
|
||||
{
|
||||
int result;
|
||||
char *filename, *debug_trap, *x;
|
||||
@@ -171,7 +170,7 @@ source_builtin (list)
|
||||
if (list->next)
|
||||
{
|
||||
push_dollar_vars ();
|
||||
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
|
||||
add_unwind_protect (uw_maybe_pop_dollar_vars, NULL);
|
||||
if (debugging_mode || shell_compatibility_level <= 44)
|
||||
init_bash_argv (); /* Initialize BASH_ARGV and BASH_ARGC */
|
||||
remember_args (list->next, 1);
|
||||
@@ -188,7 +187,7 @@ source_builtin (list)
|
||||
{
|
||||
debug_trap = savestring (debug_trap);
|
||||
add_unwind_protect (xfree, debug_trap);
|
||||
add_unwind_protect (maybe_set_debug_trap, debug_trap);
|
||||
add_unwind_protect (uw_maybe_set_debug_trap, debug_trap);
|
||||
restore_default_signal (DEBUG_TRAP);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ $END
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
static sighandler suspend_continue PARAMS((int));
|
||||
static sighandler suspend_continue (int);
|
||||
|
||||
static SigHandler *old_cont;
|
||||
#if 0
|
||||
@@ -65,8 +65,7 @@ static SigHandler *old_stop;
|
||||
|
||||
/* Continue handler. */
|
||||
static sighandler
|
||||
suspend_continue (sig)
|
||||
int sig;
|
||||
suspend_continue (int sig)
|
||||
{
|
||||
set_signal_handler (SIGCONT, old_cont);
|
||||
#if 0
|
||||
@@ -78,8 +77,7 @@ suspend_continue (sig)
|
||||
/* Suspending the shell. If -f is the arg, then do the suspend
|
||||
no matter what. Otherwise, complain if a login shell. */
|
||||
int
|
||||
suspend_builtin (list)
|
||||
WORD_LIST *list;
|
||||
suspend_builtin (WORD_LIST *list)
|
||||
{
|
||||
int opt, force;
|
||||
|
||||
@@ -98,7 +96,7 @@ suspend_builtin (list)
|
||||
}
|
||||
|
||||
list = loptend;
|
||||
no_args (list);
|
||||
no_args (list, 0);
|
||||
|
||||
if (force == 0)
|
||||
{
|
||||
|
||||
+2
-3
@@ -1,7 +1,7 @@
|
||||
This file is test.def, from which is created test.c.
|
||||
It implements the builtin "test" in Bash.
|
||||
|
||||
Copyright (C) 1987-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2015,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -131,8 +131,7 @@ $END
|
||||
|
||||
/* TEST/[ builtin. */
|
||||
int
|
||||
test_builtin (list)
|
||||
WORD_LIST *list;
|
||||
test_builtin (WORD_LIST *list)
|
||||
{
|
||||
char **argv;
|
||||
int argc, result;
|
||||
|
||||
+6
-4
@@ -1,7 +1,7 @@
|
||||
This file is times.def, from which is created times.c.
|
||||
It implements the builtin "times" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2009,2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -43,7 +43,6 @@ $END
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../bashtypes.h"
|
||||
#include "../shell.h"
|
||||
|
||||
#include <posixtime.h>
|
||||
|
||||
@@ -55,12 +54,15 @@ $END
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#define NEED_CLOCK_FUNCS_DECL
|
||||
#define NEED_TIMEVAL_FUNCS_DECL
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
|
||||
/* Print the totals for system and user time used. */
|
||||
int
|
||||
times_builtin (list)
|
||||
WORD_LIST *list;
|
||||
times_builtin (WORD_LIST *list)
|
||||
{
|
||||
#if defined (HAVE_GETRUSAGE) && defined (HAVE_TIMEVAL) && defined (RUSAGE_SELF)
|
||||
struct rusage self, kids;
|
||||
|
||||
+90
-38
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -22,31 +22,38 @@ $PRODUCES trap.c
|
||||
|
||||
$BUILTIN trap
|
||||
$FUNCTION trap_builtin
|
||||
$SHORT_DOC trap [-lp] [[arg] signal_spec ...]
|
||||
$SHORT_DOC trap [-Plp] [[action] signal_spec ...]
|
||||
Trap signals and other events.
|
||||
|
||||
Defines and activates handlers to be run when the shell receives signals
|
||||
or other conditions.
|
||||
|
||||
ARG is a command to be read and executed when the shell receives the
|
||||
signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC
|
||||
ACTION is a command to be read and executed when the shell receives the
|
||||
signal(s) SIGNAL_SPEC. If ACTION is absent (and a single SIGNAL_SPEC
|
||||
is supplied) or `-', each specified signal is reset to its original
|
||||
value. If ARG is the null string each SIGNAL_SPEC is ignored by the
|
||||
value. If ACTION is the null string each SIGNAL_SPEC is ignored by the
|
||||
shell and by the commands it invokes.
|
||||
|
||||
If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If
|
||||
a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If
|
||||
a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a
|
||||
script run by the . or source builtins finishes executing. A SIGNAL_SPEC
|
||||
of ERR means to execute ARG each time a command's failure would cause the
|
||||
shell to exit when the -e option is enabled.
|
||||
If a SIGNAL_SPEC is EXIT (0) ACTION is executed on exit from the shell.
|
||||
If a SIGNAL_SPEC is DEBUG, ACTION is executed before every simple command
|
||||
and selected other commands. If a SIGNAL_SPEC is RETURN, ACTION is
|
||||
executed each time a shell function or a script run by the . or source
|
||||
builtins finishes executing. A SIGNAL_SPEC of ERR means to execute ACTION
|
||||
each time a command's failure would cause the shell to exit when the -e
|
||||
option is enabled.
|
||||
|
||||
If no arguments are supplied, trap prints the list of commands associated
|
||||
with each signal.
|
||||
with each trapped signal in a form that may be reused as shell input to
|
||||
restore the same signal dispositions.
|
||||
|
||||
Options:
|
||||
-l print a list of signal names and their corresponding numbers
|
||||
-p display the trap commands associated with each SIGNAL_SPEC
|
||||
-p display the trap commands associated with each SIGNAL_SPEC in a
|
||||
form that may be reused as shell input; or for all trapped
|
||||
signals if no arguments are supplied
|
||||
-P display the trap commands associated with each SIGNAL_SPEC. At least
|
||||
one SIGNAL_SPEC must be supplied. -P and -p cannot be used
|
||||
together.
|
||||
|
||||
Each SIGNAL_SPEC is either a signal name in <signal.h> or a signal number.
|
||||
Signal names are case insensitive and the SIG prefix is optional. A
|
||||
@@ -75,13 +82,13 @@ $END
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
static void showtrap PARAMS((int, int));
|
||||
static int display_traps PARAMS((WORD_LIST *, int));
|
||||
static void showtrap (int, int);
|
||||
static int display_traps (WORD_LIST *, int);
|
||||
|
||||
/* The trap command:
|
||||
|
||||
trap <arg> <signal ...>
|
||||
trap <signal ...>
|
||||
trap <action> <sigspec ...>
|
||||
trap <signum ...>
|
||||
trap -l
|
||||
trap -p [sigspec ...]
|
||||
trap [--]
|
||||
@@ -97,17 +104,21 @@ static int display_traps PARAMS((WORD_LIST *, int));
|
||||
#define REVERT 1 /* Revert to this signals original value. */
|
||||
#define IGNORE 2 /* Ignore this signal. */
|
||||
|
||||
int
|
||||
trap_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int list_signal_names, display, result, opt;
|
||||
/* Flags saying how to display the trap list. */
|
||||
#define DISP_TRAPCMD 1
|
||||
#define DISP_ALLSIGS 2
|
||||
#define DISP_ACTIONONLY 4
|
||||
|
||||
list_signal_names = display = 0;
|
||||
int
|
||||
trap_builtin (WORD_LIST *list)
|
||||
{
|
||||
int list_signal_names, result, opt, dflags;
|
||||
|
||||
list_signal_names = dflags = 0;
|
||||
result = EXECUTION_SUCCESS;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "lp")) != -1)
|
||||
while ((opt = internal_getopt (list, "lpP")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
@@ -115,7 +126,10 @@ trap_builtin (list)
|
||||
list_signal_names++;
|
||||
break;
|
||||
case 'p':
|
||||
display++;
|
||||
dflags |= DISP_TRAPCMD;
|
||||
break;
|
||||
case 'P':
|
||||
dflags |= DISP_ACTIONONLY;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
@@ -127,13 +141,26 @@ trap_builtin (list)
|
||||
|
||||
opt = DSIG_NOCASE|DSIG_SIGPREFIX; /* flags for decode_signal */
|
||||
|
||||
if ((dflags & DISP_TRAPCMD) && (dflags & DISP_ACTIONONLY))
|
||||
{
|
||||
builtin_error ("cannot specify both -p and -P");
|
||||
return EX_USAGE;
|
||||
}
|
||||
if ((dflags & DISP_ACTIONONLY) && list == 0)
|
||||
{
|
||||
builtin_error ("-P requires at least one signal name");
|
||||
return EX_USAGE;
|
||||
}
|
||||
|
||||
if (list_signal_names)
|
||||
return (sh_chkwrite (display_signal_list ((WORD_LIST *)NULL, 1)));
|
||||
else if (display || list == 0)
|
||||
else if (dflags || list == 0)
|
||||
{
|
||||
initialize_terminating_signals ();
|
||||
get_all_original_signals ();
|
||||
return (sh_chkwrite (display_traps (list, display && posixly_correct)));
|
||||
if (dflags & DISP_TRAPCMD)
|
||||
dflags |= posixly_correct ? DISP_ALLSIGS : 0;
|
||||
return (sh_chkwrite (display_traps (list, dflags)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -207,7 +234,13 @@ trap_builtin (list)
|
||||
{
|
||||
case SIGINT:
|
||||
/* XXX - should we do this if original disposition
|
||||
was SIG_IGN? */
|
||||
was SIG_IGN? Yes, because setup_async_signals can
|
||||
set the original disposition to SIG_IGN to keep
|
||||
restore_signal from restoring the SIGINT
|
||||
disposition from when the shell was invoked, and
|
||||
we want to allow an asynchronous subshell to
|
||||
use `trap' to restore the default disposition or
|
||||
set a trap command. */
|
||||
if (interactive)
|
||||
set_signal_handler (SIGINT, sigint_sighandler);
|
||||
/* special cases for interactive == 0 */
|
||||
@@ -218,8 +251,13 @@ trap_builtin (list)
|
||||
break;
|
||||
|
||||
case SIGQUIT:
|
||||
/* Always ignore SIGQUIT. */
|
||||
set_signal_handler (SIGQUIT, SIG_IGN);
|
||||
/* Always ignore SIGQUIT, but allow a posix-mode shell
|
||||
that is running asynchronously and has ignored
|
||||
SIGQUIT to reset it to the default. POSIX interp 751. */
|
||||
if (posixly_correct && signal_is_async_ignored (SIGQUIT))
|
||||
set_signal_handler (SIGQUIT, termsig_sighandler);
|
||||
else
|
||||
set_signal_handler (SIGQUIT, SIG_IGN);
|
||||
break;
|
||||
case SIGTERM:
|
||||
#if defined (JOB_CONTROL)
|
||||
@@ -246,8 +284,7 @@ trap_builtin (list)
|
||||
}
|
||||
|
||||
static void
|
||||
showtrap (i, show_default)
|
||||
int i, show_default;
|
||||
showtrap (int i, int show_default)
|
||||
{
|
||||
char *t, *p, *sn;
|
||||
int free_t;
|
||||
@@ -286,13 +323,18 @@ showtrap (i, show_default)
|
||||
FREE (t);
|
||||
}
|
||||
|
||||
static int
|
||||
display_traps (list, show_all)
|
||||
WORD_LIST *list;
|
||||
int show_all;
|
||||
{
|
||||
int result, i;
|
||||
/* Flags saying how to display the trap list. */
|
||||
#define DISP_TRAPCMD 1
|
||||
#define DISP_ALLSIGS 2
|
||||
#define DISP_ACTIONONLY 4
|
||||
|
||||
|
||||
static int
|
||||
display_traps (WORD_LIST *list, int flags)
|
||||
{
|
||||
int result, i, show_all;
|
||||
|
||||
show_all = flags & DISP_ALLSIGS;
|
||||
if (list == 0)
|
||||
{
|
||||
for (i = 0; i < BASH_NSIG; i++)
|
||||
@@ -308,6 +350,16 @@ display_traps (list, show_all)
|
||||
sh_invalidsig (list->word->word);
|
||||
result = EXECUTION_FAILURE;
|
||||
}
|
||||
else if (flags & DISP_ACTIONONLY)
|
||||
{
|
||||
char *t;
|
||||
t = trap_list[i];
|
||||
if (t == (char *)DEFAULT_SIG || signal_is_hard_ignored (i))
|
||||
continue;
|
||||
else if (t == (char *)IGNORE_SIG)
|
||||
t = "";
|
||||
printf ("%s\n", t);
|
||||
}
|
||||
else
|
||||
showtrap (i, show_all);
|
||||
}
|
||||
|
||||
+31
-14
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -64,6 +64,7 @@ $END
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../builtins.h"
|
||||
#include "../parser.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../findcmd.h"
|
||||
@@ -76,8 +77,6 @@ $END
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
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
|
||||
execve, or if it is a builtin command, or an alias. Possible flag
|
||||
@@ -107,8 +106,7 @@ extern int find_reserved_word PARAMS((char *));
|
||||
*/
|
||||
|
||||
int
|
||||
type_builtin (list)
|
||||
WORD_LIST *list;
|
||||
type_builtin (WORD_LIST *list)
|
||||
{
|
||||
int dflags, any_failed, opt;
|
||||
WORD_LIST *this;
|
||||
@@ -163,7 +161,7 @@ type_builtin (list)
|
||||
dflags |= CDESC_TYPE;
|
||||
dflags &= ~(CDESC_PATH_ONLY|CDESC_SHORTDESC);
|
||||
break;
|
||||
case 'P': /* shorthand for type -ap */
|
||||
case 'P': /* force path search only plus hash table lookup */
|
||||
dflags |= (CDESC_PATH_ONLY|CDESC_FORCE_PATH);
|
||||
dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC);
|
||||
break;
|
||||
@@ -210,11 +208,9 @@ type_builtin (list)
|
||||
* return after finding it once.
|
||||
*/
|
||||
int
|
||||
describe_command (command, dflags)
|
||||
char *command;
|
||||
int dflags;
|
||||
describe_command (char *command, int dflags)
|
||||
{
|
||||
int found, i, found_file, f, all;
|
||||
int found, i, found_file, f, all, skipbuiltin;
|
||||
char *full_path, *x, *pathlist;
|
||||
SHELL_VAR *func;
|
||||
#if defined (ALIAS)
|
||||
@@ -242,7 +238,7 @@ describe_command (command, dflags)
|
||||
|
||||
found = 1;
|
||||
|
||||
if (all == 0)
|
||||
if (all == 0) /* type -p returns, any executable file would not have precedence */
|
||||
return (1);
|
||||
}
|
||||
#endif /* ALIAS */
|
||||
@@ -263,6 +259,24 @@ describe_command (command, dflags)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* In posix mode, we find special builtins before shell functions. */
|
||||
/* find_shell_builtin sets current_builtin as a side effect */
|
||||
skipbuiltin = 0;
|
||||
if (posixly_correct && (dflags & CDESC_FORCE_PATH) == 0 && find_shell_builtin (command) != 0 && (current_builtin->flags & SPECIAL_BUILTIN))
|
||||
{
|
||||
if (dflags & CDESC_TYPE)
|
||||
puts ("builtin");
|
||||
else if (dflags & CDESC_SHORTDESC)
|
||||
printf (_("%s is a special shell builtin\n"), command);
|
||||
else if (dflags & CDESC_REUSABLE)
|
||||
printf ("%s\n", command);
|
||||
|
||||
skipbuiltin = found = 1;
|
||||
|
||||
if (all == 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Command is a function? */
|
||||
if (((dflags & (CDESC_FORCE_PATH|CDESC_NOFUNCS)) == 0) && (func = find_function (command)))
|
||||
{
|
||||
@@ -289,13 +303,14 @@ describe_command (command, dflags)
|
||||
}
|
||||
|
||||
/* Command is a builtin? */
|
||||
if (((dflags & CDESC_FORCE_PATH) == 0) && find_shell_builtin (command))
|
||||
/* find_shell_builtin sets current_builtin as a side effect */
|
||||
if (skipbuiltin == 0 && ((dflags & CDESC_FORCE_PATH) == 0) && find_shell_builtin (command))
|
||||
{
|
||||
if (dflags & CDESC_TYPE)
|
||||
puts ("builtin");
|
||||
else if (dflags & CDESC_SHORTDESC)
|
||||
{
|
||||
if (posixly_correct && find_special_builtin (command) != 0)
|
||||
if (posixly_correct && (current_builtin->flags & SPECIAL_BUILTIN))
|
||||
printf (_("%s is a special shell builtin\n"), command);
|
||||
else
|
||||
printf (_("%s is a shell builtin\n"), command);
|
||||
@@ -345,7 +360,8 @@ describe_command (command, dflags)
|
||||
printf ("%s\n", full_path);
|
||||
|
||||
free (full_path);
|
||||
return (1);
|
||||
if (all == 0)
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,6 +387,7 @@ describe_command (command, dflags)
|
||||
probably doesn't exist. Check whether or not the command is an
|
||||
executable file. If it's not, don't report a match. This is
|
||||
the default posix mode behavior */
|
||||
/* This code path isn't executed any more as of 3/2023. */
|
||||
if (STREQ (full_path, command) || posixly_correct)
|
||||
{
|
||||
f = file_status (full_path);
|
||||
|
||||
+44
-55
@@ -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-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -63,9 +63,10 @@ current soft limit, the current hard limit, and no limit, respectively.
|
||||
Otherwise, the current value of the specified resource is printed. If
|
||||
no option is given, then -f is assumed.
|
||||
|
||||
Values are in 1024-byte increments, except for -t, which is in seconds,
|
||||
-p, which is in increments of 512 bytes, and -u, which is an unscaled
|
||||
number of processes.
|
||||
Values are in 1024-byte increments, except for -t, which is in seconds;
|
||||
-p, which is in increments of 512 bytes; -R, which is in microseconds;
|
||||
-b, which is in bytes; and -e, -i, -k, -n, -q, -r, -u, -x, and -P,
|
||||
which accept unscaled values.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or an error occurs.
|
||||
@@ -93,6 +94,7 @@ $END
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "pipesize.h"
|
||||
#include <chartypes.h>
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
@@ -130,7 +132,7 @@ extern int errno;
|
||||
|
||||
#if !defined (RLIMTYPE)
|
||||
# define RLIMTYPE long
|
||||
# define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
|
||||
# define string_to_rlimtype(s, ep) strtol(s, ep, 10)
|
||||
# define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
|
||||
#endif
|
||||
|
||||
@@ -204,22 +206,22 @@ extern int errno;
|
||||
|
||||
#define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
|
||||
|
||||
static int _findlim PARAMS((int));
|
||||
static int _findlim (int);
|
||||
|
||||
static int ulimit_internal PARAMS((int, char *, int, int));
|
||||
static int ulimit_internal (int, char *, int, int);
|
||||
|
||||
static int get_limit PARAMS((int, RLIMTYPE *, RLIMTYPE *));
|
||||
static int set_limit PARAMS((int, RLIMTYPE, int));
|
||||
static int get_limit (int, RLIMTYPE *, RLIMTYPE *);
|
||||
static int set_limit (int, RLIMTYPE, int);
|
||||
|
||||
static void printone PARAMS((int, RLIMTYPE, int));
|
||||
static void print_all_limits PARAMS((int));
|
||||
static void printone (int, RLIMTYPE, int);
|
||||
static void print_all_limits (int);
|
||||
|
||||
static int set_all_limits PARAMS((int, RLIMTYPE));
|
||||
static int set_all_limits (int, RLIMTYPE);
|
||||
|
||||
static int filesize PARAMS((RLIMTYPE *));
|
||||
static int pipesize PARAMS((RLIMTYPE *));
|
||||
static int getmaxuprc PARAMS((RLIMTYPE *));
|
||||
static int getmaxvm PARAMS((RLIMTYPE *, RLIMTYPE *));
|
||||
static int filesize (RLIMTYPE *);
|
||||
static int pipesize (RLIMTYPE *);
|
||||
static int getmaxuprc (RLIMTYPE *);
|
||||
static int getmaxvm (RLIMTYPE *, RLIMTYPE *);
|
||||
|
||||
typedef struct {
|
||||
int option; /* The ulimit option for this limit. */
|
||||
@@ -299,13 +301,11 @@ typedef struct _cmd {
|
||||
|
||||
static ULCMD *cmdlist;
|
||||
static int ncmd;
|
||||
static int cmdlistsz;
|
||||
static size_t cmdlistsz;
|
||||
|
||||
#if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
|
||||
long
|
||||
ulimit (cmd, newlim)
|
||||
int cmd;
|
||||
long newlim;
|
||||
ulimit (int cmd, long newlim)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@@ -313,8 +313,7 @@ ulimit (cmd, newlim)
|
||||
#endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
|
||||
|
||||
static int
|
||||
_findlim (opt)
|
||||
int opt;
|
||||
_findlim (int opt)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -329,8 +328,7 @@ static char optstring[4 + 2 * NCMDS];
|
||||
/* Report or set limits associated with certain per-process resources.
|
||||
See the help documentation in builtins.c for a full description. */
|
||||
int
|
||||
ulimit_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
ulimit_builtin (WORD_LIST *list)
|
||||
{
|
||||
register char *s;
|
||||
int c, limind, mode, opt, all_limits;
|
||||
@@ -441,14 +439,11 @@ ulimit_builtin (list)
|
||||
if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
static int
|
||||
ulimit_internal (cmd, cmdarg, mode, multiple)
|
||||
int cmd;
|
||||
char *cmdarg;
|
||||
int mode, multiple;
|
||||
ulimit_internal (int cmd, char *cmdarg, int mode, int multiple)
|
||||
{
|
||||
int opt, limind, setting;
|
||||
int block_factor;
|
||||
@@ -479,9 +474,16 @@ ulimit_internal (cmd, cmdarg, mode, multiple)
|
||||
real_limit = soft_limit;
|
||||
else if (STREQ (cmdarg, "unlimited"))
|
||||
real_limit = RLIM_INFINITY;
|
||||
else if (all_digits (cmdarg))
|
||||
else if (DIGIT (*cmdarg) && (cmdarg[1] == 0 || DIGIT (cmdarg[1])))
|
||||
{
|
||||
limit = string_to_rlimtype (cmdarg);
|
||||
char *endp;
|
||||
limit = string_to_rlimtype (cmdarg, &endp);
|
||||
if (*endp != '\0')
|
||||
{
|
||||
sh_invalidnum (cmdarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
block_factor = BLOCKSIZE(limits[limind].block_factor);
|
||||
real_limit = limit * block_factor;
|
||||
|
||||
@@ -508,9 +510,7 @@ ulimit_internal (cmd, cmdarg, mode, multiple)
|
||||
}
|
||||
|
||||
static int
|
||||
get_limit (ind, softlim, hardlim)
|
||||
int ind;
|
||||
RLIMTYPE *softlim, *hardlim;
|
||||
get_limit (int ind, RLIMTYPE *softlim, RLIMTYPE *hardlim)
|
||||
{
|
||||
RLIMTYPE value;
|
||||
#if defined (HAVE_RESOURCE)
|
||||
@@ -569,10 +569,7 @@ get_limit (ind, softlim, hardlim)
|
||||
}
|
||||
|
||||
static int
|
||||
set_limit (ind, newlim, mode)
|
||||
int ind;
|
||||
RLIMTYPE newlim;
|
||||
int mode;
|
||||
set_limit (int ind, RLIMTYPE newlim, int mode)
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit limit;
|
||||
@@ -634,8 +631,7 @@ set_limit (ind, newlim, mode)
|
||||
}
|
||||
|
||||
static int
|
||||
getmaxvm (softlim, hardlim)
|
||||
RLIMTYPE *softlim, *hardlim;
|
||||
getmaxvm (RLIMTYPE *softlim, RLIMTYPE *hardlim)
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit datalim, stacklim;
|
||||
@@ -657,8 +653,7 @@ getmaxvm (softlim, hardlim)
|
||||
}
|
||||
|
||||
static int
|
||||
filesize(valuep)
|
||||
RLIMTYPE *valuep;
|
||||
filesize (RLIMTYPE *valuep)
|
||||
{
|
||||
#if !defined (HAVE_RESOURCE)
|
||||
long result;
|
||||
@@ -674,8 +669,7 @@ filesize(valuep)
|
||||
}
|
||||
|
||||
static int
|
||||
pipesize (valuep)
|
||||
RLIMTYPE *valuep;
|
||||
pipesize (RLIMTYPE *valuep)
|
||||
{
|
||||
#if defined (PIPE_BUF)
|
||||
/* This is defined on Posix systems. */
|
||||
@@ -699,8 +693,7 @@ pipesize (valuep)
|
||||
}
|
||||
|
||||
static int
|
||||
getmaxuprc (valuep)
|
||||
RLIMTYPE *valuep;
|
||||
getmaxuprc (RLIMTYPE *valuep)
|
||||
{
|
||||
long maxchild;
|
||||
|
||||
@@ -718,8 +711,7 @@ getmaxuprc (valuep)
|
||||
}
|
||||
|
||||
static void
|
||||
print_all_limits (mode)
|
||||
int mode;
|
||||
print_all_limits (int mode)
|
||||
{
|
||||
register int i;
|
||||
RLIMTYPE softlim, hardlim;
|
||||
@@ -738,10 +730,7 @@ print_all_limits (mode)
|
||||
}
|
||||
|
||||
static void
|
||||
printone (limind, curlim, pdesc)
|
||||
int limind;
|
||||
RLIMTYPE curlim;
|
||||
int pdesc;
|
||||
printone (int limind, RLIMTYPE curlim, int pdesc)
|
||||
{
|
||||
char unitstr[64];
|
||||
int factor;
|
||||
@@ -766,6 +755,7 @@ printone (limind, curlim, pdesc)
|
||||
print_rlimtype ((curlim / factor), 1);
|
||||
}
|
||||
|
||||
#ifdef NOTYET
|
||||
/* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
|
||||
causes all limits to be set as high as possible depending on mode (like
|
||||
csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
|
||||
@@ -780,9 +770,7 @@ printone (limind, curlim, pdesc)
|
||||
*/
|
||||
|
||||
static int
|
||||
set_all_limits (mode, newlim)
|
||||
int mode;
|
||||
RLIMTYPE newlim;
|
||||
set_all_limits (int mode, RLIMTYPE newlim)
|
||||
{
|
||||
register int i;
|
||||
int retval = 0;
|
||||
@@ -805,5 +793,6 @@ set_all_limits (mode, newlim)
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif /* NOTYET */
|
||||
|
||||
#endif /* !_MINIX */
|
||||
|
||||
+104
-50
@@ -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-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -67,14 +67,13 @@ $END
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static void print_symbolic_umask PARAMS((mode_t));
|
||||
static int symbolic_umask PARAMS((WORD_LIST *));
|
||||
static void print_symbolic_umask (mode_t);
|
||||
static int symbolic_umask (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. */
|
||||
int
|
||||
umask_builtin (list)
|
||||
WORD_LIST *list;
|
||||
umask_builtin (WORD_LIST *list)
|
||||
{
|
||||
int print_symbolically, opt, umask_value, pflag;
|
||||
mode_t umask_arg;
|
||||
@@ -146,12 +145,7 @@ umask_builtin (list)
|
||||
/* Print the umask in a symbolic form. In the output, a letter is
|
||||
printed if the corresponding bit is clear in the umask. */
|
||||
static void
|
||||
#if defined (__STDC__)
|
||||
print_symbolic_umask (mode_t um)
|
||||
#else
|
||||
print_symbolic_umask (um)
|
||||
mode_t um;
|
||||
#endif
|
||||
{
|
||||
char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */
|
||||
int i;
|
||||
@@ -186,17 +180,41 @@ print_symbolic_umask (um)
|
||||
printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits);
|
||||
}
|
||||
|
||||
int
|
||||
parse_symbolic_mode (mode, initial_bits)
|
||||
char *mode;
|
||||
int initial_bits;
|
||||
static inline mode_t
|
||||
copyuser (mode_t mask)
|
||||
{
|
||||
int who, op, perm, bits, c;
|
||||
return ((mask & S_IRUSR) ? S_IRUGO : 0) |
|
||||
((mask & S_IWUSR) ? S_IWUGO : 0) |
|
||||
((mask & S_IXUSR) ? S_IXUGO : 0);
|
||||
}
|
||||
|
||||
static inline mode_t
|
||||
copygroup (mode_t mask)
|
||||
{
|
||||
return ((mask & S_IRGRP) ? S_IRUGO : 0) |
|
||||
((mask & S_IWGRP) ? S_IWUGO : 0) |
|
||||
((mask & S_IXGRP) ? S_IXUGO : 0);
|
||||
}
|
||||
|
||||
static inline mode_t
|
||||
copyother (mode_t mask)
|
||||
{
|
||||
return ((mask & S_IROTH) ? S_IRUGO : 0) |
|
||||
((mask & S_IWOTH) ? S_IWUGO : 0) |
|
||||
((mask & S_IXOTH) ? S_IXUGO : 0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_symbolic_mode (char *mode, mode_t initial_bits)
|
||||
{
|
||||
char op, c;
|
||||
mode_t who, perm, bits;
|
||||
char *s;
|
||||
|
||||
for (s = mode, bits = initial_bits;;)
|
||||
{
|
||||
who = op = perm = 0;
|
||||
who = 0;
|
||||
op = 0;
|
||||
|
||||
/* Parse the `who' portion of the symbolic mode clause. */
|
||||
while (member (*s, "agou"))
|
||||
@@ -220,7 +238,13 @@ parse_symbolic_mode (mode, initial_bits)
|
||||
}
|
||||
}
|
||||
|
||||
/* default `who' is `a' */
|
||||
if (who == 0)
|
||||
who = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
|
||||
/* The operation is now sitting in *s. */
|
||||
start_op:
|
||||
perm = 0;
|
||||
op = *s++;
|
||||
switch (op)
|
||||
{
|
||||
@@ -233,57 +257,87 @@ parse_symbolic_mode (mode, initial_bits)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Parse out the `perm' section of the symbolic mode clause. */
|
||||
while (member (*s, "rwx"))
|
||||
/* Parse out the `action' section of the symbolic mode clause. An
|
||||
action can be a set of permissions (rwxXst), a copy specification
|
||||
(ugo), or another op (+-=). */
|
||||
while (member (*s, "rwxXstugo"))
|
||||
{
|
||||
c = *s++;
|
||||
|
||||
switch (c)
|
||||
switch (*s)
|
||||
{
|
||||
/* First the copy specification */
|
||||
case 'u':
|
||||
perm = copyuser (initial_bits);
|
||||
break;
|
||||
case 'g':
|
||||
perm = copygroup (initial_bits);
|
||||
break;
|
||||
case 'o':
|
||||
perm = copyother (initial_bits);
|
||||
break;
|
||||
|
||||
/* Then the permissions. */
|
||||
case 'r':
|
||||
perm |= S_IRUGO;
|
||||
break;
|
||||
case 'w':
|
||||
perm |= S_IWUGO;
|
||||
break;
|
||||
case 'X':
|
||||
/* for chmod, this includes S_ISDIR but that doesn't make sense here */
|
||||
if ((initial_bits & S_IXUGO) == 0)
|
||||
break; /* no-op if original mask doesn't include execute bits */
|
||||
/* FALLTHROUGH */
|
||||
case 'x':
|
||||
perm |= S_IXUGO;
|
||||
break;
|
||||
case 's':
|
||||
#ifdef S_ISUID
|
||||
perm |= S_ISUID | S_ISGID;
|
||||
break;
|
||||
#else
|
||||
goto spec_error;
|
||||
#endif
|
||||
case 't':
|
||||
#ifdef S_ISVTX
|
||||
perm |= S_ISVTX;
|
||||
break;
|
||||
#else
|
||||
goto spec_error;
|
||||
#endif
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
/* Now perform the operation or return an error for a
|
||||
bad permission string. */
|
||||
if (!*s || *s == ',')
|
||||
perm &= who;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
if (who)
|
||||
perm &= who;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case '+':
|
||||
bits |= perm;
|
||||
break;
|
||||
case '-':
|
||||
bits &= ~perm;
|
||||
break;
|
||||
case '=':
|
||||
if (who == 0)
|
||||
who = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
bits &= ~who;
|
||||
bits |= perm;
|
||||
break;
|
||||
|
||||
/* No other values are possible. */
|
||||
}
|
||||
|
||||
if (*s == '\0')
|
||||
break;
|
||||
else
|
||||
s++; /* skip past ',' */
|
||||
case '+':
|
||||
bits |= perm;
|
||||
break;
|
||||
case '-':
|
||||
bits &= ~perm;
|
||||
break;
|
||||
case '=':
|
||||
bits &= ~who;
|
||||
bits |= perm;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Break if the end of the action string, loop if we're going to parse
|
||||
another `who', go back to parsing another op if we have an op spec
|
||||
(+-=). Return an invalid mode character error for everything else. */
|
||||
if (*s == '\0')
|
||||
break;
|
||||
else if (*s == ',')
|
||||
s++; /* skip past ',' */
|
||||
else if (*s == '+' || *s == '-' || *s == '=')
|
||||
goto start_op;
|
||||
else
|
||||
{
|
||||
spec_error:
|
||||
builtin_error (_("`%c': invalid symbolic mode character"), *s);
|
||||
return (-1);
|
||||
}
|
||||
@@ -296,10 +350,10 @@ parse_symbolic_mode (mode, initial_bits)
|
||||
by chmod. If the -S argument is given, then print the umask in a
|
||||
symbolic form. */
|
||||
static int
|
||||
symbolic_umask (list)
|
||||
WORD_LIST *list;
|
||||
symbolic_umask (WORD_LIST *list)
|
||||
{
|
||||
int um, bits;
|
||||
mode_t um;
|
||||
int bits;
|
||||
|
||||
/* Get the initial umask. Don't change it yet. */
|
||||
um = umask (022);
|
||||
|
||||
+65
-14
@@ -1,7 +1,7 @@
|
||||
'This file is wait.def, from which is created wait.c.
|
||||
This file is wait.def, from which is created wait.c.
|
||||
It implements the builtin "wait" in Bash.
|
||||
|
||||
Copyright (C) 1987-2021 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -90,8 +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));
|
||||
static int set_waitlist (WORD_LIST *);
|
||||
static void unset_waitlist (void);
|
||||
static int check_bgpids (WORD_LIST *, struct procstat *);
|
||||
|
||||
/* 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
|
||||
@@ -108,8 +109,7 @@ static void unset_waitlist PARAMS((void));
|
||||
while (0)
|
||||
|
||||
int
|
||||
wait_builtin (list)
|
||||
WORD_LIST *list;
|
||||
wait_builtin (WORD_LIST *list)
|
||||
{
|
||||
int status, code, opt, nflag, vflags, bindflags;
|
||||
volatile int wflags;
|
||||
@@ -154,10 +154,10 @@ wait_builtin (list)
|
||||
int arrayflags;
|
||||
|
||||
SET_VFLAGS (vflags, arrayflags, bindflags);
|
||||
if (legal_identifier (vname) == 0 && valid_array_reference (vname, arrayflags) == 0)
|
||||
if (valid_identifier (vname) == 0 && valid_array_reference (vname, arrayflags) == 0)
|
||||
#else
|
||||
bindflags = 0;
|
||||
if (legal_identifier (vname) == 0)
|
||||
if (valid_identifier (vname) == 0)
|
||||
#endif
|
||||
{
|
||||
sh_invalidid (vname);
|
||||
@@ -211,6 +211,21 @@ wait_builtin (list)
|
||||
#if defined (JOB_CONTROL)
|
||||
if (nflag)
|
||||
{
|
||||
#if 0 /* TAG:bash-5.3 stevenpelley@gmail.com 01/22/2024 */
|
||||
/* First let's see if there are any requested pids that have already
|
||||
been removed from the jobs list and saved on bgpids. */
|
||||
if (list)
|
||||
{
|
||||
status = check_bgpids (list, &pstat);
|
||||
if (status != -1)
|
||||
{
|
||||
if (vname)
|
||||
builtin_bind_var_to_int (vname, pstat.pid, bindflags);
|
||||
WAIT_RETURN (status);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (list)
|
||||
{
|
||||
opt = set_waitlist (list);
|
||||
@@ -255,7 +270,7 @@ wait_builtin (list)
|
||||
w = list->word->word;
|
||||
if (DIGIT (*w))
|
||||
{
|
||||
if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value)
|
||||
if (valid_number (w, &pid_value) && pid_value == (pid_t)pid_value)
|
||||
{
|
||||
pid = (pid_t)pid_value;
|
||||
status = wait_for_single_pid (pid, wflags|JWAIT_PERROR);
|
||||
@@ -331,11 +346,10 @@ wait_builtin (list)
|
||||
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;
|
||||
set_waitlist (WORD_LIST *list)
|
||||
{
|
||||
sigset_t set, oset;
|
||||
int job, r, njob;
|
||||
int job, njob;
|
||||
intmax_t pid;
|
||||
WORD_LIST *l;
|
||||
|
||||
@@ -344,7 +358,7 @@ set_waitlist (list)
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
job = NO_JOB;
|
||||
job = (l && legal_number (l->word->word, &pid) && pid == (pid_t) pid)
|
||||
job = (l && l->word && valid_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))
|
||||
@@ -367,7 +381,7 @@ set_waitlist (list)
|
||||
|
||||
/* Clean up after a call to wait -n jobs */
|
||||
static void
|
||||
unset_waitlist ()
|
||||
unset_waitlist (void)
|
||||
{
|
||||
int i;
|
||||
sigset_t set, oset;
|
||||
@@ -378,4 +392,41 @@ unset_waitlist ()
|
||||
jobs[i]->flags &= ~J_WAITING;
|
||||
UNBLOCK_CHILD (oset);
|
||||
}
|
||||
|
||||
#if 0 /* TAG:bash-5.3 */
|
||||
static int
|
||||
check_bgpids (WORD_LIST *list, struct procstat *pstat)
|
||||
{
|
||||
sigset_t set, oset;
|
||||
pid_t pid;
|
||||
intmax_t ipid;
|
||||
WORD_LIST *l;
|
||||
int r, s;
|
||||
|
||||
r = -1;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
if (l && valid_number (l->word->word, &ipid) && ipid == (pid_t) ipid)
|
||||
pid = ipid;
|
||||
else
|
||||
continue; /* skip job ids for now */
|
||||
|
||||
if ((s = retrieve_proc_status (pid, 0)) != -1)
|
||||
{
|
||||
pstat->pid = pid;
|
||||
pstat->status = r = s;
|
||||
/* If running in posix mode, `wait -n pid' deletes pid from bgpids,
|
||||
just like `wait pid'. */
|
||||
if (posixly_correct)
|
||||
delete_proc_status (pid, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
UNBLOCK_CHILD (oset);
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user