aboutsummaryrefslogtreecommitdiffstats
path: root/builtins
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>2002-07-17 14:10:11 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:55 +0000
commit7117c2d221b2aed4ede8600f6a36b7c1454b4f55 (patch)
treeb792f26ecca68813c51ed5ba2e381790758ef31b /builtins
parentf73dda092b33638d2d5e9c35375f687a607b5403 (diff)
downloadandroid_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.tar.gz
android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.tar.bz2
android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.zip
Imported from ../bash-2.05b.tar.gz.
Diffstat (limited to 'builtins')
-rw-r--r--builtins/Makefile.in63
-rw-r--r--builtins/alias.def6
-rw-r--r--builtins/bashgetopt.c53
-rw-r--r--builtins/bashgetopt.h2
-rw-r--r--builtins/bind.def31
-rw-r--r--builtins/break.def10
-rw-r--r--builtins/builtin.def11
-rw-r--r--builtins/cd.def47
-rw-r--r--builtins/colon.def6
-rw-r--r--builtins/command.def12
-rw-r--r--builtins/common.c358
-rw-r--r--builtins/common.h62
-rw-r--r--builtins/complete.def74
-rw-r--r--builtins/declare.def138
-rw-r--r--builtins/echo.def2
-rw-r--r--builtins/enable.def13
-rw-r--r--builtins/eval.def3
-rw-r--r--builtins/evalfile.c2
-rw-r--r--builtins/evalstring.c21
-rw-r--r--builtins/exec.def12
-rw-r--r--builtins/exit.def5
-rw-r--r--builtins/fc.def27
-rw-r--r--builtins/fg_bg.def11
-rw-r--r--builtins/getopt.c27
-rw-r--r--builtins/getopts.def34
-rw-r--r--builtins/hash.def127
-rw-r--r--builtins/help.def50
-rw-r--r--builtins/history.def36
-rw-r--r--builtins/inlib.def6
-rw-r--r--builtins/jobs.def10
-rw-r--r--builtins/kill.def34
-rw-r--r--builtins/let.def22
-rw-r--r--builtins/mkbuiltins.c128
-rw-r--r--builtins/printf.def346
-rw-r--r--builtins/pushd.def46
-rw-r--r--builtins/read.def143
-rw-r--r--builtins/reserved.def42
-rw-r--r--builtins/return.def4
-rw-r--r--builtins/set.def290
-rw-r--r--builtins/setattr.def80
-rw-r--r--builtins/shift.def8
-rw-r--r--builtins/shopt.def25
-rw-r--r--builtins/source.def20
-rw-r--r--builtins/suspend.def4
-rw-r--r--builtins/test.def4
-rw-r--r--builtins/times.def19
-rw-r--r--builtins/trap.def7
-rw-r--r--builtins/type.def186
-rw-r--r--builtins/ulimit.def49
-rw-r--r--builtins/umask.def9
-rw-r--r--builtins/wait.def18
51 files changed, 1508 insertions, 1235 deletions
diff --git a/builtins/Makefile.in b/builtins/Makefile.in
index 837b53e..53ae75a 100644
--- a/builtins/Makefile.in
+++ b/builtins/Makefile.in
@@ -28,32 +28,52 @@ CP = cp
EXEEXT = @EXEEXT@
+prefix = @prefix@
+
srcdir = @srcdir@
VPATH = .:@srcdir@
topdir = @top_srcdir@
includedir = @includedir@
+datadir = @datadir@
+
+# Support an alternate destination root directory for package building
+DESTDIR =
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
BUILD_DIR = @BUILD_DIR@
PROFILE_FLAGS = @PROFILE_FLAGS@
CFLAGS = @CFLAGS@
-LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
+
+LIBS = @LIBS@
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
+LDFLAGS_FOR_BUILD = $(LDFLAGS)
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
-LIBS = @LIBS@
+#LIBS_FOR_BUILD = @LIBS_FOR_BUILD@
+LIBS_FOR_BUILD = $(LIBS)
BASHINCDIR = ${topdir}/include
RL_INCLUDEDIR = @RL_INCLUDEDIR@
+HELPDIR = @HELPDIR@
+MKDIRS = ${topdir}/support/mkdirs
+
INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir)
-CCFLAGS_FOR_BUILD = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
- $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS)
+BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
+ ${INCLUDES} $(LOCAL_CFLAGS)
-CCFLAGS = $(CCFLAGS_FOR_BUILD) $(CFLAGS)
+CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
+
+CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
-Wcast-align -Wstrict-prototypes -Wconversion \
@@ -61,6 +81,7 @@ GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
MKBUILTINS = mkbuiltins$(EXEEXT)
DIRECTDEFINE = -D $(srcdir)
+HELPDIRDEFINE = @HELPDIRDEFINE@
# xxx this is bad style
RL_LIBSRC = $(topdir)/lib/readline
@@ -124,7 +145,7 @@ builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
@-if test -f builtins.c; then mv -f builtins.c old-builtins.c; fi
@-if test -f builtext.h; then mv -f builtext.h old-builtext.h; fi
./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
- -noproduction $(DIRECTDEFINE) $(DEFSRC)
+ -noproduction $(DIRECTDEFINE) $(HELPDIRDEFINE) $(DEFSRC)
@-if cmp -s old-builtext.h builtext.h 2>/dev/null; then \
mv old-builtext.h builtext.h; \
else \
@@ -136,13 +157,28 @@ builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
$(RM) old-builtins.c; \
fi
+helpdoc: $(MKBUILTINS) $(DEFSRC)
+ ./$(MKBUILTINS) ${HELPDIRDEFINE} -noproduction $(DIRECTDEFINE) $(DEFSRC)
+
+install-help:
+ @-if test -n "${HELPDIR}" && test -d helpfiles ; then \
+ test -d ${HELPDIR} || ${SHELL} ${MKDIRS} $(DESTDIR)$(HELPDIR) ;\
+ ( cd helpfiles ; \
+ for f in *; do \
+ echo installing $$f; \
+ ${INSTALL_DATA} $$f $(DESTDIR)$(HELPDIR); \
+ done; ) ; \
+ fi
+
+install: @HELPINSTALL@
+
mkbuiltins.o: ../config.h
mkbuiltins.o: mkbuiltins.c
$(RM) $@
$(CC_FOR_BUILD) -c $(CCFLAGS_FOR_BUILD) $<
mkbuiltins$(EXEEXT): mkbuiltins.o
- $(CC_FOR_BUILD) $(PROFILE_FLAGS) $(LDFLAGS) -o $(MKBUILTINS) mkbuiltins.o $(LIBS)
+ $(CC_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $(MKBUILTINS) mkbuiltins.o $(LIBS_FOR_BUILD)
# rules for deficient makes, like SunOS
mkbuiltins.o: mkbuiltins.c
@@ -163,13 +199,12 @@ psize.aux: psize.c
documentation: builtins.texi
-$(OFILES): $(MKBUILTINS) ../config.h
-
builtins.texi: $(MKBUILTINS)
./$(MKBUILTINS) -documentonly $(DEFSRC)
clean:
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) mkbuiltins.o libbuiltins.a
+ -test -d helpfiles && $(RM) -r helpfiles
mostlyclean:
$(RM) $(OFILES) libbuiltins.a
@@ -177,6 +212,8 @@ mostlyclean:
distclean maintainer-clean: clean
$(RM) Makefile
+$(OFILES): $(MKBUILTINS) ../config.h
+
alias.o: alias.def
bind.o: bind.def
break.o: break.def
@@ -293,6 +330,7 @@ builtin.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/e
builtin.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
builtin.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
builtin.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
+builtin.o: $(srcdir)/bashgetopt.h
cd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
cd.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
cd.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
@@ -308,7 +346,7 @@ declare.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
declare.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
declare.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
declare.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
-declare.o: $(topdir)/arrayfunc.h
+declare.o: $(topdir)/arrayfunc.h $(srcdir)/bashgetopt.h
echo.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
echo.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -351,7 +389,7 @@ fc.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
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
-fg_bg.o: $(topdir)/bashtypes.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
fg_bg.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -373,7 +411,7 @@ help.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
help.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
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 $(topdir)/conftypes.h
-help.o: ${srcdir}/common.h ../version.h
+help.o: ${srcdir}/common.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
@@ -449,6 +487,7 @@ source.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/fi
source.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
source.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
source.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
+source.o: $(srcdir)/bashgetopt.h
suspend.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
suspend.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
suspend.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
diff --git a/builtins/alias.def b/builtins/alias.def
index e279d4d..f51df94 100644
--- a/builtins/alias.def
+++ b/builtins/alias.def
@@ -1,7 +1,7 @@
This file is alias.def, from which is created alias.c
It implements the builtins "alias" and "unalias" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -120,7 +120,7 @@ alias_builtin (list)
print_alias (t);
else
{
- builtin_error ("`%s' not found", name);
+ sh_notfound (name);
any_failed++;
}
}
@@ -180,7 +180,7 @@ unalias_builtin (list)
remove_alias (alias->name);
else
{
- builtin_error ("`%s': not an alias", list->word->word);
+ sh_notfound (list->word->word);
aflag++;
}
diff --git a/builtins/bashgetopt.c b/builtins/bashgetopt.c
index a0b14c0..4c8d907 100644
--- a/builtins/bashgetopt.c
+++ b/builtins/bashgetopt.c
@@ -1,6 +1,6 @@
/* bashgetopt.c -- `getopt' for use by the builtins. */
-/* Copyright (C) 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -31,12 +31,14 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#include "../shell.h"
#include "common.h"
-#define ERR(S, C) builtin_error("%s%c", (S), (C))
-
+#define ISOPT(s) (((*(s) == '-') || (plus && *(s) == '+')) && (s)[1])
+#define NOTOPT(s) (((*(s) != '-') && (!plus || *(s) != '+')) || (s)[1] == '\0')
+
static int sp;
char *list_optarg;
int list_optopt;
+int list_opttype;
static WORD_LIST *lhead = (WORD_LIST *)NULL;
WORD_LIST *lcurrent = (WORD_LIST *)NULL;
@@ -50,12 +52,11 @@ char *opts;
register int c;
register char *cp;
int plus; /* nonzero means to handle +option */
+ static char errstr[3] = { '-', '\0', '\0' };
- if (*opts == '+') {
- plus = 1;
+ plus = *opts == '+';
+ if (plus)
opts++;
- } else
- plus = 0;
if (list == 0) {
list_optarg = (char *)NULL;
@@ -71,8 +72,7 @@ char *opts;
}
if (sp == 1) {
- if (lcurrent == 0 ||
- (lcurrent->word->word[0] != '-' || lcurrent->word->word[1] == '\0')) {
+ if (lcurrent == 0 || NOTOPT(lcurrent->word->word)) {
lhead = (WORD_LIST *)NULL;
loptend = lcurrent;
return(-1);
@@ -83,12 +83,14 @@ char *opts;
loptend = lcurrent->next;
return(-1);
}
+ errstr[0] = list_opttype = lcurrent->word->word[0];
}
list_optopt = c = lcurrent->word->word[sp];
if (c == ':' || (cp = strchr(opts, c)) == NULL) {
- ERR("illegal option: -", c);
+ errstr[1] = c;
+ sh_invalidopt (errstr);
if (lcurrent->word->word[++sp] == '\0') {
lcurrent = lcurrent->next;
sp = 1;
@@ -108,7 +110,11 @@ char *opts;
lcurrent = lcurrent->next;
/* If the specifier is `;', don't set optarg if the next
argument looks like another option. */
+#if 0
} else if (lcurrent->next && (*cp == ':' || lcurrent->next->word->word[0] != '-')) {
+#else
+ } else if (lcurrent->next && (*cp == ':' || NOTOPT(lcurrent->next->word->word))) {
+#endif
lcurrent = lcurrent->next;
list_optarg = lcurrent->word->word;
lcurrent = lcurrent->next;
@@ -116,14 +122,15 @@ char *opts;
list_optarg = (char *)NULL;
lcurrent = lcurrent->next;
} else { /* lcurrent->next == NULL */
- ERR("option requires an argument: -", c);
+ errstr[1] = c;
+ sh_needarg (errstr);
sp = 1;
list_optarg = (char *)NULL;
return('?');
}
sp = 1;
} else if (*cp == '#') {
- /* optional numeric argument */
+ /* option requires a numeric argument */
if (lcurrent->word->word[sp+1]) {
if (DIGIT(lcurrent->word->word[sp+1])) {
list_optarg = lcurrent->word->word + sp + 1;
@@ -131,12 +138,17 @@ char *opts;
} else
list_optarg = (char *)NULL;
} else {
- if (lcurrent->next && legal_number(lcurrent->next->word->word, (long *)0)) {
+ if (lcurrent->next && legal_number(lcurrent->next->word->word, (intmax_t *)0)) {
lcurrent = lcurrent->next;
list_optarg = lcurrent->word->word;
lcurrent = lcurrent->next;
- } else
+ } else {
+ errstr[1] = c;
+ sh_neednumarg (errstr);
+ sp = 1;
list_optarg = (char *)NULL;
+ return ('?');
+ }
}
} else {
@@ -161,16 +173,3 @@ reset_internal_getopt ()
lhead = lcurrent = loptend = (WORD_LIST *)NULL;
sp = 1;
}
-
-#ifdef INCLUDE_UNUSED
-void
-report_bad_option ()
-{
- char s[3];
-
- s[0] = '-';
- s[1] = list_optopt;
- s[2] = '\0';
- bad_option (s);
-}
-#endif
diff --git a/builtins/bashgetopt.h b/builtins/bashgetopt.h
index 93cf590..835797c 100644
--- a/builtins/bashgetopt.h
+++ b/builtins/bashgetopt.h
@@ -28,12 +28,12 @@
extern char *list_optarg;
extern int list_optopt;
+extern int list_opttype;
extern WORD_LIST *lcurrent;
extern WORD_LIST *loptend;
extern int internal_getopt __P((WORD_LIST *, char *));
extern void reset_internal_getopt __P((void));
-extern void report_bad_option __P((void));
#endif /* !__BASH_GETOPT_H */
diff --git a/builtins/bind.def b/builtins/bind.def
index 40c8c9f..ddf5619 100644
--- a/builtins/bind.def
+++ b/builtins/bind.def
@@ -1,7 +1,7 @@
This file is bind.def, from which is created bind.c.
It implements the builtin "bind" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -26,11 +26,12 @@ $PRODUCES bind.c
$BUILTIN bind
$DEPENDS_ON READLINE
$FUNCTION bind_builtin
-$SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function]
-Bind a key sequence to a Readline function, or to a macro. The
-syntax is equivalent to that found in ~/.inputrc, but must be
-passed as a single argument: bind '"\C-x\C-r": re-read-init-file'.
-Arguments we accept:
+$SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
+Bind a key sequence to a Readline function or a macro, or set
+a Readline variable. The non-option argument syntax is equivalent
+to that found in ~/.inputrc, but must be passed as a single argument:
+bind '"\C-x\C-r": re-read-init-file'.
+bind accepts the following options:
-m keymap Use `keymap' as the keymap for the duration of this
command. Acceptable keymap names are emacs,
emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
@@ -40,8 +41,8 @@ Arguments we accept:
-p List functions and bindings in a form that can be
reused as input.
-r keyseq Remove the binding for KEYSEQ.
- -x keyseq:shell-command Cause SHELL-COMMAND to be executed when KEYSEQ
- is entered.
+ -x keyseq:shell-command Cause SHELL-COMMAND to be executed when
+ KEYSEQ is entered.
-f filename Read key bindings from FILENAME.
-q function-name Query about which keys invoke the named function.
-u function-name Unbind all keys which are bound to the named function.
@@ -49,8 +50,8 @@ Arguments we accept:
-v List variable names and values in a form that can
be reused as input.
-S List key sequences that invoke macros and their values
- -s List key sequences that invoke macros and their values in
- a form that can be reused as input.
+ -s List key sequences that invoke macros and their values
+ in a form that can be reused as input.
$END
#if defined (READLINE)
@@ -227,7 +228,7 @@ bind_builtin (list)
{
if (rl_read_init_file (initfile) != 0)
{
- builtin_error ("cannot read %s: %s", initfile, strerror (errno));
+ builtin_error ("%s: cannot read: %s", initfile, strerror (errno));
BIND_RETURN (EXECUTION_FAILURE);
}
}
@@ -242,7 +243,7 @@ bind_builtin (list)
{
if (rl_set_key (remove_seq, (rl_command_func_t *)NULL, rl_get_keymap ()) != 0)
{
- builtin_error ("cannot unbind %s", remove_seq);
+ builtin_error ("`%s': cannot unbind", remove_seq);
BIND_RETURN (EXECUTION_FAILURE);
}
}
@@ -277,7 +278,7 @@ query_bindings (name)
function = rl_named_function (name);
if (function == 0)
{
- builtin_error ("unknown function name `%s'", name);
+ builtin_error ("`%s': unknown function name", name);
return EXECUTION_FAILURE;
}
@@ -294,7 +295,7 @@ query_bindings (name)
printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n");
if (keyseqs[j])
printf ("...\n");
- free_array (keyseqs);
+ strvec_dispose (keyseqs);
return EXECUTION_SUCCESS;
}
@@ -307,7 +308,7 @@ unbind_command (name)
function = rl_named_function (name);
if (function == 0)
{
- builtin_error ("unknown function name `%s'", name);
+ builtin_error ("`%s': unknown function name", name);
return EXECUTION_FAILURE;
}
diff --git a/builtins/break.def b/builtins/break.def
index e90a32b..1025414 100644
--- a/builtins/break.def
+++ b/builtins/break.def
@@ -1,7 +1,7 @@
This file is break.def, from which is created break.c.
It implements the builtins "break" and "continue" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -59,7 +59,7 @@ int
break_builtin (list)
WORD_LIST *list;
{
- long newbreak;
+ intmax_t newbreak;
if (check_loop_level () == 0)
return (EXECUTION_SUCCESS);
@@ -68,7 +68,7 @@ break_builtin (list)
if (newbreak <= 0)
{
- builtin_error ("loop count must be > 0");
+ sh_erange (list->word->word, "loop count");
breaking = loop_level;
return (EXECUTION_FAILURE);
}
@@ -94,7 +94,7 @@ int
continue_builtin (list)
WORD_LIST *list;
{
- long newcont;
+ intmax_t newcont;
if (check_loop_level () == 0)
return (EXECUTION_SUCCESS);
@@ -103,7 +103,7 @@ continue_builtin (list)
if (newcont <= 0)
{
- builtin_error ("loop count must be > 0");
+ sh_erange (list->word->word, "loop count");
breaking = loop_level;
return (EXECUTION_FAILURE);
}
diff --git a/builtins/builtin.def b/builtins/builtin.def
index f3de5d6..8571f37 100644
--- a/builtins/builtin.def
+++ b/builtins/builtin.def
@@ -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, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -39,6 +39,7 @@ $END
#include "../shell.h"
#include "common.h"
+#include "bashgetopt.h"
extern char *this_command_name;
@@ -51,10 +52,14 @@ builtin_builtin (list)
sh_builtin_func_t *function;
register char *command;
- if (!list)
+ if (no_options (list))
+ return (EX_USAGE);
+ list = loptend; /* skip over possible `--' */
+
+ if (list == 0)
return (EXECUTION_SUCCESS);
- command = (list->word->word);
+ command = list->word->word;
#if defined (DISABLED_BUILTINS)
function = builtin_address (command);
#else /* !DISABLED_BUILTINS */
diff --git a/builtins/cd.def b/builtins/cd.def
index 77e8f82..1c58c7c 100644
--- a/builtins/cd.def
+++ b/builtins/cd.def
@@ -69,7 +69,7 @@ int cdable_vars;
$BUILTIN cd
$FUNCTION cd_builtin
-$SHORT_DOC cd [-PL] [dir]
+$SHORT_DOC cd [-L|-P] [dir]
Change the current directory to DIR. The variable $HOME is the
default DIR. The variable CDPATH defines the search path for
the directory containing DIR. Alternative directory names in CDPATH
@@ -118,6 +118,19 @@ bindpwd (no_symlinks)
return (EXECUTION_SUCCESS);
}
+/* Call get_working_directory to reset the value of
+ the_current_working_directory () */
+static char *
+resetpwd ()
+{
+ char *tdir;
+
+ FREE (the_current_working_directory);
+ the_current_working_directory = (char *)NULL;
+ tdir = get_working_directory ("cd");
+ return (tdir);
+}
+
#define LCD_DOVARS 0x001
#define LCD_DOSPELL 0x002
#define LCD_PRINTPATH 0x004
@@ -137,7 +150,7 @@ cd_builtin (list)
#if defined (RESTRICTED_SHELL)
if (restricted)
{
- builtin_error ("restricted");
+ sh_restricted ((char *)NULL);
return (EXECUTION_FAILURE);
}
#endif /* RESTRICTED_SHELL */
@@ -350,7 +363,7 @@ change_to_directory (newdir, nolinks)
int nolinks;
{
char *t, *tdir;
- int err;
+ int err, canon_failed;
tdir = (char *)NULL;
@@ -370,20 +383,38 @@ change_to_directory (newdir, nolinks)
/* Use the canonicalized version of NEWDIR, or, if canonicalization
failed, use the non-canonical form. */
+ canon_failed = 0;
if (tdir && *tdir)
free (t);
else
{
FREE (tdir);
tdir = t;
+ canon_failed = 1;
+ }
+
+ /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
+ returns NULL (because it checks the path, it will return NULL if the
+ resolved path doesn't exist), fail immediately. */
+ if (posixly_correct && nolinks == 0 && canon_failed)
+ {
+ errno = ENOENT;
+ return (0);
}
/* If the chdir succeeds, update the_current_working_directory. */
if (chdir (nolinks ? newdir : tdir) == 0)
{
- FREE (the_current_working_directory);
- the_current_working_directory = tdir;
-
+ /* If canonicalization failed, but the chdir succeeded, reset the
+ shell's idea of the_current_working_directory. */
+ if (canon_failed)
+ resetpwd ();
+ else
+ {
+ FREE (the_current_working_directory);
+ the_current_working_directory = tdir;
+ }
+
return (1);
}
@@ -400,9 +431,7 @@ change_to_directory (newdir, nolinks)
verbatim. If we succeed, reinitialize the_current_working_directory. */
if (chdir (newdir) == 0)
{
- FREE (the_current_working_directory);
- the_current_working_directory = (char *)NULL;
- tdir = get_working_directory ("cd");
+ tdir = resetpwd ();
FREE (tdir);
return (1);
diff --git a/builtins/colon.def b/builtins/colon.def
index e00428d..a7cdc12 100644
--- a/builtins/colon.def
+++ b/builtins/colon.def
@@ -1,7 +1,7 @@
This file is colon.def, from which is created colon.c.
It implements the builtin ":" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,21 +22,19 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
$PRODUCES colon.c
$BUILTIN :
-$DOCNAME colon_builtin
+$DOCNAME colon
$FUNCTION colon_builtin
$SHORT_DOC :
No effect; the command does nothing. A zero exit code is returned.
$END
$BUILTIN true
-$DOCNAME true_builtin
$FUNCTION colon_builtin
$SHORT_DOC true
Return a successful result.
$END
$BUILTIN false
-$DOCNAME false_builtin
$FUNCTION false_builtin
$SHORT_DOC false
Return an unsuccessful result.
diff --git a/builtins/command.def b/builtins/command.def
index 28515be..dcbbec1 100644
--- a/builtins/command.def
+++ b/builtins/command.def
@@ -1,7 +1,7 @@
This file is command.def, from which is created command.c.
It implements the builtin "command" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -78,10 +78,10 @@ command_builtin (list)
use_standard_path = 1;
break;
case 'V':
- verbose = 2;
+ verbose = CDESC_SHORTDESC; /* look in common.h for constants */
break;
case 'v':
- verbose = 4;
+ verbose = CDESC_REUSABLE; /* ditto */
break;
default:
builtin_usage ();
@@ -99,10 +99,10 @@ command_builtin (list)
for (any_found = 0; list; list = list->next)
{
- found = describe_command (list->word->word, verbose, 0);
+ found = describe_command (list->word->word, verbose);
if (found == 0)
- builtin_error ("%s: not found", list->word->word);
+ sh_notfound (list->word->word);
any_found += found;
}
@@ -112,7 +112,7 @@ command_builtin (list)
#if defined (RESTRICTED_SHELL)
if (use_standard_path && restricted)
{
- builtin_error ("restricted: cannot use -p");
+ sh_restricted ("-p");
return (EXECUTION_FAILURE);
}
#endif
diff --git a/builtins/common.c b/builtins/common.c
index 19a76ea..b818600 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -36,9 +36,7 @@
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
-# if defined (PREFER_VARARGS)
-# include <varargs.h>
-# endif
+# include <varargs.h>
#endif
#include "../bashansi.h"
@@ -64,8 +62,7 @@
extern int errno;
#endif /* !errno */
-extern int no_symbolic_links;
-extern int indirection_level, startup_state, subshell_environment;
+extern int indirection_level, subshell_environment;
extern int line_number;
extern int last_command_exit_value;
extern int running_trap;
@@ -86,7 +83,6 @@ sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
/* This is a lot like report_error (), but it is for shell builtins
instead of shell control structures, and it won't ever exit the
shell. */
-#if defined (USE_VARARGS)
void
#if defined (PREFER_STDARG)
builtin_error (const char *format, ...)
@@ -102,32 +98,18 @@ builtin_error (format, va_alist)
name = get_name_for_error ();
fprintf (stderr, "%s: ", name);
+ if (interactive_shell == 0)
+ fprintf (stderr, "line %d: ", executing_line_number ());
+
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
-#if defined (PREFER_STDARG)
- va_start (args, format);
-#else
- va_start (args);
-#endif
+ SH_VA_START (args, format);
vfprintf (stderr, format, args);
va_end (args);
fprintf (stderr, "\n");
}
-#else /* !USE_VARARGS */
-void
-builtin_error (format, arg1, arg2, arg3, arg4, arg5)
- char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
-{
- if (this_command_name && *this_command_name)
- fprintf (stderr, "%s: ", this_command_name);
-
- fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
- fprintf (stderr, "\n");
- fflush (stderr);
-}
-#endif /* !USE_VARARGS */
/* Print a usage summary for the currently-executing builtin command. */
void
@@ -152,15 +134,6 @@ no_args (list)
}
}
-/* Function called when one of the builtin commands detects a bad
- option. */
-void
-bad_option (s)
- char *s;
-{
- builtin_error ("unknown option: %s", s);
-}
-
/* Check that no options were given to the currently-executing builtin,
and return 0 if there were options. */
int
@@ -176,6 +149,119 @@ no_options (list)
return (0);
}
+void
+sh_needarg (s)
+ char *s;
+{
+ builtin_error ("%s: option requires an argument", s);
+}
+
+void
+sh_neednumarg (s)
+ char *s;
+{
+ builtin_error ("%s: numeric argument required", s);
+}
+
+void
+sh_notfound (s)
+ char *s;
+{
+ builtin_error ("%s: not found", s);
+}
+
+/* Function called when one of the builtin commands detects an invalid
+ option. */
+void
+sh_invalidopt (s)
+ char *s;
+{
+ builtin_error ("%s: invalid option", s);
+}
+
+void
+sh_invalidoptname (s)
+ char *s;
+{
+ builtin_error ("%s: invalid option name", s);
+}
+
+void
+sh_invalidid (s)
+ char *s;
+{
+ builtin_error ("`%s': not a valid identifier", s);
+}
+
+void
+sh_invalidnum (s)
+ char *s;
+{
+ builtin_error ("%s: invalid number", s);
+}
+
+void
+sh_invalidsig (s)
+ char *s;
+{
+ builtin_error ("%s: invalid signal specification", s);
+}
+
+void
+sh_badpid (s)
+ char *s;
+{
+ builtin_error ("`%s': not a pid or valid job spec", s);
+}
+
+void
+sh_readonly (s)
+ const char *s;
+{
+ builtin_error ("%s: readonly variable", s);
+}
+
+void
+sh_erange (s, desc)
+ char *s, *desc;
+{
+ if (s)
+ builtin_error ("%s: %s out of range", s, desc ? desc : "argument");
+ else
+ builtin_error ("%s out of range", desc ? desc : "argument");
+}
+
+#if defined (JOB_CONTROL)
+void
+sh_badjob (s)
+ char *s;
+{
+ builtin_error ("%s: no such job", s);
+}
+
+void
+sh_nojobs (s)
+ char *s;
+{
+ if (s)
+ builtin_error ("%s: no job control");
+ else
+ builtin_error ("no job control");
+}
+#endif
+
+#if defined (RESTRICTED_SHELL)
+void
+sh_restricted (s)
+ char *s;
+{
+ if (s)
+ builtin_error ("%s: restricted", s);
+ else
+ builtin_error ("restricted");
+}
+#endif
+
/* **************************************************************** */
/* */
/* Shell positional parameter manipulation */
@@ -192,7 +278,7 @@ make_builtin_argv (list, ip)
{
char **argv;
- argv = word_list_to_argv (list, 0, 1, ip);
+ argv = strvec_from_word_list (list, 0, 1, ip);
argv[0] = this_command_name;
return argv;
}
@@ -235,67 +321,6 @@ remember_args (list, destructive)
set_dollar_vars_changed ();
}
-/* **************************************************************** */
-/* */
-/* Pushing and Popping variable contexts */
-/* */
-/* **************************************************************** */
-
-static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
-static int dollar_arg_stack_slots;
-static int dollar_arg_stack_index;
-
-void
-push_context ()
-{
- push_dollar_vars ();
- variable_context++;
-}
-
-void
-pop_context ()
-{
- pop_dollar_vars ();
- kill_all_local_variables ();
- variable_context--;
-}
-
-/* Save the existing positional parameters on a stack. */
-void
-push_dollar_vars ()
-{
- if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
- {
- dollar_arg_stack = (WORD_LIST **)
- xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
- * sizeof (WORD_LIST **));
- }
- dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
- dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
-}
-
-/* Restore the positional parameters from our stack. */
-void
-pop_dollar_vars ()
-{
- if (!dollar_arg_stack || dollar_arg_stack_index == 0)
- return;
-
- remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
- dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
- dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
-}
-
-void
-dispose_saved_dollar_vars ()
-{
- if (!dollar_arg_stack || dollar_arg_stack_index == 0)
- return;
-
- dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
- dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
-}
-
static int changed_dollar_vars;
/* Have the dollar variables been reset to new values since we last
@@ -315,7 +340,12 @@ set_dollar_vars_unchanged ()
void
set_dollar_vars_changed ()
{
- changed_dollar_vars = 1;
+ if (variable_context)
+ changed_dollar_vars |= ARGS_FUNC;
+ else if (this_shell_builtin == set_builtin)
+ changed_dollar_vars |= ARGS_SETBLTIN;
+ else
+ changed_dollar_vars |= ARGS_INVOC;
}
/* **************************************************************** */
@@ -330,21 +360,24 @@ set_dollar_vars_changed ()
follow. If FATAL is true, call throw_to_top_level, which exits the
shell; if not, call jump_to_top_level (DISCARD), which aborts the
current command. */
-long
+intmax_t
get_numeric_arg (list, fatal)
WORD_LIST *list;
int fatal;
{
- long count = 1;
+ intmax_t count = 1;
+
+ if (list && list->word && ISOPTION (list->word->word, '-'))
+ list = list->next;
if (list)
{
register char *arg;
arg = list->word->word;
- if (!arg || (legal_number (arg, &count) == 0))
+ if (arg == 0 || (legal_number (arg, &count) == 0))
{
- builtin_error ("bad non-numeric arg `%s'", list->word->word);
+ sh_neednumarg (list->word->word);
if (fatal)
throw_to_top_level ();
else
@@ -362,13 +395,19 @@ get_exitstat (list)
WORD_LIST *list;
{
int status;
- long sval;
+ intmax_t sval;
char *arg;
+ if (list && list->word && ISOPTION (list->word->word, '-'))
+ list = list->next;
+
+ if (list == 0)
+ return (last_command_exit_value);
+
arg = list->word->word;
if (arg == 0 || legal_number (arg, &sval) == 0)
{
- builtin_error ("bad non-numeric arg `%s'", list->word->word);
+ sh_neednumarg (list->word->word ? list->word->word : "`'");
return 255;
}
no_args (list->next);
@@ -460,13 +499,65 @@ set_working_directory (name)
/* **************************************************************** */
#if defined (JOB_CONTROL)
+int
+get_job_by_name (name, flags)
+ const char *name;
+ int flags;
+{
+ register int i, wl, cl, match, job;
+ register PROCESS *p;
+
+ job = NO_JOB;
+ wl = strlen (name);
+ for (i = job_slots - 1; i >= 0; i--)
+ {
+ if (jobs[i] == 0 || ((flags & JM_STOPPED) && JOBSTATE(i) != JSTOPPED))
+ continue;
+
+ p = jobs[i]->pipe;
+ do
+ {
+ if (flags & JM_EXACT)
+ {
+ cl = strlen (p->command);
+ match = STREQN (p->command, name, cl);
+ }
+ else if (flags & JM_SUBSTRING)
+ match = strindex (p->command, name) != (char *)0;
+ else
+ match = STREQN (p->command, name, wl);
+
+ if (match == 0)
+ {
+ p = p->next;
+ continue;
+ }
+ else if (flags & JM_FIRSTMATCH)
+ return i; /* return first match */
+ else if (job != NO_JOB)
+ {
+ if (this_shell_builtin)
+ builtin_error ("%s: ambiguous job spec", name);
+ else
+ report_error ("%s: ambiguous job spec", name);
+ return (DUP_JOB);
+ }
+ else
+ job = i;
+ }
+ while (p != jobs[i]->pipe);
+ }
+
+ return (job);
+}
+
/* Return the job spec found in LIST. */
int
get_job_spec (list)
WORD_LIST *list;
{
register char *word;
- int job, substring_search;
+ int job, jflags;
if (list == 0)
return (current_job);
@@ -482,10 +573,14 @@ get_job_spec (list)
if (DIGIT (*word) && all_digits (word))
{
job = atoi (word);
+#if 0
return (job >= job_slots ? NO_JOB : job - 1);
+#else
+ return (job > job_slots ? NO_JOB : job - 1);
+#endif
}
- substring_search = 0;
+ jflags = 0;
switch (*word)
{
case 0:
@@ -497,43 +592,12 @@ get_job_spec (list)
return (previous_job);
case '?': /* Substring search requested. */
- substring_search++;
+ jflags |= JM_SUBSTRING;
word++;
/* FALLTHROUGH */
default:
- {
- register int i, wl;
-
- job = NO_JOB;
- wl = strlen (word);
- for (i = 0; i < job_slots; i++)
- {
- if (jobs[i])
- {
- register PROCESS *p;
- p = jobs[i]->pipe;
- do
- {
- if ((substring_search && strindex (p->command, word)) ||
- (STREQN (p->command, word, wl)))
- {
- if (job != NO_JOB)
- {
- builtin_error ("ambigious job spec: %s", word);
- return (DUP_JOB);
- }
- else
- job = i;
- }
-
- p = p->next;
- }
- while (p != jobs[i]->pipe);
- }
- }
- return (job);
- }
+ return get_job_by_name (word, jflags);
}
}
#endif /* JOB_CONTROL */
@@ -546,7 +610,8 @@ display_signal_list (list, forcecols)
register int i, column;
char *name;
int result;
- long signum;
+ int signum;
+ intmax_t lsignum;
result = EXECUTION_SUCCESS;
if (!list)
@@ -581,20 +646,21 @@ display_signal_list (list, forcecols)
/* List individual signal names or numbers. */
while (list)
{
- if (legal_number (list->word->word, &signum))
+ if (legal_number (list->word->word, &lsignum))
{
/* This is specified by Posix.2 so that exit statuses can be
mapped into signal numbers. */
- if (signum > 128)
- signum -= 128;
- if (signum < 0 || signum >= NSIG)
+ if (lsignum > 128)
+ lsignum -= 128;
+ if (lsignum < 0 || lsignum >= NSIG)
{
- builtin_error ("bad signal number: %s", list->word->word);
+ sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
+ signum = lsignum;
name = signal_name (signum);
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
{
@@ -614,12 +680,12 @@ display_signal_list (list, forcecols)
signum = decode_signal (list->word->word);
if (signum == NO_SIG)
{
- builtin_error ("%s: not a signal specification", list->word->word);
+ sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
- printf ("%ld\n", signum);
+ printf ("%d\n", signum);
}
list = list->next;
}
diff --git a/builtins/common.h b/builtins/common.h
index dbebeda..a971bcd 100644
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -1,6 +1,6 @@
/* common.h -- extern declarations for functions defined in common.c. */
-/* Copyright (C) 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -26,30 +26,63 @@
#define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
/* Flag values for parse_and_execute () */
-#define SEVAL_NONINT 0x01
-#define SEVAL_INTERACT 0x02
-#define SEVAL_NOHIST 0x04
+#define SEVAL_NONINT 0x001
+#define SEVAL_INTERACT 0x002
+#define SEVAL_NOHIST 0x004
+#define SEVAL_NOFREE 0x008
+
+/* Flags for describe_command, shared between type.def and command.def */
+#define CDESC_ALL 0x001 /* type -a */
+#define CDESC_SHORTDESC 0x002 /* command -V */
+#define CDESC_REUSABLE 0x004 /* command -v */
+#define CDESC_TYPE 0x008 /* type -t */
+#define CDESC_PATH_ONLY 0x010 /* type -p */
+#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */
+#define CDESC_NOFUNCS 0x040 /* type -f */
+
+/* Flags for get_job_by_name */
+#define JM_PREFIX 0x01 /* prefix of job name */
+#define JM_SUBSTRING 0x02 /* substring of job name */
+#define JM_EXACT 0x04 /* match job name exactly */
+#define JM_STOPPED 0x08 /* match stopped jobs only */
+#define JM_FIRSTMATCH 0x10 /* return first matching job */
+
+/* Flags for remember_args and value of changed_dollar_vars */
+#define ARGS_NONE 0x0
+#define ARGS_INVOC 0x01
+#define ARGS_FUNC 0x02
+#define ARGS_SETBLTIN 0x04
/* Functions from common.c */
extern void builtin_error __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
extern void builtin_usage __P((void));
extern void no_args __P((WORD_LIST *));
-extern void bad_option __P((char *));
extern int no_options __P((WORD_LIST *));
+/* common error message functions */
+extern void sh_needarg __P((char *));
+extern void sh_neednumarg __P((char *));
+extern void sh_notfound __P((char *));
+extern void sh_invalidopt __P((char *));
+extern void sh_invalidoptname __P((char *));
+extern void sh_invalidid __P((char *));
+extern void sh_invalidnum __P((char *));
+extern void sh_invalidsig __P((char *));
+extern void sh_erange __P((char *, char *));
+extern void sh_badpid __P((char *));
+extern void sh_badjob __P((char *));
+extern void sh_readonly __P((const char *));
+extern void sh_nojobs __P((char *));
+extern void sh_restricted __P((char *));
+
extern char **make_builtin_argv __P((WORD_LIST *, int *));
extern void remember_args __P((WORD_LIST *, int));
-extern void push_context __P((void));
-extern void pop_context __P((void));
-extern void push_dollar_vars __P((void));
-extern void pop_dollar_vars __P((void));
-extern void dispose_saved_dollar_vars __P((void));
extern int dollar_vars_changed __P((void));
extern void set_dollar_vars_unchanged __P((void));
extern void set_dollar_vars_changed __P((void));
-extern long get_numeric_arg __P((WORD_LIST *, int));
+extern intmax_t get_numeric_arg __P((WORD_LIST *, int));
extern int get_exitstat __P((WORD_LIST *));
extern int read_octal __P((char *));
@@ -59,6 +92,7 @@ extern char *get_working_directory __P((char *));
extern void set_working_directory __P((char *));
#if defined (JOB_CONTROL)
+extern int get_job_by_name __P((const char *, int));
extern int get_job_spec __P((WORD_LIST *));
#endif
extern int display_signal_list __P((WORD_LIST *, int));
@@ -96,7 +130,7 @@ extern int shopt_listopt __P((char *, int));
extern int set_login_shell __P((int));
/* Functions from type.def */
-extern int describe_command __P((char *, int, int));
+extern int describe_command __P((char *, int));
/* Functions from setattr.def */
extern int set_or_show_attributes __P((WORD_LIST *, int, int));
@@ -106,8 +140,8 @@ extern void set_var_attribute __P((char *, int, int));
/* Functions from pushd.def */
extern char *get_dirstack_from_string __P((char *));
-extern char *get_dirstack_element __P((long, int));
-extern void set_dirstack_element __P((long, int, char *));
+extern char *get_dirstack_element __P((intmax_t, int));
+extern void set_dirstack_element __P((intmax_t, int, char *));
extern WORD_LIST *get_directory_stack __P((void));
/* Functions from evalstring.c */
diff --git a/builtins/complete.def b/builtins/complete.def
index 732ba03..f391620 100644
--- a/builtins/complete.def
+++ b/builtins/complete.def
@@ -1,7 +1,7 @@
This file is complete.def, from which is created complete.c.
It implements the builtins "complete" and "compgen" in Bash.
-Copyright (C) 1999 Free Software Foundation, Inc.
+Copyright (C) 1999-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -24,7 +24,7 @@ $PRODUCES complete.c
$BUILTIN complete
$DEPENDS_ON PROGRAMMABLE_COMPLETION
$FUNCTION complete_builtin
-$SHORT_DOC complete [-abcdefgjkvu] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]
+$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]
For each NAME, specify how arguments are to be completed.
If the -p option is supplied, or if no options are supplied, existing
completion specifications are printed in a way that allows them to be
@@ -62,11 +62,12 @@ static int build_actions __P((WORD_LIST *, int *, int *, unsigned long *, unsign
static int remove_cmd_completions __P((WORD_LIST *));
-static void print_one_completion __P((char *, COMPSPEC *));
+static int print_one_completion __P((char *, COMPSPEC *));
+static int print_compitem __P((BUCKET_CONTENTS *));
static void print_all_completions __P((void));
static int print_cmd_completions __P((WORD_LIST *));
-static char *Aarg, *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
+static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
static struct _compacts {
char *actname;
@@ -90,6 +91,7 @@ static struct _compacts {
{ "job", CA_JOB, 'j' },
{ "keyword", CA_KEYWORD, 'k' },
{ "running", CA_RUNNING, 0 },
+ { "service", CA_SERVICE, 's' },
{ "setopt", CA_SETOPT, 0 },
{ "shopt", CA_SHOPT, 0 },
{ "signal", CA_SIGNAL, 0 },
@@ -99,6 +101,7 @@ static struct _compacts {
{ (char *)NULL, 0, 0 },
};
+/* This should be a STRING_INT_ALIST */
static struct _compopt {
char *optname;
int optflag;
@@ -106,6 +109,7 @@ static struct _compopt {
{ "default", COPT_DEFAULT },
{ "dirnames", COPT_DIRNAMES },
{ "filenames",COPT_FILENAMES},
+ { "nospace", COPT_NOSPACE },
{ (char *)NULL, 0 },
};
@@ -160,7 +164,7 @@ build_actions (list, pp, rp, actp, optp)
opt_given = 0;
reset_internal_getopt ();
- while ((opt = internal_getopt (list, "abcdefgjko:pruvA:G:W:P:S:X:F:C:")) != -1)
+ while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:")) != -1)
{
opt_given = 1;
switch (opt)
@@ -173,7 +177,7 @@ build_actions (list, pp, rp, actp, optp)
}
else
{
- builtin_error ("illegal option: -r");
+ sh_invalidopt ("-r");
builtin_usage ();
return (EX_USAGE);
}
@@ -186,7 +190,7 @@ build_actions (list, pp, rp, actp, optp)
}
else
{
- builtin_error ("illegal option: -p");
+ sh_invalidopt ("-p");
builtin_usage ();
return (EX_USAGE);
}
@@ -218,6 +222,9 @@ build_actions (list, pp, rp, actp, optp)
case 'k':
acts |= CA_KEYWORD;
break;
+ case 's':
+ acts |= CA_SERVICE;
+ break;
case 'u':
acts |= CA_USER;
break;
@@ -228,7 +235,7 @@ build_actions (list, pp, rp, actp, optp)
ind = find_compopt (list_optarg);
if (ind < 0)
{
- builtin_error ("%s: invalid option name", list_optarg);
+ sh_invalidoptname (list_optarg);
return (EX_USAGE);
}
copts |= compopts[ind].optflag;
@@ -282,7 +289,6 @@ complete_builtin (list)
{
int opt_given, pflag, rflag, rval;
unsigned long acts, copts;
- char *cmd;
COMPSPEC *cs;
if (list == 0)
@@ -293,7 +299,7 @@ complete_builtin (list)
opt_given = pflag = rflag = 0;
acts = copts = (unsigned long)0L;
- Aarg = Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
+ Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
cs = (COMPSPEC *)NULL;
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
@@ -321,7 +327,7 @@ complete_builtin (list)
{
if (list == 0)
{
- clear_progcomps ();
+ progcomp_flush ();
return (EXECUTION_SUCCESS);
}
return (remove_cmd_completions (list));
@@ -335,7 +341,7 @@ complete_builtin (list)
/* If we get here, we need to build a compspec and add it for each
remaining argument. */
- cs = alloc_compspec ();
+ cs = compspec_create ();
cs->actions = acts;
cs->options = copts;
@@ -350,8 +356,7 @@ complete_builtin (list)
for (rval = EXECUTION_SUCCESS ; list; list = list->next)
{
/* Add CS as the compspec for the specified commands. */
- cmd = list->word->word;
- if (add_progcomp (cmd, cs) == 0)
+ if (progcomp_insert (list->word->word, cs) == 0)
rval = EXECUTION_FAILURE;
}
@@ -367,7 +372,7 @@ remove_cmd_completions (list)
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
{
- if (remove_progcomp (l->word->word) == 0)
+ if (progcomp_remove (l->word->word) == 0)
{
builtin_error ("%s: no completion specification", l->word->word);
ret = EXECUTION_FAILURE;
@@ -410,7 +415,7 @@ remove_cmd_completions (list)
printf ("-o %s ", f); \
} while (0)
-static void
+static int
print_one_completion (cmd, cs)
char *cmd;
COMPSPEC *cs;
@@ -426,6 +431,7 @@ print_one_completion (cmd, cs)
PRINTCOMPOPT (COPT_DEFAULT, "default");
PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
PRINTCOMPOPT (COPT_FILENAMES, "filenames");
+ PRINTCOMPOPT (COPT_NOSPACE, "nospace");
acts = cs->actions;
@@ -437,8 +443,9 @@ print_one_completion (cmd, cs)
PRINTOPT (CA_EXPORT, "-e");
PRINTOPT (CA_FILE, "-f");
PRINTOPT (CA_GROUP, "-g");
- PRINTOPT (CA_KEYWORD, "-k");
PRINTOPT (CA_JOB, "-j");
+ PRINTOPT (CA_KEYWORD, "-k");
+ PRINTOPT (CA_SERVICE, "-s");
PRINTOPT (CA_USER, "-u");
PRINTOPT (CA_VARIABLE, "-v");
@@ -470,12 +477,27 @@ print_one_completion (cmd, cs)
PRINTARG (cs->command, "-C");
printf ("%s\n", cmd);
+
+ return (0);
+}
+
+static int
+print_compitem (item)
+ BUCKET_CONTENTS *item;
+{
+ COMPSPEC *cs;
+ char *cmd;
+
+ cmd = item->key;
+ cs = (COMPSPEC *)item->data;
+
+ return (print_one_completion (cmd, cs));
}
static void
print_all_completions ()
{
- print_all_compspecs (print_one_completion);
+ progcomp_walk (print_compitem);
}
static int
@@ -488,7 +510,7 @@ print_cmd_completions (list)
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
{
- cs = find_compspec (l->word->word);
+ cs = progcomp_search (l->word->word);
if (cs)
print_one_completion (l->word->word, cs);
else
@@ -503,7 +525,7 @@ print_cmd_completions (list)
$BUILTIN compgen
$DEPENDS_ON PROGRAMMABLE_COMPLETION
$FUNCTION compgen_builtin
-$SHORT_DOC compgen [-abcdefgjkvu] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [word]
+$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [word]
Display the 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
@@ -524,7 +546,7 @@ compgen_builtin (list)
return (EXECUTION_SUCCESS);
acts = copts = (unsigned long)0L;
- Aarg = Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
+ Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
cs = (COMPSPEC *)NULL;
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
@@ -545,7 +567,7 @@ compgen_builtin (list)
internal_warning ("compgen: -C option may not work as you expect");
/* If we get here, we need to build a compspec and evaluate it. */
- cs = alloc_compspec ();
+ cs = compspec_create ();
cs->actions = acts;
cs->options = copts;
cs->refcount = 1;
@@ -569,7 +591,7 @@ compgen_builtin (list)
matches = rl_completion_matches (word, rl_filename_completion_function);
sl = completions_to_stringlist (matches);
- free_array (matches);
+ strvec_dispose (matches);
}
if (sl)
@@ -577,11 +599,11 @@ compgen_builtin (list)
if (sl->list && sl->list_len)
{
rval = EXECUTION_SUCCESS;
- print_stringlist (sl, (char *)NULL);
+ strlist_print (sl, (char *)NULL);
}
- free_stringlist (sl);
+ strlist_dispose (sl);
}
- free_compspec (cs);
+ compspec_dispose (cs);
return (rval);
}
diff --git a/builtins/declare.def b/builtins/declare.def
index 98f1cb1..75b154f 100644
--- a/builtins/declare.def
+++ b/builtins/declare.def
@@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,7 +23,7 @@ $PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
-$SHORT_DOC declare [-afFrxi] [-p] name[=value] ...
+$SHORT_DOC declare [-afFirtx] [-p] name[=value] ...
Declare variables and/or give them attributes. If no NAMEs are
given, then display the values of variables instead. The -p option
will display the attributes and values of each NAME.
@@ -33,9 +33,10 @@ The flags are:
-a to make NAMEs arrays (if supported)
-f to select from among function names only
-F to display function names without definitions
+ -i to make NAMEs have the `integer' attribute
-r to make NAMEs readonly
+ -t to make NAMEs have the `trace' attribute
-x to make NAMEs export
- -i to make NAMEs have the `integer' attribute set
Variables with the integer attribute have arithmetic evaluation (see
`let') done when the variable is assigned to.
@@ -50,7 +51,7 @@ $END
$BUILTIN typeset
$FUNCTION declare_builtin
-$SHORT_DOC typeset [-afFrxi] [-p] name[=value] ...
+$SHORT_DOC typeset [-afFirtx] [-p] name[=value] ...
Obsolete. See `declare'.
$END
@@ -70,6 +71,7 @@ $END
#include "../shell.h"
#include "common.h"
#include "builtext.h"
+#include "bashgetopt.h"
extern int array_needs_making;
@@ -103,66 +105,70 @@ local_builtin (list)
}
}
+#if defined (ARRAY_VARS)
+# define DECLARE_OPTS "+afiprtxF"
+#else
+# define DECLARE_OPTS "+fiprtxF"
+#endif
+
/* The workhorse function. */
static int
declare_internal (list, local_var)
register WORD_LIST *list;
int local_var;
{
- int flags_on, flags_off, *flags, any_failed, assign_error, pflag, nodefs;
+ int flags_on, flags_off, *flags, any_failed, assign_error, pflag, nodefs, opt;
char *t, *subscript_start;
SHELL_VAR *var;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
- while (list)
+ reset_internal_getopt ();
+ while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
{
- t = list->word->word;
- if (t[0] == '-' && t[1] == '-' && t[2] == '\0')
- {
- list = list->next;
- break;
- }
-
- if (*t != '+' && *t != '-')
- break;
+ flags = list_opttype == '+' ? &flags_off : &flags_on;
- flags = (*t++ == '+') ? &flags_off : &flags_on;
-
- while (*t)
+ switch (opt)
{
- if (*t == 'p' && local_var == 0)
- pflag++, t++;
- else if (*t == 'F')
- {
- nodefs++;
- *flags |= att_function; t++;
- }
- else if (*t == 'f')
- *flags |= att_function, t++;
- else if (*t == 'x')
- *flags |= att_exported, t++, array_needs_making = 1;
- else if (*t == 'r')
- *flags |= att_readonly, t++;
- else if (*t == 'i')
- *flags |= att_integer, t++;
+ case 'a':
#if defined (ARRAY_VARS)
- else if (*t == 'a')
- *flags |= att_array, t++;
+ *flags |= att_array;
#endif
- else
- {
- builtin_error ("unknown option: `-%c'", *t);
- builtin_usage ();
- return (EX_USAGE);
- }
+ break;
+ case 'p':
+ if (local_var == 0)
+ pflag++;
+ break;
+ case 'F':
+ nodefs++;
+ *flags |= att_function;
+ break;
+ case 'f':
+ *flags |= att_function;
+ break;
+ case 'i':
+ *flags |= att_integer;
+ break;
+ case 'r':
+ *flags |= att_readonly;
+ break;
+ case 't':
+ *flags |= att_trace;
+ break;
+ case 'x':
+ *flags |= att_exported;
+ array_needs_making = 1;
+ break;
+ default:
+ builtin_usage ();
+ return (EX_USAGE);
}
-
- list = list->next;
}
+ list = loptend;
+
/* If there are no more arguments left, then we just want to show
some variables. */
- if (list == 0) /* declare -[afFirx] */
+ if (list == 0) /* declare -[afFirtx] */
{
/* Show local variables defined at this context level if this is
the `local' builtin. */
@@ -171,7 +177,7 @@ declare_internal (list, local_var)
register SHELL_VAR **vlist;
register int i;
- vlist = map_over (variable_in_context, shell_variables);
+ vlist = all_local_variables ();
if (vlist)
{
@@ -193,14 +199,14 @@ declare_internal (list, local_var)
return (EXECUTION_SUCCESS);
}
- if (pflag) /* declare -p [-afFirx] name [name...] */
+ if (pflag) /* declare -p [-afFirtx] name [name...] */
{
for (any_failed = 0; list; list = list->next)
{
pflag = show_name_attributes (list->word->word, nodefs);
if (pflag)
{
- builtin_error ("%s: not found", list->word->word);
+ sh_notfound (list->word->word);
any_failed++;
}
}
@@ -244,7 +250,7 @@ declare_internal (list, local_var)
if (legal_identifier (name) == 0)
{
- builtin_error ("`%s': not a valid identifier", name);
+ sh_invalidid (name);
assign_error++;
NEXT_VARIABLE ();
}
@@ -253,7 +259,10 @@ declare_internal (list, local_var)
inside of a function. This means we should make local variables,
not global ones. */
- if (variable_context)
+ /* XXX - this has consequences when we're making a local copy of a
+ variable that was in the temporary environment. Watch out
+ for this. */
+ if (variable_context && ((flags_on & att_function) == 0))
{
#if defined (ARRAY_VARS)
if ((flags_on & att_array) || making_array_special)
@@ -267,6 +276,8 @@ declare_internal (list, local_var)
NEXT_VARIABLE ();
}
}
+ else
+ var = (SHELL_VAR *)NULL;
/* If we are declaring a function, then complain about it in some way.
We don't let people make functions by saying `typeset -f foo=bar'. */
@@ -315,7 +326,9 @@ declare_internal (list, local_var)
}
else /* declare -[airx] name [name...] */
{
- var = find_variable (name);
+ /* Non-null if we just created or fetched a local variable. */
+ if (var == 0)
+ var = find_variable (name);
if (var == 0)
{
@@ -330,7 +343,7 @@ declare_internal (list, local_var)
/* Cannot use declare +r to turn off readonly attribute. */
if (readonly_p (var) && (flags_off & att_readonly))
{
- builtin_error ("%s: readonly variable", name);
+ sh_readonly (name);
any_failed++;
NEXT_VARIABLE ();
}
@@ -340,7 +353,7 @@ declare_internal (list, local_var)
if ((readonly_p (var) || noassign_p (var)) && offset)
{
if (readonly_p (var))
- builtin_error ("%s: readonly variable", name);
+ sh_readonly (name);
assign_error++;
NEXT_VARIABLE ();
}
@@ -394,12 +407,27 @@ declare_internal (list, local_var)
`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. */
+ /* XXX -- should this create a variable in the global scope, or
+ modify the local variable flags? ksh93 has it modify the
+ global scope.
+ Need to handle case like in set_var_attribute where a temporary
+ variable is in the same table as the function local vars. */
if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var))
{
SHELL_VAR *tv;
- tv = bind_variable (var->name, var->value ? var->value : "");
- tv->attributes = var->attributes & ~att_tempvar;
- dispose_variable (var);
+ char *tvalue;
+
+ tv = find_tempenv_variable (var->name);
+ if (tv)
+ {
+ tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring ("");
+ tv = bind_variable (var->name, tvalue);
+ tv->attributes |= var->attributes & ~att_tempvar;
+ if (tv->context > 0)
+ VSETATTR (tv, att_propagate);
+ free (tvalue);
+ }
+ VSETATTR (var, att_propagate);
}
}
diff --git a/builtins/echo.def b/builtins/echo.def
index e1015b3..07e9f24 100644
--- a/builtins/echo.def
+++ b/builtins/echo.def
@@ -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, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
diff --git a/builtins/enable.def b/builtins/enable.def
index 50b4dc7..7496d42 100644
--- a/builtins/enable.def
+++ b/builtins/enable.def
@@ -1,7 +1,7 @@
This file is enable.def, from which is created enable.c.
It implements the builtin "enable" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -146,7 +146,7 @@ enable_builtin (list)
/* Restricted shells cannot load new builtins. */
if (restricted && (flags & (FFLAG|DFLAG)))
{
- builtin_error ("restricted");
+ sh_restricted ((char *)NULL);
return (EXECUTION_FAILURE);
}
#endif
@@ -246,6 +246,13 @@ enable_shell_command (name, disable_p)
if (disable_p)
b->flags &= ~BUILTIN_ENABLED;
+#if defined (RESTRICTED_SHELL)
+ else if (restricted && ((b->flags & BUILTIN_ENABLED) == 0))
+ {
+ sh_restricted ((char *)NULL);
+ return (EXECUTION_FAILURE);
+ }
+#endif
else
b->flags |= BUILTIN_ENABLED;
@@ -453,7 +460,7 @@ dyn_unload_builtin (name)
using it drops to zero. */
if (ref == 1 && local_dlclose (handle) != 0)
{
- builtin_error ("cannot delete %s: %s", name, dlerror ());
+ builtin_error ("%s: cannot delete: %s", name, dlerror ());
return (EXECUTION_FAILURE);
}
diff --git a/builtins/eval.def b/builtins/eval.def
index db48e12..500e8c7 100644
--- a/builtins/eval.def
+++ b/builtins/eval.def
@@ -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, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -46,6 +46,7 @@ eval_builtin (list)
{
if (no_options (list))
return (EX_USAGE);
+ list = loptend; /* skip over possible `--' */
/* Note that parse_and_execute () frees the string it is passed. */
return (list ? parse_and_execute (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS);
diff --git a/builtins/evalfile.c b/builtins/evalfile.c
index f334221..0675753 100644
--- a/builtins/evalfile.c
+++ b/builtins/evalfile.c
@@ -216,7 +216,7 @@ maybe_execute_file (fname, force_noninteractive)
char *filename;
int result, flags;
- filename = bash_tilde_expand (fname);
+ filename = bash_tilde_expand (fname, 0);
flags = FEVAL_ENOENTOK;
if (force_noninteractive)
flags |= FEVAL_NONINT;
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
index b164e74..860a3de 100644
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -83,6 +83,7 @@ parse_and_execute_cleanup ()
(flags & SEVAL_NONINT) -> interactive = 0;
(flags & SEVAL_INTERACT) -> interactive = 1;
(flags & SEVAL_NOHIST) -> call bash_history_disable ()
+ (flags & SEVAL_NOFREE) -> don't free STRING when finished
*/
int
@@ -123,7 +124,7 @@ parse_and_execute (string, from_file, flags)
}
add_unwind_protect (pop_stream, (char *)NULL);
- if (orig_string)
+ if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
@@ -320,23 +321,7 @@ cat_file (r)
return -1;
}
- rval = 0;
- while (1)
- {
- nr = zread (fd, lbuf, sizeof(lbuf));
- if (nr == 0)
- break;
- else if (nr < 0)
- {
- rval = -1;
- break;
- }
- if (zwrite (1, lbuf, nr) < 0)
- {
- rval = -1;
- break;
- }
- }
+ rval = zcatfd (fd, 1, fn);
free (fn);
close (fd);
diff --git a/builtins/exec.def b/builtins/exec.def
index c7137e3..a6881b8 100644
--- a/builtins/exec.def
+++ b/builtins/exec.def
@@ -1,7 +1,7 @@
This file is exec.def, from which is created exec.c.
It implements the builtin "exec" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -127,19 +127,19 @@ exec_builtin (list)
#if defined (RESTRICTED_SHELL)
if (restricted)
{
- builtin_error ("restricted");
+ sh_restricted ((char *)NULL);
return (EXECUTION_FAILURE);
}
#endif /* RESTRICTED_SHELL */
- args = word_list_to_argv (list, 1, 0, (int *)NULL);
+ args = strvec_from_word_list (list, 1, 0, (int *)NULL);
/* A command with a slash anywhere in its name is not looked up in $PATH. */
command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
if (command == 0)
{
- builtin_error ("%s: not found", args[0]);
+ sh_notfound (args[0]);
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
goto failed_exec;
}
@@ -215,10 +215,10 @@ failed_exec:
exit_shell (exit_value);
if (args)
- free_array (args);
+ strvec_dispose (args);
initialize_traps ();
- reinitialize_signals ();
+ initialize_signals (1);
#if defined (JOB_CONTROL)
restart_job_control ();
diff --git a/builtins/exit.def b/builtins/exit.def
index 54b6760..bf1d920 100644
--- a/builtins/exit.def
+++ b/builtins/exit.def
@@ -1,7 +1,7 @@
This file is exit.def, from which is created exit.c.
It implements the builtins "exit", and "logout" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -119,7 +119,8 @@ exit_or_logout (list)
/* Get return value if present. This means that you can type
`logout 5' to a shell, and it returns 5. */
- exit_value = list ? get_exitstat (list) : last_command_exit_value;
+
+ exit_value = get_exitstat (list);
/* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
if (login_shell && sourced_logout++ == 0 && subshell_environment == 0)
diff --git a/builtins/fc.def b/builtins/fc.def
index af99579..c300066 100644
--- a/builtins/fc.def
+++ b/builtins/fc.def
@@ -1,7 +1,7 @@
This file is fc.def, from which is created fc.c.
It implements the builtin "fc" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -239,8 +239,7 @@ fc_builtin (list)
/* If we have a list of substitutions to do, then reverse it
to get the replacements in the proper order. */
- if (rlist && rlist->next)
- rlist = (REPL *)reverse_list ((GENERIC_LIST *) rlist);
+ rlist = REVERSE_LIST (rlist, REPL *);
hlist = history_list ();
@@ -313,10 +312,9 @@ fc_builtin (list)
}
/* We print error messages for line specifications out of range. */
- if ((histbeg < 0) || (histend < 0) ||
- (histbeg > last_hist) || (histend > last_hist))
+ if ((histbeg < 0) || (histend < 0))
{
- builtin_error ("history specification out of range");
+ sh_erange ((char *)NULL, "history specification");
return (EXECUTION_FAILURE);
}
@@ -410,7 +408,7 @@ fc_number (list)
s = list->word->word;
if (*s == '-')
s++;
- return (legal_number (s, (long *)NULL));
+ return (legal_number (s, (intmax_t *)NULL));
}
/* Return an absolute index into HLIST which corresponds to COMMAND. If
@@ -457,19 +455,20 @@ fc_gethnum (command, hlist)
n = atoi (s);
n *= sign;
- /* Anything specified greater than the last history element that we
- deal with is an error. */
- if (n > i + history_base)
- return (-1);
-
/* If the value is negative or zero, then it is an offset from
the current history item. */
if (n < 0)
- return (i + n + 1);
+ {
+ n += i + 1;
+ return (n < 0 ? 0 : n);
+ }
else if (n == 0)
return (i);
else
- return (n - history_base);
+ {
+ n -= history_base;
+ return (i < n ? i : n);
+ }
}
clen = strlen (command);
diff --git a/builtins/fg_bg.def b/builtins/fg_bg.def
index 9d379e8..c16d894 100644
--- a/builtins/fg_bg.def
+++ b/builtins/fg_bg.def
@@ -1,7 +1,7 @@
This file is fg_bg.def, from which is created fg_bg.c.
It implements the builtins "bg" and "fg" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -42,6 +42,7 @@ $END
#include "../shell.h"
#include "../jobs.h"
#include "common.h"
+#include "bashgetopt.h"
#if defined (JOB_CONTROL)
extern char *this_command_name;
@@ -58,12 +59,13 @@ fg_builtin (list)
if (job_control == 0)
{
- builtin_error ("no job control");
+ sh_nojobs ((char *)NULL);
return (EXECUTION_FAILURE);
}
if (no_options (list))
return (EX_USAGE);
+ list = loptend;
/* If the last arg on the line is '&', then start this job in the
background. Else, fg the job. */
@@ -92,12 +94,13 @@ bg_builtin (list)
{
if (job_control == 0)
{
- builtin_error ("no job control");
+ sh_nojobs ((char *)NULL);
return (EXECUTION_FAILURE);
}
if (no_options (list))
return (EX_USAGE);
+ list = loptend;
return (fg_bg (list, 0));
}
@@ -117,7 +120,7 @@ fg_bg (list, foreground)
if (job < 0 || job >= job_slots || jobs[job] == 0)
{
if (job != DUP_JOB)
- builtin_error ("%s: no such job", list ? list->word->word : "current");
+ sh_badjob (list ? list->word->word : "current");
goto failure;
}
diff --git a/builtins/getopt.c b/builtins/getopt.c
index 6ea3401..60c6188 100644
--- a/builtins/getopt.c
+++ b/builtins/getopt.c
@@ -75,7 +75,7 @@ int sh_opterr = 1;
int sh_optopt = '?';
-/* Set to 1 when we see an illegal option; public so getopts can reset it. */
+/* Set to 1 when we see an invalid option; public so getopts can reset it. */
int sh_badopt = 0;
/* Scan elements of ARGV (whose length is ARGC) for option characters
@@ -135,15 +135,6 @@ sh_getopt (argc, argv, optstring)
nextchar = (char *)NULL;
}
- /* Do the increment of `sh_optind' we deferred because the last option
- was illegal. */
- if (sh_badopt && (nextchar == 0 || *nextchar == '\0'))
- {
- sh_badopt = 0;
- sh_optind++;
- nextchar = (char *)NULL;
- }
-
if (nextchar == 0 || *nextchar == '\0')
{
/* If we have done all the ARGV-elements, stop the scan. */
@@ -179,8 +170,13 @@ sh_getopt (argc, argv, optstring)
sh_optopt = c;
- /* If the option is illegal, return an error, but defer updating sh_optind
- until the next call so $OPTIND is correct. */
+ /* Increment `sh_optind' when we start to process its last character. */
+ if (nextchar == 0 || *nextchar == '\0')
+ {
+ sh_optind++;
+ nextchar = (char *)NULL;
+ }
+
if (sh_badopt = (temp == NULL || c == ':'))
{
if (sh_opterr)
@@ -189,13 +185,6 @@ sh_getopt (argc, argv, optstring)
return '?';
}
- /* Increment `sh_optind' when we start to process its last character. */
- if (nextchar == 0 || *nextchar == '\0')
- {
- sh_optind++;
- nextchar = (char *)NULL;
- }
-
if (temp[1] == ':')
{
if (nextchar && *nextchar)
diff --git a/builtins/getopts.def b/builtins/getopts.def
index 0e881d2..a2a82ff 100644
--- a/builtins/getopts.def
+++ b/builtins/getopts.def
@@ -1,7 +1,7 @@
This file is getopts.def, from which is created getopts.c.
It implements the builtin "getopts" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -39,11 +39,11 @@ getopts places that argument into the shell variable OPTARG.
getopts reports errors in one of two ways. If the first character
of OPTSTRING is a colon, getopts uses silent error reporting. In
-this mode, no error messages are printed. If an illegal option is
+this mode, no error messages are printed. If an invalid option is
seen, getopts places the option character found into OPTARG. If a
required argument is not found, getopts places a ':' into NAME and
sets OPTARG to the option character found. If getopts is not in
-silent mode, and an illegal option is seen, getopts places '?' into
+silent mode, and an invalid option is seen, getopts places '?' into
NAME and unsets OPTARG. If a required option is not found, a '?'
is placed in NAME, OPTARG is unset, and a diagnostic message is
printed.
@@ -75,11 +75,14 @@ $END
#include "getopt.h"
#define G_EOF -1
-#define G_ILLEGAL_OPT -2
+#define G_INVALID_OPT -2
#define G_ARG_MISSING -3
extern char *this_command_name;
+static int getopts_bind_variable __P((char *, char *));
+static int dogetopts __P((int, char **));
+
/* getopts_reset is magic code for when OPTIND is reset. N is the
value that has just been assigned to OPTIND. */
void
@@ -103,7 +106,7 @@ getopts_bind_variable (name, value)
}
else
{
- builtin_error ("`%s': not a valid identifier", name);
+ sh_invalidid (name);
return (EXECUTION_FAILURE);
}
}
@@ -112,9 +115,9 @@ getopts_bind_variable (name, value)
(identical to that of ksh-88). The special handling is enabled if
the first character of the option string is a colon; this handling
disables diagnostic messages concerning missing option arguments
- and illegal option characters. The handling is as follows.
+ and invalid option characters. The handling is as follows.
- ILLEGAL OPTIONS:
+ INVALID OPTIONS:
name -> "?"
if (special_error) then
OPTARG = option character found
@@ -193,7 +196,7 @@ dogetopts (argc, argv)
;
for (words = rest_of_args; words; words = words->next, i++)
;
- v = alloc_array (i + 1);
+ v = strvec_create (i + 1);
for (i = 0; i < 10 && dollar_vars[i]; i++)
v[i] = dollar_vars[i];
for (words = rest_of_args; words; words = words->next, i++)
@@ -207,7 +210,8 @@ dogetopts (argc, argv)
if (special_error)
sh_opterr = old_opterr;
- /* Set the OPTIND variable in any case, to handle "--" skipping. */
+ /* Set the OPTIND variable in any case, to handle "--" skipping. It's
+ highly unlikely that 14 digits will be too few. */
if (sh_optind < 10)
{
numval[14] = sh_optind + '0';
@@ -228,13 +232,13 @@ dogetopts (argc, argv)
/* If an error occurred, decide which one it is and set the return
code appropriately. In all cases, the option character in error
- is in OPTOPT. If an illegal option was encountered, OPTARG is
+ is in OPTOPT. If an invalid option was encountered, OPTARG is
NULL. If a required option argument was missing, OPTARG points
to a NULL string (that is, sh_optarg[0] == 0). */
if (ret == '?')
{
if (sh_optarg == NULL)
- ret = G_ILLEGAL_OPT;
+ ret = G_INVALID_OPT;
else if (sh_optarg[0] == '\0')
ret = G_ARG_MISSING;
}
@@ -245,9 +249,9 @@ dogetopts (argc, argv)
return (EXECUTION_FAILURE);
}
- if (ret == G_ILLEGAL_OPT)
+ if (ret == G_INVALID_OPT)
{
- /* Illegal option encountered. */
+ /* Invalid option encountered. */
ret = getopts_bind_variable (name, "?");
if (special_error)
@@ -257,7 +261,7 @@ dogetopts (argc, argv)
bind_variable ("OPTARG", strval);
}
else
- makunbound ("OPTARG", shell_variables);
+ unbind_variable ("OPTARG");
return (ret);
}
@@ -276,7 +280,7 @@ dogetopts (argc, argv)
else
{
ret = getopts_bind_variable (name, "?");
- makunbound ("OPTARG", shell_variables);
+ unbind_variable ("OPTARG");
}
return (ret);
}
diff --git a/builtins/hash.def b/builtins/hash.def
index 35d5086..6e0e347 100644
--- a/builtins/hash.def
+++ b/builtins/hash.def
@@ -1,7 +1,7 @@
This file is hash.def, from which is created hash.c.
It implements the builtin "hash" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,15 +23,17 @@ $PRODUCES hash.c
$BUILTIN hash
$FUNCTION hash_builtin
-$SHORT_DOC hash [-r] [-p pathname] [-t] [name ...]
+$SHORT_DOC hash [-lr] [-p pathname] [-dt] [name ...]
For each NAME, the full pathname of the command is determined and
remembered. If the -p option is supplied, PATHNAME is used as the
full pathname of NAME, and no path search is performed. The -r
-option causes the shell to forget all remembered locations.
+option causes the shell to forget all remembered locations. The -d
+option causes the shell to forget the remembered location of each NAME.
If the -t option is supplied the full pathname to which each NAME
corresponds is printed. If multiple NAME arguments are supplied with
--t, the NAME is printed before the hashed full pathname. If no arguments
-are given, information about remembered commands is displayed.
+-t, the NAME is printed before the hashed full pathname. The -l option
+causes output to be displayed in a format that may be reused as input.
+If no arguments are given, information about remembered commands is displayed.
$END
#include <config.h>
@@ -60,8 +62,10 @@ extern int dot_found_in_search;
extern char *this_command_name;
static int add_hashed_command __P((char *, int));
-static int print_hashed_commands __P((void));
-static int list_hashed_filename_targets __P((WORD_LIST *));
+static int print_hash_info __P((BUCKET_CONTENTS *));
+static int print_portable_hash_info __P((BUCKET_CONTENTS *));
+static int print_hashed_commands __P((int));
+static int list_hashed_filename_targets __P((WORD_LIST *, int));
/* Print statistics on the current state of hashed commands. If LIST is
not empty, then rehash (or hash in the first place) the specified
@@ -70,7 +74,7 @@ int
hash_builtin (list)
WORD_LIST *list;
{
- int expunge_hash_table, list_targets, opt;
+ int expunge_hash_table, list_targets, list_portably, delete, opt;
char *w, *pathname;
if (hashing_enabled == 0)
@@ -79,19 +83,25 @@ hash_builtin (list)
return (EXECUTION_FAILURE);
}
- expunge_hash_table = list_targets = 0;
+ expunge_hash_table = list_targets = list_portably = delete = 0;
pathname = (char *)NULL;
reset_internal_getopt ();
- while ((opt = internal_getopt (list, "rp:t")) != -1)
+ while ((opt = internal_getopt (list, "dlp:rt")) != -1)
{
switch (opt)
{
- case 'r':
- expunge_hash_table = 1;
+ case 'd':
+ delete = 1;
+ break;
+ case 'l':
+ list_portably = 1;
break;
case 'p':
pathname = list_optarg;
break;
+ case 'r':
+ expunge_hash_table = 1;
+ break;
case 't':
list_targets = 1;
break;
@@ -105,40 +115,38 @@ hash_builtin (list)
/* hash -t requires at least one argument. */
if (list == 0 && list_targets)
{
- builtin_error("-t: argument required");
+ sh_needarg ("-t");
return (EXECUTION_FAILURE);
}
- /* We want hash -r to be silent, but hash -- to print hashing info. That
- is the reason for the test of expunge_hash_table. */
+ /* 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)
{
- if (print_hashed_commands () == 0)
+ if (print_hashed_commands (list_portably) == 0)
printf ("%s: hash table empty\n", this_command_name);
return (EXECUTION_SUCCESS);
}
if (expunge_hash_table)
- flush_hashed_filenames ();
+ phash_flush ();
/* If someone runs `hash -r -t xyz' he will be disappointed. */
if (list_targets)
- {
- return (list_hashed_filename_targets (list));
- }
+ return (list_hashed_filename_targets (list, list_portably));
#if defined (RESTRICTED_SHELL)
if (restricted && pathname && strchr (pathname, '/'))
{
- builtin_error ("%s: restricted", pathname);
+ sh_restricted (pathname);
return (EXECUTION_FAILURE);
}
#endif
for (opt = EXECUTION_SUCCESS; list; list = list->next)
{
- /* Add or rehash the specified commands. */
+ /* Add, remove or rehash the specified commands. */
w = list->word->word;
if (pathname)
{
@@ -152,10 +160,15 @@ hash_builtin (list)
opt = EXECUTION_FAILURE;
}
else
- remember_filename (w, pathname, 0, 0);
+ phash_insert (w, pathname, 0, 0);
}
else if (absolute_program (w))
continue;
+ else if (delete && phash_remove (w))
+ {
+ sh_notfound (w);
+ opt = EXECUTION_FAILURE;
+ }
else if (add_hashed_command (w, 0))
opt = EXECUTION_FAILURE;
}
@@ -177,51 +190,52 @@ add_hashed_command (w, quiet)
{
full_path = find_user_command (w);
if (full_path && executable_file (full_path))
- remember_filename (w, full_path, dot_found_in_search, 0);
+ phash_insert (w, full_path, dot_found_in_search, 0);
else
{
if (quiet == 0)
- builtin_error ("%s: not found", w);
+ sh_notfound (w);
rv++;
}
- if (full_path)
- free (full_path);
+ FREE (full_path);
}
return (rv);
}
/* Print information about current hashed info. */
static int
-print_hashed_commands ()
+print_hash_info (item)
+ BUCKET_CONTENTS *item;
{
- BUCKET_CONTENTS *item_list;
- int bucket, any_printed;
-
- if (hashed_filenames == 0)
- return (0);
-
- for (bucket = any_printed = 0; bucket < hashed_filenames->nbuckets; bucket++)
- {
- item_list = get_hash_bucket (bucket, hashed_filenames);
- if (item_list == 0)
- continue;
+ printf ("%4d\t%s\n", item->times_found, pathdata(item)->path);
+ return 0;
+}
- if (any_printed == 0)
- {
- printf ("hits\tcommand\n");
- any_printed++;
- }
+static int
+print_portable_hash_info (item)
+ BUCKET_CONTENTS *item;
+{
+ printf ("builtin hash -p %s %s\n", pathdata(item)->path, item->key);
+ return 0;
+}
- for ( ; item_list; item_list = item_list->next)
- printf ("%4d\t%s\n", item_list->times_found, pathdata(item_list)->path);
+static int
+print_hashed_commands (fmt)
+ int fmt;
+{
+ if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
+ return (0);
- }
- return (any_printed);
+ if (fmt == 0)
+ printf ("hits\tcommand\n");
+ hash_walk (hashed_filenames, fmt ? print_portable_hash_info : print_hash_info);
+ return (1);
}
static int
-list_hashed_filename_targets (list)
+list_hashed_filename_targets (list, fmt)
WORD_LIST *list;
+ int fmt;
{
int all_found, multiple;
char *target;
@@ -232,16 +246,21 @@ list_hashed_filename_targets (list)
for (l = list; l; l = l->next)
{
- target = find_hashed_filename (l->word->word);
+ target = phash_search (l->word->word);
if (target == 0)
{
all_found = 0;
- builtin_error ("%s: not found", l->word->word);
+ sh_notfound (l->word->word);
continue;
}
- if (multiple)
- printf ("%s\t", l->word->word);
- printf ("%s\n", target);
+ if (fmt)
+ printf ("builtin hash -p %s %s\n", target, l->word->word);
+ else
+ {
+ if (multiple)
+ printf ("%s\t", l->word->word);
+ printf ("%s\n", target);
+ }
}
return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
diff --git a/builtins/help.def b/builtins/help.def
index 22181b1..234307b 100644
--- a/builtins/help.def
+++ b/builtins/help.def
@@ -1,7 +1,7 @@
This file is help.def, from which is created help.c.
It implements the builtin "help" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -44,6 +44,10 @@ $END
# include <unistd.h>
#endif
+#include <errno.h>
+
+#include <filecntl.h>
+
#include "../shell.h"
#include "../builtins.h"
#include "../pathexp.h"
@@ -53,7 +57,12 @@ $END
#include <glob/strmatch.h>
#include <glob/glob.h>
-static void show_builtin_command_help __P((void));
+#ifndef errno
+extern int errno;
+#endif
+
+static void show_builtin_command_help __P((void));
+static void show_longdoc __P((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
@@ -62,7 +71,7 @@ int
help_builtin (list)
WORD_LIST *list;
{
- register int i, j;
+ register int i;
char *pattern, *name;
int plen, match_found, sflag;
@@ -112,8 +121,7 @@ help_builtin (list)
printf ("%s: %s\n", name, shell_builtins[i].short_doc);
if (sflag == 0)
- for (j = 0; shell_builtins[i].long_doc[j]; j++)
- printf (" %s\n", shell_builtins[i].long_doc[j]);
+ show_longdoc (i);
match_found++;
}
@@ -122,7 +130,7 @@ help_builtin (list)
if (match_found == 0)
{
- builtin_error ("no help topics match `%s'. Try `help help'.", pattern);
+ builtin_error ("no help topics match `%s'. Try `help help' or `man -k %s' or `info %s'.", pattern, pattern, pattern);
return (EXECUTION_FAILURE);
}
@@ -130,6 +138,35 @@ help_builtin (list)
return (EXECUTION_SUCCESS);
}
+/* By convention, enforced by mkbuiltins.c, if separate help files are being
+ 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;
+{
+ register int j;
+ char * const *doc;
+ int fd;
+
+ doc = shell_builtins[i].long_doc;
+
+ if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
+ {
+ fd = open (doc[0], O_RDONLY);
+ if (fd == -1)
+ {
+ builtin_error ("%s: cannot open: %s", doc[0], strerror (errno));
+ return;
+ }
+ zcatfd (fd, 1, doc[0]);
+ close (fd);
+ }
+ else
+ for (j = 0; doc[j]; j++)
+ printf (" %s\n", doc[j]);
+}
+
static void
show_builtin_command_help ()
{
@@ -140,6 +177,7 @@ show_builtin_command_help ()
"These shell commands are defined internally. Type `help' to see this list.\n\
Type `help name' to find out more about the function `name'.\n\
Use `info bash' to find out more about the shell in general.\n\
+Use `man -k' or `info' to find out more about commands not in this list.\n\
\n\
A star (*) next to a name means that the command is disabled.\n\
\n");
diff --git a/builtins/history.def b/builtins/history.def
index df416ae..7311705 100644
--- a/builtins/history.def
+++ b/builtins/history.def
@@ -1,7 +1,7 @@
This file is history.def, from which is created history.c.
It implements the builtin "history" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -70,6 +70,8 @@ $END
extern int errno;
#endif
+extern int current_command_line_count;
+
static void display_history __P((WORD_LIST *));
static int delete_histent __P((int));
static int delete_last_history __P((void));
@@ -89,9 +91,9 @@ int
history_builtin (list)
WORD_LIST *list;
{
- int flags, opt, result;
+ int flags, opt, result, old_history_lines;
char *filename, *delete_arg;
- long delete_offset;
+ intmax_t delete_offset;
flags = 0;
reset_internal_getopt ();
@@ -168,7 +170,7 @@ history_builtin (list)
|| (delete_offset < history_base)
|| (delete_offset > (history_base + history_length)))
{
- builtin_error ("%s: not a valid history position", delete_arg);
+ sh_erange (delete_arg, "history position");
return (EXECUTION_FAILURE);
}
opt = delete_offset;
@@ -197,10 +199,12 @@ history_builtin (list)
else if (flags & NFLAG) /* Read `new' history from file. */
{
/* Read all of the lines in the file that we haven't already read. */
+ old_history_lines = history_lines_in_file;
using_history ();
result = read_history_range (filename, history_lines_in_file, -1);
using_history ();
history_lines_in_file = where_history ();
+ history_lines_this_session += history_lines_in_file - old_history_lines;
}
return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
@@ -215,7 +219,7 @@ display_history (list)
WORD_LIST *list;
{
register int i;
- long limit;
+ intmax_t limit;
HIST_ENTRY **hlist;
if (list)
@@ -297,10 +301,28 @@ push_history (list)
{
char *s;
+ /* Delete the last history entry if it was a single entry added to the
+ history list (generally the `history -s' itself), or if `history -s'
+ is being used in a compound command and the compound command was
+ added to the history as a single element (command-oriented history).
+ If you don't want history -s to remove the compound command from the
+ history, change #if 0 to #if 1 below. */
+#if 0
if (hist_last_line_added && delete_last_history () == 0)
- return;
+#else
+ if ((hist_last_line_added || (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
+ && delete_last_history () == 0)
+#endif
+ return;
+
s = string_list (list);
- maybe_add_history (s); /* Obeys HISTCONTROL setting. */
+ /* Call check_add_history with FORCE set to 1 to skip the check against
+ current_command_line_count. If history -s is used in a compound
+ command, the above code will delete the compound command's history
+ entry and this call will add the line to the history as a separate
+ entry. Without FORCE=1, if current_command_line_count were > 1, the
+ line would be appended to the entry before the just-deleted entry. */
+ check_add_history (s, 1); /* obeys HISTCONTROL, HISTIGNORE */
free (s);
}
diff --git a/builtins/inlib.def b/builtins/inlib.def
index ff068f8..094c4b9 100644
--- a/builtins/inlib.def
+++ b/builtins/inlib.def
@@ -1,7 +1,7 @@
This file is inlib.def, from which is created inlib.c.
It implements the Apollo-specific builtin "inlib" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -51,7 +51,7 @@ inlib_builtin (list)
if (!list)
{
- builtin_error ("usage: inlib pathname [pathname...]");
+ builtin_usage ();
return (EX_USAGE);
}
@@ -64,7 +64,7 @@ inlib_builtin (list)
if (status.all != status_$ok)
{
- builtin_error ("inlib failed for %s", list->word->word);
+ builtin_error ("%s: inlib failed", list->word->word);
return_value = EXECUTION_FAILURE;
}
diff --git a/builtins/jobs.def b/builtins/jobs.def
index f8a2b00..54f50ca 100644
--- a/builtins/jobs.def
+++ b/builtins/jobs.def
@@ -1,7 +1,7 @@
This file is jobs.def, from which is created jobs.c.
It implements the builtins "jobs" and "disown" in Bash.
-Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -98,7 +98,7 @@ jobs_builtin (list)
case 'x':
if (form != JLIST_STANDARD)
{
- builtin_error ("Other options not allowed with `-x'");
+ builtin_error ("no other options allowed with `-x'");
return (EXECUTION_FAILURE);
}
execute++;
@@ -145,7 +145,7 @@ jobs_builtin (list)
if ((job == NO_JOB) || !jobs || !jobs[job])
{
- builtin_error ("no such job %s", list->word->word);
+ sh_badjob (list->word->word);
any_failed++;
}
else if (job != DUP_JOB)
@@ -219,7 +219,7 @@ disown_builtin (list)
{
int opt, job, retval, nohup_only, running_jobs, all_jobs;
sigset_t set, oset;
- long pid_value;
+ intmax_t pid_value;
nohup_only = running_jobs = all_jobs = 0;
reset_internal_getopt ();
@@ -263,7 +263,7 @@ disown_builtin (list)
if (job == NO_JOB || jobs == 0 || job < 0 || job >= job_slots || jobs[job] == 0)
{
- builtin_error ("%s: no such job", list ? list->word->word : "current");
+ sh_badjob (list ? list->word->word : "current");
retval = EXECUTION_FAILURE;
}
else if (nohup_only)
diff --git a/builtins/kill.def b/builtins/kill.def
index d7aba5b..96b34fc 100644
--- a/builtins/kill.def
+++ b/builtins/kill.def
@@ -1,7 +1,7 @@
This file is kill.def, from which is created kill.c.
It implements the builtin "kill" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -73,10 +73,10 @@ int
kill_builtin (list)
WORD_LIST *list;
{
- int signal, any_succeeded, listing, saw_signal;
+ int sig, any_succeeded, listing, saw_signal;
char *sigspec, *word;
pid_t pid;
- long pid_value;
+ intmax_t pid_value;
if (list == 0)
{
@@ -85,7 +85,7 @@ kill_builtin (list)
}
any_succeeded = listing = saw_signal = 0;
- signal = SIGTERM;
+ sig = SIGTERM;
sigspec = "TERM";
/* Process options. */
@@ -105,14 +105,14 @@ kill_builtin (list)
{
sigspec = list->word->word;
if (sigspec[0] == '0' && sigspec[1] == '\0')
- signal = 0;
+ sig = 0;
else
- signal = decode_signal (sigspec);
+ sig = decode_signal (sigspec);
list = list->next;
}
else
{
- builtin_error ("%s requires an argument", word);
+ sh_needarg (word);
return (EXECUTION_FAILURE);
}
}
@@ -132,7 +132,7 @@ kill_builtin (list)
else if ((*word == '-') && !saw_signal)
{
sigspec = word + 1;
- signal = decode_signal (sigspec);
+ sig = decode_signal (sigspec);
saw_signal++;
list = list->next;
}
@@ -144,9 +144,9 @@ kill_builtin (list)
return (display_signal_list (list, 0));
/* OK, we are killing processes. */
- if (signal == NO_SIG)
+ if (sig == NO_SIG)
{
- builtin_error ("bad signal spec `%s'", sigspec);
+ sh_invalidsig (sigspec);
return (EXECUTION_FAILURE);
}
@@ -163,12 +163,12 @@ kill_builtin (list)
if (*word == '-')
word++;
- if (*word && legal_number (word, &pid_value) && (pid_value == (pid_t)pid_value))
+ /* 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))
{
- /* Use the entire argument in case of minus sign presence. */
pid = (pid_t) pid_value;
- if (kill_pid (pid, signal, 0) < 0)
+ if ((pid < -1 ? kill_pid (-pid, sig, 1) : kill_pid (pid, sig, 0)) < 0)
goto signal_error;
else
any_succeeded++;
@@ -190,7 +190,7 @@ kill_builtin (list)
if (job < 0 || job >= job_slots || !jobs[job])
{
if (job != DUP_JOB)
- builtin_error ("%s: no such job", list->word->word);
+ sh_badjob (list->word->word);
UNBLOCK_CHILD (oset);
CONTINUE_OR_FAIL;
}
@@ -203,11 +203,11 @@ kill_builtin (list)
UNBLOCK_CHILD (oset);
- if (kill_pid (pid, signal, 1) < 0)
+ if (kill_pid (pid, sig, 1) < 0)
{
signal_error:
if (errno == EINVAL)
- builtin_error ("Invalid signal %d", signal);
+ sh_invalidsig (sigspec);
else
builtin_error ("(%ld) - %s", (long)pid, strerror (errno));
CONTINUE_OR_FAIL;
@@ -217,7 +217,7 @@ kill_builtin (list)
}
else
{
- builtin_error ("`%s': not a pid or valid job spec", list->word->word);
+ sh_badpid (list->word->word);
CONTINUE_OR_FAIL;
}
continue_killing:
diff --git a/builtins/let.def b/builtins/let.def
index 1d8c25e..7c9341e 100644
--- a/builtins/let.def
+++ b/builtins/let.def
@@ -1,7 +1,7 @@
This file is let.def, from which is created let.c.
It implements the builtin "let" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -24,13 +24,16 @@ $FUNCTION let_builtin
$PRODUCES let.c
$SHORT_DOC let arg [arg ...]
Each ARG is an arithmetic expression to be evaluated. Evaluation
-is done in long integers with no check for overflow, though division
-by 0 is trapped and flagged as an error. The following list of
-operators is grouped into levels of equal-precedence operators.
+is done in fixed-width integers with no check for overflow, though
+division by 0 is trapped and flagged as an error. The following
+list of operators is grouped into levels of equal-precedence operators.
The levels are listed in order of decreasing precedence.
+ id++, id-- variable post-increment, post-decrement
+ ++id, --id variable pre-increment, pre-decrement
-, + unary minus, plus
!, ~ logical and bitwise negation
+ ** exponentiation
*, /, % multiplication, division, remainder
+, - addition, subtraction
<<, >> left and right bitwise shifts
@@ -48,7 +51,7 @@ The levels are listed in order of decreasing precedence.
&=, ^=, |= assignment
Shell variables are allowed as operands. The name of the variable
-is replaced by its value (coerced to a long integer) within
+is replaced by its value (coerced to a fixed-width integer) within
an expression. The variable need not have its integer attribute
turned on to be used in an expression.
@@ -77,9 +80,13 @@ int
let_builtin (list)
WORD_LIST *list;
{
- long ret;
+ intmax_t ret;
int expok;
+ /* Skip over leading `--' argument. */
+ if (list && list->word && ISOPTION (list->word->word, '-'))
+ list = list->next;
+
if (list == 0)
{
builtin_error ("expression expected");
@@ -102,7 +109,8 @@ exp_builtin (list)
WORD_LIST *list;
{
char *exp;
- int ret, expok;
+ intmax_t ret;
+ int expok;
if (list == 0)
{
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
index 7532866..c911f86 100644
--- a/builtins/mkbuiltins.c
+++ b/builtins/mkbuiltins.c
@@ -1,7 +1,7 @@
/* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
a single source file called builtins.def. */
-/* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -38,11 +38,16 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#include "../bashansi.h"
#include <stdio.h>
+#include <errno.h>
#include "stdc.h"
#define DOCFILE "builtins.texi"
+#ifndef errno
+extern int errno;
+#endif
+
static char *xmalloc (), *xrealloc ();
#if !defined (__STDC__) && !defined (strcpy)
@@ -66,9 +71,13 @@ int only_documentation = 0;
/* Non-zero means to not do any productions. */
int inhibit_production = 0;
-#if !defined (OLDCODE)
-int no_long_document = 0;
-#endif /* !OLDCODE */
+/* Non-zero means to produce separate help files for each builtin, named by
+ the builtin name, in `./helpfiles'. */
+int separate_helpfiles = 0;
+
+/* The name of a directory into which the separate external help files will
+ eventually be installed. */
+char *helpfile_directory;
/* The name of a directory to precede the filename when reporting
errors. */
@@ -149,11 +158,16 @@ void write_documentation ();
void write_longdocs ();
void write_builtins ();
+int write_helpfiles ();
+
void free_defs ();
void add_documentation ();
void must_be_building ();
void remove_trailing_whitespace ();
+
+#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
@@ -204,10 +218,11 @@ main (argc, argv)
only_documentation = 1;
documentation_file = fopen (documentation_filename, "w");
}
-#if !defined (OLDCODE)
- else if (strcmp (arg, "-nodocument") == 0)
- no_long_document = 1;
-#endif /* !OLDCODE */
+ else if (strcmp (arg, "-H") == 0)
+ {
+ separate_helpfiles = 1;
+ helpfile_directory = argv[arg_index++];
+ }
else
{
fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
@@ -278,6 +293,11 @@ main (argc, argv)
fclose (externfile);
}
+ if (separate_helpfiles)
+ {
+ write_helpfiles (saved_builtins);
+ }
+
if (documentation_file)
{
fprintf (documentation_file, "@end ftable\n");
@@ -1036,8 +1056,9 @@ save_builtin (builtin)
}
/* Flags that mean something to write_documentation (). */
-#define STRING_ARRAY 1
-#define TEXINFO 2
+#define STRING_ARRAY 1
+#define TEXINFO 2
+#define PLAINTEXT 4
char *structfile_header[] = {
"/* builtins.c -- the built in shell commands. */",
@@ -1045,7 +1066,7 @@ char *structfile_header[] = {
"/* This file is manufactured by ./mkbuiltins, and should not be",
" edited by hand. See the source to mkbuiltins for details. */",
"",
- "/* Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc.",
+ "/* Copyright (C) 1987-2002 Free Software Foundation, Inc.",
"",
" This file is part of GNU Bash, the Bourne Again SHell.",
"",
@@ -1165,8 +1186,8 @@ write_builtins (defs, structfile, externfile)
fprintf (externfile, "extern int %s __P((WORD_LIST *));\n",
builtin->function);
- fprintf (externfile, "extern char *%s_doc[];\n",
- builtin->docname ? builtin->docname : builtin->name);
+ fprintf (externfile, "extern char * const %s_doc[];\n",
+ document_name (builtin));
}
/* Write the structure definition. */
@@ -1183,17 +1204,19 @@ write_builtins (defs, structfile, externfile)
"BUILTIN_ENABLED | STATIC_BUILTIN",
(builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
(builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
- builtin->docname ? builtin->docname : builtin->name);
+ document_name (builtin));
fprintf
(structfile, " \"%s\", (char *)NULL },\n",
builtin->shortdoc ? builtin->shortdoc : builtin->name);
- /* Save away this builtin for later writing of the
- long documentation strings. */
- save_builtin (builtin);
}
+ if (structfile || separate_helpfiles)
+ /* Save away this builtin for later writing of the
+ long documentation strings. */
+ save_builtin (builtin);
+
/* Write out the matching #endif, if neccessary. */
if (builtin->dependencies)
{
@@ -1223,6 +1246,8 @@ write_longdocs (stream, builtins)
{
register int i;
register BUILTIN_DESC *builtin;
+ char *dname;
+ char *sarray[2];
for (i = 0; i < builtins->sindex; i++)
{
@@ -1232,9 +1257,20 @@ write_longdocs (stream, builtins)
write_ifdefs (stream, builtin->dependencies->array);
/* Write the long documentation strings. */
- fprintf (stream, "char *%s_doc[] =",
- builtin->docname ? builtin->docname : builtin->name);
- write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY);
+ dname = document_name (builtin);
+ fprintf (stream, "char * const %s_doc[] =", dname);
+
+ if (separate_helpfiles)
+ {
+ int l = strlen (helpfile_directory) + strlen (dname) + 1;
+ sarray[0] = (char *)xmalloc (l + 1);
+ sprintf (sarray[0], "%s/%s", helpfile_directory, dname);
+ sarray[1] = (char *)NULL;
+ write_documentation (stream, sarray, 0, STRING_ARRAY);
+ free (sarray[0]);
+ }
+ else
+ write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY);
if (builtin->dependencies)
write_endifs (stream, builtin->dependencies->array);
@@ -1321,12 +1357,6 @@ write_documentation (stream, documentation, indentation, flags)
if (string_array)
fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n");
-#if !defined (OLDCODE)
- /* XXX -- clean me up; for experiment only */
- if (no_long_document)
- goto end_of_document;
-#endif /* !OLDCODE */
-
for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
{
/* Allow #ifdef's to be written out verbatim. */
@@ -1384,14 +1414,52 @@ write_documentation (stream, documentation, indentation, flags)
fprintf (stream, "%s\n", line);
}
-#if !defined (OLDCODE)
-end_of_document:
-#endif /* !OLDCODE */
-
if (string_array)
fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
}
+int
+write_helpfiles (builtins)
+ ARRAY *builtins;
+{
+ char *helpfile, *bname;
+ FILE *helpfp;
+ int i, hdlen;
+ BUILTIN_DESC *builtin;
+
+ i = mkdir ("helpfiles", 0777);
+ if (i < 0 && errno != EEXIST)
+ {
+ fprintf (stderr, "write_helpfiles: helpfiles: cannot create directory\n");
+ return -1;
+ }
+
+ hdlen = strlen ("helpfiles/");
+ for (i = 0; i < builtins->sindex; i++)
+ {
+ builtin = (BUILTIN_DESC *)builtins->array[i];
+
+ bname = document_name (builtin);
+ helpfile = (char *)xmalloc (hdlen + strlen (bname) + 1);
+ sprintf (helpfile, "helpfiles/%s", bname);
+
+ helpfp = fopen (helpfile, "w");
+ if (helpfp == 0)
+ {
+ fprintf (stderr, "write_helpfiles: cannot open %s\n", helpfile);
+ free (helpfile);
+ continue;
+ }
+
+ write_documentation (helpfp, builtin->longdoc->array, 4, PLAINTEXT);
+
+ fflush (helpfp);
+ fclose (helpfp);
+ free (helpfile);
+ }
+ return 0;
+}
+
static int
_find_in_table (name, name_table)
char *name, *name_table[];
diff --git a/builtins/printf.def b/builtins/printf.def
index bcf625c..8821ecb 100644
--- a/builtins/printf.def
+++ b/builtins/printf.def
@@ -1,7 +1,7 @@
This file is printf.def, from which is created printf.c.
It implements the builtin "printf" in Bash.
-Copyright (C) 1997 Free Software Foundation, Inc.
+Copyright (C) 1997-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -56,18 +56,17 @@ $END
#include "../bashansi.h"
-#define NEED_STRTOIMAX_DECL
-
#include "../shell.h"
#include "stdc.h"
#include "bashgetopt.h"
#include "common.h"
-/* This should use the ISO C constant format strings; I'll do that later. */
-#if SIZEOF_LONG < SIZEOF_LONG_LONG
-# define INTMAX_CONV "ll"
-#else
-# define INTMAX_CONV "l"
+#if !defined (PRIdMAX)
+# if HAVE_LONG_LONG
+# define PRIdMAX "lld"
+# else
+# define PRIdMAX "ld"
+# endif
#endif
#if !defined (errno)
@@ -104,25 +103,28 @@ extern int errno;
#define SKIP1 "#'-+ 0"
#define LENMODS "hjlLtz"
+static void printf_erange __P((char *));
static void printstr __P((char *, char *, int, int, int));
static int tescape __P((char *, int, char *, int *));
static char *bexpand __P((char *, int, int *, int *));
-static char *mklong __P((char *, char *));
+static char *mklong __P((char *, char *, size_t));
static int getchr __P((void));
static char *getstr __P((void));
static int getint __P((void));
-static long getlong __P((void));
-static unsigned long getulong __P((void));
-#if defined (HAVE_LONG_LONG)
-static long long getllong __P((void));
-static unsigned long long getullong __P((void));
-#endif
static intmax_t getintmax __P((void));
static uintmax_t getuintmax __P((void));
-static double getdouble __P((void));
+
#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD
-static long double getldouble __P((void));
+typedef long double floatmax_t;
+# define FLOATMAX_CONV "L"
+# define strtofltmax strtold
+#else
+typedef double floatmax_t;
+# define FLOATMAX_CONV ""
+# define strtofltmax strtod
#endif
+static floatmax_t getfloatmax __P((void));
+
static int asciicode __P((void));
static WORD_LIST *garglist;
@@ -138,18 +140,15 @@ printf_builtin (list)
{
int ch, fieldwidth, precision;
int have_fieldwidth, have_precision;
- long tw;
+ intmax_t tw;
char convch, thisch, nextch, *format, *modstart, *fmt, *start;
conversion_error = 0;
retval = EXECUTION_SUCCESS;
- reset_internal_getopt ();
- if (internal_getopt (list, "") != -1)
- {
- builtin_usage();
- return (EX_USAGE);
- }
- list = loptend;
+
+ if (no_options (list))
+ return (EX_USAGE);
+ list = loptend; /* skip over possible `--' */
if (list == 0)
{
@@ -288,7 +287,7 @@ printf_builtin (list)
bind_var_to_int (var, tw);
else
{
- builtin_error ("%s: invalid variable name", var);
+ sh_invalidid (var);
PRETURN (EXECUTION_FAILURE);
}
}
@@ -322,7 +321,10 @@ printf_builtin (list)
char *p, *xp;
p = getstr ();
- xp = sh_backslash_quote (p);
+ if (ansic_shouldquote (p))
+ xp = ansic_quote (p, 0, (int *)0);
+ else
+ xp = sh_backslash_quote (p);
if (xp)
{
/* Use printstr to get fieldwidth and precision right. */
@@ -336,32 +338,23 @@ printf_builtin (list)
case 'i':
{
char *f;
-#if defined (HAVE_LONG_LONG)
- if (thisch == 'l' && nextch == 'l')
- {
- long long p;
+ long p;
+ intmax_t pp;
- p = getllong ();
- f = mklong (start, "ll");
- PF(f, p);
- }
- else
-#endif
- if (thisch == 'j')
+ p = pp = getintmax ();
+ if (p != pp)
{
- intmax_t p;
-
- p = getintmax ();
- f = mklong (start, INTMAX_CONV);
- PF(f, p);
+ f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
+ PF (f, pp);
}
else
{
- long p;
-
- p = getlong ();
- f = mklong (start, "l");
- PF(f, p);
+ /* Optimize the common case where the integer fits
+ in "long". This also works around some long
+ long and/or intmax_t library bugs in the common
+ case, e.g. glibc 2.2 x86. */
+ f = mklong (start, "l", 1);
+ PF (f, p);
}
break;
}
@@ -372,31 +365,18 @@ printf_builtin (list)
case 'X':
{
char *f;
-#if defined (HAVE_LONG_LONG)
- if (thisch == 'l' && nextch == 'l')
- {
- unsigned long long p;
+ unsigned long p;
+ uintmax_t pp;
- p = getullong ();
- f = mklong (start, "ll");
- PF(f, p);
- }
- else
-#endif
- if (thisch == 'j')
+ p = pp = getuintmax ();
+ if (p != pp)
{
- uintmax_t p;
-
- p = getuintmax ();
- f = mklong (start, INTMAX_CONV);
- PF(f, p);
+ f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
+ PF (f, pp);
}
else
{
- unsigned long p;
-
- p = getulong ();
- f = mklong (start, "l");
+ f = mklong (start, "l", 1);
PF (f, p);
}
break;
@@ -414,24 +394,11 @@ printf_builtin (list)
#endif
{
char *f;
-#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD
- if (thisch == 'L')
- {
- long double p;
-
- p = getldouble ();
- f = mklong (start, "L");
- PF (f, p);
- }
- else
-#endif
- {
- double p;
+ floatmax_t p;
- p = getdouble ();
- f = mklong (start, "");
- PF (f, p);
- }
+ p = getfloatmax ();
+ f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1);
+ PF (f, p);
break;
}
@@ -454,6 +421,13 @@ printf_builtin (list)
PRETURN (retval);
}
+static void
+printf_erange (s)
+ char *s;
+{
+ builtin_error ("warning: %s: %s", s, strerror(ERANGE));
+}
+
/* We duplicate a lot of what printf(3) does here. */
static void
printstr (fmt, string, len, fieldwidth, precision)
@@ -605,16 +579,11 @@ tescape (estart, trans_squote, cp, sawc)
/* %b octal constants are `\0' followed by one, two, or three
octal digits... */
case '0':
- for (temp = 3, evalue = 0; ISOCTAL (*p) && temp--; p++)
- evalue = (evalue * 8) + OCTVALUE (*p);
- *cp = evalue & 0xFF;
- break;
-
/* but, as an extension, the other echo-like octal escape
sequences are supported as well. */
case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
- for (temp = 2, evalue = c - '0'; ISOCTAL (*p) && temp--; p++)
+ for (temp = 2+(c=='0'), evalue = c - '0'; ISOCTAL (*p) && temp--; p++)
evalue = (evalue * 8) + OCTVALUE (*p);
*cp = evalue & 0xFF;
break;
@@ -706,14 +675,14 @@ bexpand (string, len, sawc, lenp)
}
static char *
-mklong (str, modifiers)
+mklong (str, modifiers, mlen)
char *str;
char *modifiers;
+ size_t mlen;
{
- size_t len, slen, mlen;
+ size_t len, slen;
slen = strlen (str);
- mlen = strlen (modifiers);
len = slen + mlen + 1;
if (len > conv_bufsize)
@@ -759,152 +728,24 @@ getstr ()
static int
getint ()
{
- long ret;
+ intmax_t ret;
- ret = getlong ();
+ ret = getintmax ();
if (ret > INT_MAX)
{
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+ printf_erange (garglist->word->word);
ret = INT_MAX;
}
else if (ret < INT_MIN)
{
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+ printf_erange (garglist->word->word);
ret = INT_MIN;
}
return ((int)ret);
}
-static long
-getlong ()
-{
- long ret;
- char *ep;
-
- if (garglist == 0)
- return (0);
-
- if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
- return asciicode ();
-
- errno = 0;
- ret = strtol (garglist->word->word, &ep, 0);
-
- if (*ep)
- {
- builtin_error ("%s: invalid number", garglist->word->word);
- /* POSIX.2 says ``...a diagnostic message shall be written to standard
- error, and the utility shall not exit with a zero exit status, but
- shall continue processing any remaining operands and shall write the
- value accumulated at the time the error was detected to standard
- output.'' Yecch. */
- ret = 0;
- conversion_error = 1;
- }
- else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
-
- garglist = garglist->next;
- return (ret);
-}
-
-static unsigned long
-getulong ()
-{
- unsigned long ret;
- char *ep;
-
- if (garglist == 0)
- return (0);
-
- if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
- return asciicode ();
-
- errno = 0;
- ret = strtoul (garglist->word->word, &ep, 0);
-
- if (*ep)
- {
- builtin_error ("%s: invalid number", garglist->word->word);
- /* Same thing about POSIX.2 conversion error requirements as getlong(). */
- ret = 0;
- conversion_error = 1;
- }
- else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
-
- garglist = garglist->next;
- return (ret);
-}
-
-#if defined (HAVE_LONG_LONG)
-
-static long long
-getllong ()
-{
- long long ret;
- char *ep;
-
- if (garglist == 0)
- return (0);
-
- if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
- return asciicode ();
-
- errno = 0;
- ret = strtoll (garglist->word->word, &ep, 0);
-
- if (*ep)
- {
- builtin_error ("%s: invalid number", garglist->word->word);
- /* POSIX.2 says ``...a diagnostic message shall be written to standard
- error, and the utility shall not exit with a zero exit status, but
- shall continue processing any remaining operands and shall write the
- value accumulated at the time the error was detected to standard
- output.'' Yecch. */
- ret = 0;
- conversion_error = 1;
- }
- else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
-
- garglist = garglist->next;
- return (ret);
-}
-
-static unsigned long long
-getullong ()
-{
- unsigned long long ret;
- char *ep;
-
- if (garglist == 0)
- return (0);
-
- if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
- return asciicode ();
-
- errno = 0;
- ret = strtoull (garglist->word->word, &ep, 0);
-
- if (*ep)
- {
- builtin_error ("%s: invalid number", garglist->word->word);
- /* Same thing about POSIX.2 conversion error requirements as getlong(). */
- ret = 0;
- conversion_error = 1;
- }
- else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
-
- garglist = garglist->next;
- return (ret);
-}
-
-#endif /* HAVE_LONG_LONG */
-
static intmax_t
getintmax ()
{
@@ -922,7 +763,7 @@ getintmax ()
if (*ep)
{
- builtin_error ("%s: invalid number", garglist->word->word);
+ sh_invalidnum (garglist->word->word);
/* POSIX.2 says ``...a diagnostic message shall be written to standard
error, and the utility shall not exit with a zero exit status, but
shall continue processing any remaining operands and shall write the
@@ -932,7 +773,7 @@ getintmax ()
conversion_error = 1;
}
else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+ printf_erange (garglist->word->word);
garglist = garglist->next;
return (ret);
@@ -955,22 +796,22 @@ getuintmax ()
if (*ep)
{
- builtin_error ("%s: invalid number", garglist->word->word);
- /* Same thing about POSIX.2 conversion error requirements as getlong(). */
+ sh_invalidnum (garglist->word->word);
+ /* Same POSIX.2 conversion error requirements as getintmax(). */
ret = 0;
conversion_error = 1;
}
else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+ printf_erange (garglist->word->word);
garglist = garglist->next;
return (ret);
}
-static double
-getdouble ()
+static floatmax_t
+getfloatmax ()
{
- double ret;
+ floatmax_t ret;
char *ep;
if (garglist == 0)
@@ -980,52 +821,21 @@ getdouble ()
return asciicode ();
errno = 0;
- ret = strtod (garglist->word->word, &ep);
-
- if (*ep)
- {
- builtin_error ("%s: invalid number", garglist->word->word);
- /* Same thing about POSIX.2 conversion error requirements. */
- ret = 0;
- conversion_error = 1;
- }
- else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
-
- garglist = garglist->next;
- return (ret);
-}
-
-#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD
-static long double
-getldouble ()
-{
- long double ret;
- char *ep;
-
- if (garglist == 0)
- return (0);
-
- if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
- return (asciicode ());
-
- errno = 0;
- ret = strtold (garglist->word->word, &ep);
+ ret = strtofltmax (garglist->word->word, &ep);
if (*ep)
{
- builtin_error ("%s: invalid number", garglist->word->word);
+ sh_invalidnum (garglist->word->word);
/* Same thing about POSIX.2 conversion error requirements. */
ret = 0;
conversion_error = 1;
}
else if (errno == ERANGE)
- builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+ printf_erange (garglist->word->word);
garglist = garglist->next;
return (ret);
}
-#endif /* HAVE_LONG_DOUBLE && HAVE_DECL_STRTOLD */
/* NO check is needed for garglist here. */
static int
diff --git a/builtins/pushd.def b/builtins/pushd.def
index f47b294..2bb72ff 100644
--- a/builtins/pushd.def
+++ b/builtins/pushd.def
@@ -1,7 +1,7 @@
This file is pushd.def, from which is created pushd.c. It implements the
builtins "pushd", "popd", and "dirs" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -125,8 +125,6 @@ $END
extern int errno;
#endif /* !errno */
-static char *m_badarg = "%s: bad argument";
-
/* The list of remembered directories. */
static char **pushd_directory_list = (char **)NULL;
@@ -141,7 +139,7 @@ static void clear_directory_stack __P((void));
static int cd_to_string __P((char *));
static int change_to_temp __P((char *));
static void add_dirstack_element __P((char *));
-static int get_dirstack_index __P((long, int, int *));
+static int get_dirstack_index __P((intmax_t, int, int *));
#define NOCD 0x01
#define ROTATE 0x02
@@ -154,9 +152,12 @@ pushd_builtin (list)
{
char *temp, *current_directory, *top;
int j, flags;
- long num;
+ intmax_t num;
char direction;
+ if (list && list->word && ISOPTION (list->word->word, '-'))
+ list = list->next;
+
/* If there is no argument list then switch current and
top of list. */
if (list == 0)
@@ -197,7 +198,7 @@ pushd_builtin (list)
{
if (legal_number (list->word->word + 1, &num) == 0)
{
- builtin_error (m_badarg, list->word->word);
+ sh_invalidnum (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
}
@@ -214,7 +215,7 @@ pushd_builtin (list)
}
else if (*list->word->word == '-')
{
- bad_option (list->word->word);
+ sh_invalidopt (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
}
@@ -287,7 +288,7 @@ popd_builtin (list)
WORD_LIST *list;
{
register int i;
- long which;
+ intmax_t which;
int flags;
char direction;
char *which_word;
@@ -308,7 +309,7 @@ popd_builtin (list)
{
if (legal_number (list->word->word + 1, &which) == 0)
{
- builtin_error (m_badarg, list->word->word);
+ sh_invalidnum (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
}
@@ -316,7 +317,7 @@ popd_builtin (list)
}
else if (*list->word->word == '-')
{
- bad_option (list->word->word);
+ sh_invalidopt (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
}
@@ -364,7 +365,7 @@ dirs_builtin (list)
WORD_LIST *list;
{
int flags, desired_index, index_flag, vflag;
- long i;
+ intmax_t i;
char *temp, *w;
for (flags = vflag = index_flag = 0, desired_index = -1, w = ""; list; list = list->next)
@@ -395,7 +396,7 @@ dirs_builtin (list)
int sign;
if (legal_number (w = list->word->word + 1, &i) == 0)
{
- builtin_error (m_badarg, list->word->word);
+ sh_invalidnum (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
}
@@ -404,7 +405,7 @@ dirs_builtin (list)
}
else
{
- bad_option (list->word->word);
+ sh_invalidopt (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
}
@@ -475,10 +476,8 @@ pushd_error (offset, arg)
{
if (offset == 0)
builtin_error ("directory stack empty");
- else if (arg)
- builtin_error ("%s: bad directory stack index", arg);
else
- builtin_error ("bad directory stack index");
+ sh_erange (arg, "directory stack index");
}
static void
@@ -525,19 +524,14 @@ static void
add_dirstack_element (dir)
char *dir;
{
- int j;
-
if (directory_list_offset == directory_list_size)
- {
- j = (directory_list_size += 10) * sizeof (char *);
- pushd_directory_list = (char **)xrealloc (pushd_directory_list, j);
- }
+ pushd_directory_list = strvec_resize (pushd_directory_list, directory_list_size += 10);
pushd_directory_list[directory_list_offset++] = dir;
}
static int
get_dirstack_index (ind, sign, indexp)
- long ind;
+ intmax_t ind;
int sign, *indexp;
{
if (indexp)
@@ -565,7 +559,7 @@ get_dirstack_from_string (string)
char *string;
{
int ind, sign, index_flag;
- long i;
+ intmax_t i;
sign = 1;
if (*string == '-' || *string == '+')
@@ -589,7 +583,7 @@ get_dirstack_from_string (string)
#ifdef INCLUDE_UNUSED
char *
get_dirstack_element (ind, sign)
- long ind;
+ intmax_t ind;
int sign;
{
int i;
@@ -602,7 +596,7 @@ get_dirstack_element (ind, sign)
void
set_dirstack_element (ind, sign, value)
- long ind;
+ intmax_t ind;
int sign;
char *value;
{
diff --git a/builtins/read.def b/builtins/read.def
index a9d4a40..46a0407 100644
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -1,7 +1,7 @@
This file is read.def, from which is created read.c.
It implements the builtin "read" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,25 +23,28 @@ $PRODUCES read.c
$BUILTIN read
$FUNCTION read_builtin
-$SHORT_DOC read [-ers] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
-One line is read from the standard input, and the first word is
-assigned to the first NAME, the second word to the second NAME, and so
-on, with leftover words assigned to the last NAME. Only the characters
-found in $IFS are recognized as word delimiters. If no NAMEs are supplied,
-the line read is stored in the REPLY variable. If the -r option is given,
-this signifies `raw' input, and backslash escaping is disabled. The
--d option causes read to continue until the first character of DELIM is
-read, rather than newline. If the `-p' option is supplied, the string
-PROMPT is output without a trailing newline before attempting to read.
-If -a is supplied, the words read are assigned to sequential indices of
-ARRAY, starting at zero. If -e is supplied and the shell is interactive,
-readline is used to obtain the line. If -n is supplied with a non-zero
-NCHARS argument, read returns after NCHARS characters have been read.
-The -s option causes input coming from a terminal to not be echoed.
+$SHORT_DOC read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
+One line is read from the standard input, or from file descriptor FD if the
+-u option is supplied, and the first word is assigned to the first NAME,
+the second word to the second NAME, and so on, with leftover words assigned
+to the last NAME. Only the characters found in $IFS are recognized as word
+delimiters. If no NAMEs are supplied, the line read is stored in the REPLY
+variable. If the -r option is given, this signifies `raw' input, and
+backslash escaping is disabled. The -d option causes read to continue
+until the first character of DELIM is read, rather than newline. If the -p
+option is supplied, the string PROMPT is output without a trailing newline
+before attempting to read. If -a is supplied, the words read are assigned
+to sequential indices of ARRAY, starting at zero. If -e is supplied and
+the shell is interactive, readline is used to obtain the line. If -n is
+supplied with a non-zero NCHARS argument, read returns after NCHARS
+characters have been read. The -s option causes input coming from a
+terminal to not be echoed.
The -t option causes read to time out and return failure if a complete line
-of input is not read within TIMEOUT seconds. The return code is zero,
-unless end-of-file is encountered or read times out.
+of input is not read within TIMEOUT seconds. If the TMOUT variable is set,
+its value is the default timeout. The return code is zero, unless end-of-file
+is encountered, read times out, or an invalid file descriptor is supplied as
+the argument to -u.
$END
#include <config.h>
@@ -78,8 +81,6 @@ $END
extern int errno;
#endif
-#define issep(c) (strchr (ifs_chars, (c)))
-
extern int interrupt_immediately;
#if defined (READLINE)
@@ -123,9 +124,9 @@ read_builtin (list)
register char *varname;
int size, i, pass_next, saw_escape, eof, opt, retval, code;
int input_is_tty, input_is_pipe, unbuffered_read;
- int raw, edit, nchars, silent, have_timeout;
+ int raw, edit, nchars, silent, have_timeout, fd;
unsigned int tmout;
- long timeoutval, ncharsval;
+ intmax_t intval;
char c;
char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
char *e, *t, *t1;
@@ -162,6 +163,7 @@ read_builtin (list)
raw = edit = 0; /* Not reading raw input by default. */
silent = 0;
arrayname = prompt = (char *)NULL;
+ fd = 0; /* file descriptor to read from */
#if defined (READLINE)
rlbuf = (char *)0;
@@ -173,7 +175,7 @@ read_builtin (list)
delim = '\n'; /* read until newline */
reset_internal_getopt ();
- while ((opt = internal_getopt (list, "erp:a:d:t:n:s")) != -1)
+ while ((opt = internal_getopt (list, "ersa:d:n:p:t:u:")) != -1)
{
switch (opt)
{
@@ -197,8 +199,8 @@ read_builtin (list)
break;
#endif
case 't':
- code = legal_number (list_optarg, &timeoutval);
- if (code == 0 || timeoutval < 0 || timeoutval != (unsigned int)timeoutval)
+ code = legal_number (list_optarg, &intval);
+ if (code == 0 || intval < 0 || intval != (unsigned int)intval)
{
builtin_error ("%s: invalid timeout specification", list_optarg);
return (EXECUTION_FAILURE);
@@ -206,18 +208,33 @@ read_builtin (list)
else
{
have_timeout = 1;
- tmout = timeoutval;
+ tmout = intval;
}
break;
case 'n':
- code = legal_number (list_optarg, &ncharsval);
- if (code == 0 || ncharsval < 0 || ncharsval != (int)ncharsval)
+ code = legal_number (list_optarg, &intval);
+ if (code == 0 || intval < 0 || intval != (int)intval)
{
- builtin_error ("%s: invalid number specification", list_optarg);
+ sh_invalidnum (list_optarg);
return (EXECUTION_FAILURE);
}
else
- nchars = ncharsval;
+ nchars = intval;
+ break;
+ case 'u':
+ code = legal_number (list_optarg, &intval);
+ if (code == 0 || intval < 0 || intval != (int)intval)
+ {
+ builtin_error ("%s: invalid file descriptor specification", list_optarg);
+ return (EXECUTION_FAILURE);
+ }
+ else
+ fd = intval;
+ if (sh_validfd (fd) == 0)
+ {
+ builtin_error ("%d: invalid file descriptor: %s", fd, strerror (errno));
+ return (EXECUTION_FAILURE);
+ }
break;
case 'd':
delim = *list_optarg;
@@ -229,24 +246,32 @@ read_builtin (list)
}
list = loptend;
- /* `read -t 0 var' returns failure immediately. */
+ /* `read -t 0 var' returns failure immediately. XXX - should it test
+ whether input is available with select/FIONREAD, and fail if those
+ are unavailable? */
if (have_timeout && tmout == 0)
return (EXECUTION_FAILURE);
/* IF IFS is unset, we use the default of " \t\n". */
- var = find_variable ("IFS");
- ifs_chars = var ? value_cell (var) : " \t\n";
- if (ifs_chars == 0) /* XXX */
- ifs_chars = ""; /* XXX */
+ ifs_chars = getifs ();
+ if (ifs_chars == 0) /* XXX - shouldn't happen */
+ ifs_chars = "";
- input_string = (char *)xmalloc (size = 128);
+ input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
+
+ /* $TMOUT, if set, is the default timeout for read. */
+ if (have_timeout == 0 && (e = get_string_value ("TMOUT")))
+ {
+ code = legal_number (e, &intval);
+ if (code == 0 || intval < 0 || intval != (unsigned int)intval)
+ tmout = 0;
+ else
+ tmout = intval;
+ }
begin_unwind_frame ("read_builtin");
-#if defined (READLINE)
- add_unwind_protect (xfree, rlbuf);
-#endif
- input_is_tty = isatty (0);
+ input_is_tty = isatty (fd);
if (input_is_tty == 0)
#ifndef __CYGWIN__
input_is_pipe = (lseek (0, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
@@ -262,6 +287,11 @@ read_builtin (list)
edit = silent = 0;
}
+#if defined (READLINE)
+ if (edit)
+ add_unwind_protect (xfree, rlbuf);
+#endif
+
if (prompt && edit == 0)
{
fprintf (stderr, "%s", prompt);
@@ -275,7 +305,7 @@ read_builtin (list)
{
/* Turn off the timeout if stdin is a regular file (e.g. from
input redirection). */
- if ((fstat (0, &tsb) < 0) || S_ISREG (tsb.st_mode))
+ if ((fstat (fd, &tsb) < 0) || S_ISREG (tsb.st_mode))
tmout = 0;
}
@@ -341,7 +371,7 @@ read_builtin (list)
setmode (0, O_TEXT);
#endif
- for (eof = 0;;)
+ for (eof = retval = 0;;)
{
#if defined (READLINE)
if (edit)
@@ -368,9 +398,9 @@ read_builtin (list)
#endif
if (unbuffered_read)
- retval = zread (0, &c, 1);
+ retval = zread (fd, &c, 1);
else
- retval = zreadc (0, &c);
+ retval = zreadc (fd, &c);
if (retval <= 0)
{
@@ -425,6 +455,14 @@ read_builtin (list)
}
input_string[i] = '\0';
+#if 1
+ if (retval < 0)
+ {
+ builtin_error ("read error: %d: %s", fd, strerror (errno));
+ return (EXECUTION_FAILURE);
+ }
+#endif
+
if (tmout > 0)
reset_alarm ();
@@ -447,7 +485,7 @@ read_builtin (list)
ttrestore ();
if (unbuffered_read == 0)
- zsyncfd (0);
+ zsyncfd (fd);
interrupt_immediately--;
discard_unwind_frame ("read_builtin");
@@ -462,7 +500,7 @@ read_builtin (list)
var = find_or_make_array_variable (arrayname, 1);
if (var == 0)
return EXECUTION_FAILURE; /* readonly or noassign */
- empty_array (array_cell (var));
+ array_flush (array_cell (var));
alist = list_string (input_string, ifs_chars, 0);
if (alist)
@@ -487,7 +525,7 @@ read_builtin (list)
{
#if 0
orig_input_string = input_string;
- for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
+ for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
;
input_string = t;
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
@@ -513,7 +551,7 @@ read_builtin (list)
/* Remove IFS white space at the beginning of the input string. If
$IFS is null, no field splitting is performed. */
- for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
+ for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
;
input_string = t;
@@ -526,7 +564,7 @@ read_builtin (list)
if (legal_identifier (varname) == 0)
#endif
{
- builtin_error ("`%s': not a valid identifier", varname);
+ sh_invalidid (varname);
xfree (orig_input_string);
return (EXECUTION_FAILURE);
}
@@ -574,7 +612,7 @@ read_builtin (list)
if (legal_identifier (list->word->word) == 0)
#endif
{
- builtin_error ("`%s': not a valid identifier", list->word->word);
+ sh_invalidid (list->word->word);
xfree (orig_input_string);
return (EXECUTION_FAILURE);
}
@@ -615,6 +653,8 @@ bind_read_variable (name, value)
}
#if defined (READLINE)
+static rl_completion_func_t *old_attempted_completion_function;
+
static char *
edit_line (p)
char *p;
@@ -624,7 +664,10 @@ edit_line (p)
if (!bash_readline_initialized)
initialize_readline ();
+ old_attempted_completion_function = rl_attempted_completion_function;
+ rl_attempted_completion_function = (rl_completion_func_t *)NULL;
ret = readline (p);
+ rl_attempted_completion_function = old_attempted_completion_function;
if (ret == 0)
return ret;
len = strlen (ret);
diff --git a/builtins/reserved.def b/builtins/reserved.def
index 2897900..0f293d3 100644
--- a/builtins/reserved.def
+++ b/builtins/reserved.def
@@ -2,7 +2,7 @@ This file is reserved.def, in which the shell reserved words are defined.
It has no direct C file production, but defines builtins for the Bash
builtin help command.
-Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -28,6 +28,19 @@ assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
$END
+$BUILTIN for ((
+$DOCNAME arith_for
+$SHORT_DOC for (( exp1; exp2; exp3 )); do COMMANDS; done
+Equivalent to
+ (( EXP1 ))
+ while (( EXP2 )); do
+ COMMANDS
+ (( EXP3 ))
+ done
+EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
+omitted, it behaves as if it evaluates to 1.
+$END
+
$BUILTIN select
$SHORT_DOC select NAME [in WORDS ... ;] do COMMANDS; done
The WORDS are expanded, generating a list of words. The
@@ -40,7 +53,7 @@ to that word. If the line is empty, WORDS and the prompt are
redisplayed. If EOF is read, the command completes. Any other
value read causes NAME to be set to null. The line read is saved
in the variable REPLY. COMMANDS are executed after each selection
-until a break or return command is executed.
+until a break command is executed.
$END
$BUILTIN time
@@ -103,6 +116,31 @@ WORD, then the job whose name begins with WORD is used. Following the
job specification with a `&' places the job in the background.
$END
+$BUILTIN (( ... ))
+$DOCNAME arith
+$SHORT_DOC (( expression ))
+The EXPRESSION is evaluated according to the rules for arithmetic
+evaluation. Equivalent to "let EXPRESSION".
+$END
+
+$BUILTIN [[ ... ]]
+$DOCNAME conditional
+$SHORT_DOC [[ expression ]]
+Returns a status of 0 or 1 depending on the evaluation of the conditional
+expression EXPRESSION. Expressions are composed of the same primaries used
+by the `test' builtin, and may be combined using the following operators
+
+ ( EXPRESSION ) Returns the value of EXPRESSION
+ ! EXPRESSION True if EXPRESSION is false; else false
+ EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false
+ EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false
+
+When the `==' and `!=' operators are used, the string to the right of the
+operator is used as a pattern and pattern matching is performed. The
+&& and || operators do not evaluate EXPR2 if EXPR1 is sufficient to
+determine the expression's value.
+$END
+
$BUILTIN variables
$DOCNAME variable_help
$SHORT_DOC variables - Some variable names and meanings
diff --git a/builtins/return.def b/builtins/return.def
index 529e04c..84a90a3 100644
--- a/builtins/return.def
+++ b/builtins/return.def
@@ -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, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -52,7 +52,7 @@ int
return_builtin (list)
WORD_LIST *list;
{
- return_catch_value = list ? get_exitstat (list) : last_command_exit_value;
+ return_catch_value = get_exitstat (list);
if (return_catch_flag)
longjmp (return_catch, 1);
diff --git a/builtins/set.def b/builtins/set.def
index 8f96017..10aaf5f 100644
--- a/builtins/set.def
+++ b/builtins/set.def
@@ -1,7 +1,7 @@
This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -49,7 +49,7 @@ $PRODUCES set.c
# include "../bashhist.h"
#endif
-extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit;
+extern int posixly_correct, ignoreeof, eof_encountered_limit;
#if defined (HISTORY)
extern int dont_save_function_defs;
#endif
@@ -65,8 +65,6 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
-e Exit immediately if a command exits with a non-zero status.
-f Disable file name generation (globbing).
-h Remember the location of commands as they are looked up.
- -i Force the shell to be an "interactive" one. Interactive shells
- always read `~/.bashrc' on startup.
-k All assignment arguments are placed in the environment for a
command, not just those that precede the command name.
-m Job control is enabled.
@@ -135,6 +133,9 @@ parameters and are assigned, in order, to $1, $2, .. $n. If no
ARGs are given, all shell variables are printed.
$END
+typedef int setopt_set_func_t __P((int, char *));
+typedef int setopt_get_func_t __P((char *));
+
static void print_minus_o_option __P((char *, int, int));
static void print_all_shell_variables __P((void));
@@ -153,70 +154,66 @@ static int bash_set_history __P((int, char *));
static char *on = "on";
static char *off = "off";
-/* An a-list used to match long options for set -o to the corresponding
- option letter. */
+/* A struct used to match long options for set -o to the corresponding
+ option letter or internal variable. The functions can be called to
+ dynamically generate values. */
struct {
char *name;
int letter;
+ int *variable;
+ setopt_set_func_t *set_func;
+ setopt_get_func_t *get_func;
} o_options[] = {
- { "allexport", 'a' },
+ { "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (BRACE_EXPANSION)
- { "braceexpand",'B' },
+ { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif
- { "errexit", 'e' },
- { "hashall", 'h' },
+#if defined (READLINE)
+ { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
+#endif
+ { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (BANG_HISTORY)
- { "histexpand", 'H' },
+ { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif /* BANG_HISTORY */
- { "keyword", 'k' },
- { "monitor", 'm' },
- { "noclobber", 'C' },
- { "noexec", 'n' },
- { "noglob", 'f' },
-#if defined (JOB_CONTROL)
- { "notify", 'b' },
-#endif /* JOB_CONTROL */
- { "nounset", 'u' },
- { "onecmd", 't' },
- { "physical", 'P' },
- { "privileged", 'p' },
- { "verbose", 'v' },
- { "xtrace", 'x' },
- {(char *)NULL, 0 },
-};
-
-typedef int setopt_set_func_t __P((int, char *));
-typedef int setopt_get_func_t __P((char *));
-
-struct {
- char *name;
- int *variable;
- setopt_set_func_t *set_func;
- setopt_get_func_t *get_func;
-} binary_o_options[] = {
#if defined (HISTORY)
- { "history", &remember_on_history, bash_set_history, (setopt_get_func_t *)NULL },
+ { "history", '\0', &remember_on_history, bash_set_history, (setopt_get_func_t *)NULL },
#endif
- { "ignoreeof", &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
- { "interactive-comments", &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
+ { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (HISTORY)
- { "nolog", &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif
- { "posix", &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
+#if defined (JOB_CONTROL)
+ { "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+#endif /* JOB_CONTROL */
+ { "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
+ { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ { "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (READLINE)
- { "emacs", (int *)NULL, set_edit_mode, get_edit_mode },
- { "vi", (int *)NULL, set_edit_mode, get_edit_mode },
+ { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
#endif
- { (char *)NULL, (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }
+ { "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+ {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
};
+#define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0]))
+
#define GET_BINARY_O_OPTION_VALUE(i, name) \
- ((binary_o_options[i].get_func) ? (*binary_o_options[i].get_func) (name) \
- : (*binary_o_options[i].variable))
+ ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \
+ : (*o_options[i].variable))
#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
- ((binary_o_options[i].set_func) ? (*binary_o_options[i].set_func) (onoff, name) \
- : (*binary_o_options[i].variable = (onoff == FLAG_ON)))
+ ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \
+ : (*o_options[i].variable = (onoff == FLAG_ON)))
int
minus_o_option_value (name)
@@ -229,15 +226,15 @@ minus_o_option_value (name)
{
if (STREQ (name, o_options[i].name))
{
- on_or_off = find_flag (o_options[i].letter);
- return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
+ if (o_options[i].letter)
+ {
+ on_or_off = find_flag (o_options[i].letter);
+ return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
+ }
+ else
+ return (GET_BINARY_O_OPTION_VALUE (i, name));
}
}
- for (i = 0; binary_o_options[i].name; i++)
- {
- if (STREQ (name, binary_o_options[i].name))
- return (GET_BINARY_O_OPTION_VALUE (i, name));
- }
return (-1);
}
@@ -262,19 +259,23 @@ list_minus_o_opts (mode, reusable)
register int i;
int *on_or_off, value;
- for (value = i = 0; o_options[i].name; i++)
- {
- on_or_off = find_flag (o_options[i].letter);
- if (on_or_off == FLAG_UNKNOWN)
- on_or_off = &value;
- if (mode == -1 || mode == *on_or_off)
- print_minus_o_option (o_options[i].name, *on_or_off, reusable);
- }
- for (i = 0; binary_o_options[i].name; i++)
+ for (i = 0; o_options[i].name; i++)
{
- value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
- if (mode == -1 || mode == value)
- print_minus_o_option (binary_o_options[i].name, value, reusable);
+ if (o_options[i].letter)
+ {
+ value = 0;
+ on_or_off = find_flag (o_options[i].letter);
+ if (on_or_off == FLAG_UNKNOWN)
+ on_or_off = &value;
+ if (mode == -1 || mode == *on_or_off)
+ print_minus_o_option (o_options[i].name, *on_or_off, reusable);
+ }
+ else
+ {
+ value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
+ if (mode == -1 || mode == value)
+ print_minus_o_option (o_options[i].name, value, reusable);
+ }
}
}
@@ -282,16 +283,12 @@ char **
get_minus_o_opts ()
{
char **ret;
- int n, i, ind;
-
- n = (sizeof (o_options) / sizeof (o_options[0])) +
- (sizeof (binary_o_options) / sizeof (binary_o_options[0]));
- ret = alloc_array (n + 1);
- for (i = ind = 0; o_options[i].name; i++)
- ret[ind++] = o_options[i].name;
- for (i = 0; binary_o_options[i].name; i++)
- ret[ind++] = binary_o_options[i].name;
- ret[ind] = (char *)NULL;
+ int i;
+
+ ret = strvec_create (N_O_OPTIONS + 1);
+ for (i = 0; o_options[i].name; i++)
+ ret[i] = o_options[i].name;
+ ret[i] = (char *)NULL;
return ret;
}
@@ -386,37 +383,33 @@ set_minus_o_option (on_or_off, option_name)
int on_or_off;
char *option_name;
{
- int option_char;
register int i;
- for (i = 0; binary_o_options[i].name; i++)
- {
- if (STREQ (option_name, binary_o_options[i].name))
- {
- SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
- return (EXECUTION_SUCCESS);
- }
- }
-
- for (i = 0, option_char = -1; o_options[i].name; i++)
+ for (i = 0; o_options[i].name; i++)
{
if (STREQ (option_name, o_options[i].name))
{
- option_char = o_options[i].letter;
- break;
+ if (o_options[i].letter == 0)
+ {
+ SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
+ return (EXECUTION_SUCCESS);
+ }
+ else
+ {
+ if (change_flag (o_options[i].letter, on_or_off) == FLAG_ERROR)
+ {
+ sh_invalidoptname (option_name);
+ return (EXECUTION_FAILURE);
+ }
+ else
+ return (EXECUTION_SUCCESS);
+ }
+
}
}
- if (option_char == -1)
- {
- builtin_error ("%s: unknown option name", option_name);
- return (EXECUTION_FAILURE);
- }
- if (change_flag (option_char, on_or_off) == FLAG_ERROR)
- {
- bad_option (option_name);
- return (EXECUTION_FAILURE);
- }
- return (EXECUTION_SUCCESS);
+
+ sh_invalidoptname (option_name);
+ return (EXECUTION_FAILURE);
}
static void
@@ -448,38 +441,41 @@ void
set_shellopts ()
{
char *value;
+ char tflag[N_O_OPTIONS];
int vsize, i, vptr, *ip, exported;
SHELL_VAR *v;
for (vsize = i = 0; o_options[i].name; i++)
{
- ip = find_flag (o_options[i].letter);
- if (ip && *ip)
- vsize += strlen (o_options[i].name) + 1;
+ tflag[i] = 0;
+ if (o_options[i].letter)
+ {
+ ip = find_flag (o_options[i].letter);
+ if (ip && *ip)
+ {
+ vsize += strlen (o_options[i].name) + 1;
+ tflag[i] = 1;
+ }
+ }
+ else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name))
+ {
+ vsize += strlen (o_options[i].name) + 1;
+ tflag[i] = 1;
+ }
}
- for (i = 0; binary_o_options[i].name; i++)
- if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
- vsize += strlen (binary_o_options[i].name) + 1;
value = (char *)xmalloc (vsize + 1);
for (i = vptr = 0; o_options[i].name; i++)
{
- ip = find_flag (o_options[i].letter);
- if (ip && *ip)
+ if (tflag[i])
{
strcpy (value + vptr, o_options[i].name);
vptr += strlen (o_options[i].name);
value[vptr++] = ':';
}
}
- for (i = 0; binary_o_options[i].name; i++)
- if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
- {
- strcpy (value + vptr, binary_o_options[i].name);
- vptr += strlen (binary_o_options[i].name);
- value[vptr++] = ':';
- }
+
if (vptr)
vptr--; /* cut off trailing colon */
value[vptr] = '\0';
@@ -571,6 +567,7 @@ set_builtin (list)
int on_or_off, flag_name, force_assignment, opts_changed;
WORD_LIST *l;
register char *arg;
+ char s[3];
if (list == 0)
{
@@ -579,34 +576,19 @@ set_builtin (list)
}
/* Check validity of flag arguments. */
- if (*list->word->word == '-' || *list->word->word == '+')
+ reset_internal_getopt ();
+ while ((flag_name = internal_getopt (list, optflags)) != -1)
{
- for (l = list; l && (arg = l->word->word); l = l->next)
+ switch (flag_name)
{
- char c;
-
- if (arg[0] != '-' && arg[0] != '+')
+ case '?':
+ builtin_usage ();
+ return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
+ default:
break;
-
- /* `-' or `--' signifies end of flag arguments. */
- if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
- break;
-
- while (c = *++arg)
- {
- if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
- {
- char s[2];
- s[0] = c; s[1] = '\0';
- bad_option (s);
- if (c == '?')
- builtin_usage ();
- return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
- }
- }
}
}
-
+
/* Do the set command. While the list consists of words starting with
'-' or '+' treat them as flags, otherwise, start assigning them to
$1 ... $n. */
@@ -678,11 +660,10 @@ set_builtin (list)
}
else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
{
- char opt[3];
- opt[0] = on_or_off;
- opt[1] = flag_name;
- opt[2] = '\0';
- bad_option (opt);
+ s[0] = on_or_off;
+ s[1] = flag_name;
+ s[2] = '\0';
+ sh_invalidopt (s);
builtin_usage ();
set_shellopts ();
return (EXECUTION_FAILURE);
@@ -777,7 +758,7 @@ unset_builtin (list)
mode when unsetting a function. */
if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
{
- builtin_error ("`%s': not a valid identifier", name);
+ sh_invalidid (name);
NEXT_VARIABLE ();
}
@@ -807,22 +788,27 @@ unset_builtin (list)
NEXT_VARIABLE ();
}
else
- tem = unbind_array_element (var, t);
+ {
+ tem = unbind_array_element (var, t);
+ if (tem == -1)
+ any_failed++;
+ }
}
else
#endif /* ARRAY_VARS */
- tem = makunbound (name, unset_function ? shell_functions : shell_variables);
+ tem = unset_function ? unbind_func (name) : unbind_variable (name);
/* This is what Posix.2 draft 11+ 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.'' */
if (tem == -1 && !unset_function && !unset_variable)
- tem = makunbound (name, shell_functions);
+ tem = unbind_func (name);
+
+ /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
+ was not previously set shall not be considered an error.'' */
- if (tem == -1)
- any_failed++;
- else if (!unset_function)
+ if (unset_function == 0)
stupidly_hack_special_variables (name);
list = list->next;
diff --git a/builtins/setattr.def b/builtins/setattr.def
index dad11fd..8465e7d 100644
--- a/builtins/setattr.def
+++ b/builtins/setattr.def
@@ -1,7 +1,7 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -43,7 +43,7 @@ extern char *this_command_name;
extern sh_builtin_func_t *this_shell_builtin;
#ifdef ARRAY_VARS
-extern int declare_builtin ();
+extern int declare_builtin __P((WORD_LIST *));
#endif
#define READONLY_OR_EXPORT \
@@ -51,7 +51,7 @@ extern int declare_builtin ();
$BUILTIN export
$FUNCTION export_builtin
-$SHORT_DOC export [-nf] [name ...] or export -p
+$SHORT_DOC export [-nf] [name[=value] ...] or export -p
NAMEs are marked for automatic export to the environment of
subsequently executed commands. If the -f option is given,
the NAMEs refer to functions. If no NAMEs are given, or if `-p'
@@ -75,7 +75,7 @@ export_builtin (list)
$BUILTIN readonly
$FUNCTION readonly_builtin
-$SHORT_DOC readonly [-anf] [name ...] or readonly -p
+$SHORT_DOC readonly [-anf] [name[=value] ...] or readonly -p
The given NAMEs are marked readonly and the values of these NAMEs may
not be changed by subsequent assignment. If the -f option is given,
then functions corresponding to the NAMEs are so marked. If no
@@ -95,6 +95,12 @@ readonly_builtin (list)
return (set_or_show_attributes (list, att_readonly, 0));
}
+#if defined (ARRAY_VARS)
+# define ATTROPTS "afnp"
+#else
+# define ATTROPTS "fnp"
+#endif
+
/* For each variable name in LIST, make that variable have the specified
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
remaining names in LIST. */
@@ -114,7 +120,7 @@ set_or_show_attributes (list, attribute, nodefs)
undo = functions_only = arrays_only = any_failed = assign_error = 0;
/* Read arguments from the front of the list. */
reset_internal_getopt ();
- while ((opt = internal_getopt (list, "anfp")) != -1)
+ while ((opt = internal_getopt (list, ATTROPTS)) != -1)
{
switch (opt)
{
@@ -174,7 +180,7 @@ set_or_show_attributes (list, attribute, nodefs)
if (legal_identifier (name) == 0)
{
- builtin_error ("`%s': not a valid identifier", name);
+ sh_invalidid (name);
if (assign)
assign_error++;
else
@@ -248,11 +254,7 @@ set_or_show_attributes (list, attribute, nodefs)
if (arrays_only && array_p (var) == 0)
continue;
#endif
-#if 0
- if ((var->attributes & attribute) && invisible_p (var) == 0)
-#else
if ((var->attributes & attribute))
-#endif
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
}
free (variable_list);
@@ -275,7 +277,7 @@ show_var_attributes (var, pattr, nodefs)
SHELL_VAR *var;
int pattr, nodefs;
{
- char flags[6], *x;
+ char flags[8], *x;
int i;
i = 0;
@@ -297,6 +299,9 @@ show_var_attributes (var, pattr, nodefs)
if (readonly_p (var))
flags[i++] = 'r';
+ if (trace_p (var))
+ flags[i++] = 't';
+
if (exported_p (var))
flags[i++] = 'x';
}
@@ -313,6 +318,17 @@ show_var_attributes (var, pattr, nodefs)
flags[i] = '\0';
+ /* If we're printing functions with definitions, print the function def
+ first, then the attributes, instead of printing output that can't be
+ reused as input to recreate the current state. */
+ if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
+ {
+ printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
+ nodefs++;
+ if (pattr == 0 && i == 1 && flags[0] == 'f')
+ return 0; /* don't print `declare -f name' */
+ }
+
if (pattr == 0 || posixly_correct == 0)
printf ("declare -%s ", i ? flags : "-");
else if (i)
@@ -325,7 +341,7 @@ show_var_attributes (var, pattr, nodefs)
print_array_assignment (var, 1);
else
#endif
- /* force `readline' and `export' to not print out function definitions
+ /* force `readonly' and `export' to not print out function definitions
when in POSIX mode. */
if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
printf ("%s\n", var->name);
@@ -335,7 +351,7 @@ show_var_attributes (var, pattr, nodefs)
printf ("%s\n", var->name);
else
{
- x = sh_double_quote (value_cell (var) ? value_cell (var) : "");
+ x = sh_double_quote (var_isset (var) ? value_cell (var) : "");
printf ("%s=%s\n", var->name, x);
free (x);
}
@@ -349,15 +365,11 @@ show_name_attributes (name, nodefs)
{
SHELL_VAR *var;
- var = find_tempenv_variable (name);
- if (var == 0)
- var = find_variable (name);
+ var = find_variable_internal (name, 1);
if (var && invisible_p (var) == 0)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
- if (tempvar_p (var))
- dispose_variable (var);
return (0);
}
else
@@ -370,23 +382,39 @@ set_var_attribute (name, attribute, undo)
int attribute, undo;
{
SHELL_VAR *var, *tv;
+ char *tvalue;
if (undo)
var = find_variable (name);
else
{
- if (tv = find_tempenv_variable (name))
+ 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))
{
- var = bind_variable (tv->name, tv->value ? tv->value : "");
- dispose_variable (tv);
+ tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
+
+ var = bind_variable (tv->name, tvalue);
+ var->attributes |= tv->attributes & ~att_tempvar;
+ VSETATTR (tv, att_propagate);
+ if (var->context != 0)
+ VSETATTR (var, att_propagate);
+ SETVARATTR (tv, attribute, undo); /* XXX */
+
+ free (tvalue);
}
else
- var = find_variable (name);
-
- if (var == 0)
{
- var = bind_variable (name, (char *)NULL);
- VSETATTR (var, att_invisible);
+ var = find_variable_internal (name, 0);
+ if (var == 0)
+ {
+ var = bind_variable (name, (char *)NULL);
+ VSETATTR (var, att_invisible);
+ }
+ else if (var->context != 0)
+ VSETATTR (var, att_propagate);
}
}
diff --git a/builtins/shift.def b/builtins/shift.def
index 6db7c7f..dbff062 100644
--- a/builtins/shift.def
+++ b/builtins/shift.def
@@ -1,7 +1,7 @@
This file is shift.def, from which is created shift.c.
It implements the builtin "shift" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -52,7 +52,7 @@ int
shift_builtin (list)
WORD_LIST *list;
{
- long times;
+ intmax_t times;
register int count;
WORD_LIST *temp;
@@ -62,13 +62,13 @@ shift_builtin (list)
return (EXECUTION_SUCCESS);
else if (times < 0)
{
- builtin_error ("shift count must be >= 0");
+ sh_erange (list->word->word, "shift count");
return (EXECUTION_FAILURE);
}
else if (times > number_of_args ())
{
if (print_shift_error)
- builtin_error ("shift count must be <= $#");
+ sh_erange (list->word->word, "shift count");
return (EXECUTION_FAILURE);
}
diff --git a/builtins/shopt.def b/builtins/shopt.def
index 8de2aad..ae15330 100644
--- a/builtins/shopt.def
+++ b/builtins/shopt.def
@@ -1,7 +1,7 @@
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
-Copyright (C) 1994 Free Software Foundation, Inc.
+Copyright (C) 1994-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,7 +22,6 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
$PRODUCES shopt.c
$BUILTIN shopt
-$DOCNAME shopt_builtin
$FUNCTION shopt_builtin
$SHORT_DOC shopt [-pqsu] [-o long-option] optname [optname...]
Toggle the values of variables controlling optional behavior.
@@ -59,7 +58,7 @@ $END
extern int allow_null_glob_expansion, glob_dot_filenames;
extern int cdable_vars, mail_warning, source_uses_path;
extern int no_exit_on_failed_exec, print_shift_error;
-extern int check_hashed_filenames, promptvars, interactive_comments;
+extern int check_hashed_filenames, promptvars;
extern int cdspelling, expand_aliases;
extern int check_window_size;
extern int glob_ignore_case;
@@ -86,10 +85,11 @@ extern int prog_completion_enabled;
#endif
#if defined (RESTRICTED_SHELL)
-extern int restricted_shell;
extern char *shell_name;
#endif
+static void shopt_error __P((char *));
+
static int set_interactive_comments __P((int));
#if defined (RESTRICTED_SHELL)
@@ -268,7 +268,12 @@ find_shopt (name)
return -1;
}
-#define SHOPT_ERROR(str) builtin_error ("%s: unknown shell option name", str)
+static void
+shopt_error (s)
+ char *s;
+{
+ builtin_error ("%s: invalid shell option name", s);
+}
static int
toggle_shopts (mode, list, quiet)
@@ -284,7 +289,7 @@ toggle_shopts (mode, list, quiet)
ind = find_shopt (l->word->word);
if (ind < 0)
{
- SHOPT_ERROR (l->word->word);
+ shopt_error (l->word->word);
rval = EXECUTION_FAILURE;
}
else
@@ -334,7 +339,7 @@ list_shopts (list, flags)
i = find_shopt (l->word->word);
if (i < 0)
{
- SHOPT_ERROR (l->word->word);
+ shopt_error (l->word->word);
rval = EXECUTION_FAILURE;
continue;
}
@@ -383,7 +388,7 @@ list_shopt_o_options (list, flags)
val = minus_o_option_value (l->word->word);
if (val == -1)
{
- builtin_error ("%s: unknown option name", l->word->word);
+ sh_invalidoptname (l->word->word);
rval = EXECUTION_FAILURE;
continue;
}
@@ -470,7 +475,7 @@ get_shopt_options ()
int n, i;
n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
- ret = alloc_array (n + 1);
+ ret = strvec_create (n + 1);
for (i = 0; shopt_vars[i].name; i++)
ret[i] = savestring (shopt_vars[i].name);
ret[i] = (char *)NULL;
@@ -509,7 +514,7 @@ shopt_listopt (name, reusable)
i = find_shopt (name);
if (i < 0)
{
- SHOPT_ERROR (name);
+ shopt_error (name);
return (EXECUTION_FAILURE);
}
diff --git a/builtins/source.def b/builtins/source.def
index f9086f8..ffb23f0 100644
--- a/builtins/source.def
+++ b/builtins/source.def
@@ -1,7 +1,7 @@
This file is source.def, from which is created source.c.
It implements the builtins "." and "source" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -55,6 +55,7 @@ $END
#include "../shell.h"
#include "../findcmd.h"
#include "common.h"
+#include "bashgetopt.h"
#if !defined (errno)
extern int errno;
@@ -80,13 +81,11 @@ int source_searches_cwd = 1;
static void
maybe_pop_dollar_vars ()
{
- if (variable_context == 0 && dollar_vars_changed ())
- {
- dispose_saved_dollar_vars ();
- set_dollar_vars_unchanged ();
- }
+ if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
+ dispose_saved_dollar_vars ();
else
pop_dollar_vars ();
+ set_dollar_vars_unchanged ();
}
/* Read and execute commands from the file passed as argument. Guess what.
@@ -100,6 +99,10 @@ source_builtin (list)
int result;
char *filename;
+ if (no_options (list))
+ return (EX_USAGE);
+ list = loptend;
+
if (list == 0)
{
builtin_error ("filename argument required");
@@ -107,13 +110,10 @@ source_builtin (list)
return (EX_USAGE);
}
- if (no_options (list))
- return (EX_USAGE);
-
#if defined (RESTRICTED_SHELL)
if (restricted && strchr (list->word->word, '/'))
{
- builtin_error ("%s: restricted", list->word->word);
+ sh_restricted (list->word->word);
return (EXECUTION_FAILURE);
}
#endif
diff --git a/builtins/suspend.def b/builtins/suspend.def
index c1dc6d1..43391c0 100644
--- a/builtins/suspend.def
+++ b/builtins/suspend.def
@@ -1,7 +1,7 @@
This file is suspend.def, from which is created suspend.c.
It implements the builtin "suspend" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -89,7 +89,7 @@ suspend_builtin (list)
if (job_control == 0)
{
- builtin_error ("cannot suspend a shell without job control");
+ sh_nojobs ("cannot suspend");
return (EXECUTION_FAILURE);
}
diff --git a/builtins/test.def b/builtins/test.def
index d328876..e51d00b 100644
--- a/builtins/test.def
+++ b/builtins/test.def
@@ -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, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -24,7 +24,7 @@ $PRODUCES test.c
$BUILTIN test
$FUNCTION test_builtin
$SHORT_DOC test [expr]
-Exits with a status of 0 (trueness) or 1 (falseness) depending on
+Exits with a status of 0 (true) or 1 (false) depending on
the evaluation of EXPR. Expressions may be unary or binary. Unary
expressions are often used to examine the status of a file. There
are string operators as well, and numeric comparison operators.
diff --git a/builtins/times.def b/builtins/times.def
index 4dba724..22304fc 100644
--- a/builtins/times.def
+++ b/builtins/times.def
@@ -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, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -61,6 +61,11 @@ times_builtin (list)
#if defined (HAVE_GETRUSAGE) && defined (HAVE_TIMEVAL) && defined (RUSAGE_SELF)
struct rusage self, kids;
+ USE_VAR(list);
+
+ if (no_options (list))
+ return (EX_USAGE);
+
getrusage (RUSAGE_SELF, &self);
getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */
@@ -79,6 +84,11 @@ times_builtin (list)
`struct tms' with values of type clock_t. */
struct tms t;
+ USE_VAR(list);
+
+ if (no_options (list))
+ return (EX_USAGE);
+
times (&t);
print_clock_t (stdout, t.tms_utime);
@@ -89,8 +99,15 @@ times_builtin (list)
putchar (' ');
print_clock_t (stdout, t.tms_cstime);
putchar ('\n');
+
# else /* !HAVE_TIMES */
+
+ USE_VAR(list);
+
+ if (no_options (list))
+ return (EX_USAGE);
printf ("0.00 0.00\n0.00 0.00\n");
+
# endif /* HAVE_TIMES */
#endif /* !HAVE_TIMES */
diff --git a/builtins/trap.def b/builtins/trap.def
index 933bd25..af9e6d6 100644
--- a/builtins/trap.def
+++ b/builtins/trap.def
@@ -1,7 +1,7 @@
This file is trap.def, from which is created trap.c.
It implements the builtin "trap" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -137,8 +137,7 @@ trap_builtin (list)
if (sig == NO_SIG)
{
- builtin_error ("%s: not a signal specification",
- list->word->word);
+ sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
}
else
@@ -239,8 +238,8 @@ display_traps (list)
i = decode_signal (list->word->word);
if (i == NO_SIG)
{
+ sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
- builtin_error ("%s: not a signal specification", list->word->word);
}
else
showtrap (i);
diff --git a/builtins/type.def b/builtins/type.def
index 9510a0e..2d9d2a5 100644
--- a/builtins/type.def
+++ b/builtins/type.def
@@ -1,7 +1,7 @@
This file is type.def, from which is created type.c.
It implements the builtin "type" in Bash.
-Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,7 +23,7 @@ $PRODUCES type.c
$BUILTIN type
$FUNCTION type_builtin
-$SHORT_DOC type [-apt] name [name ...]
+$SHORT_DOC type [-afptP] name [name ...]
For each NAME, indicate how it would be interpreted if used as a
command name.
@@ -37,8 +37,14 @@ file that would be executed, or nothing if `type -t NAME' would not
return `file'.
If the -a flag is used, `type' displays all of the places that contain
-an executable named `file'. This includes aliases and functions, if
-and only if the -p flag is not also used.
+an executable named `file'. This includes aliases, builtins, and
+functions, if and only if the -p flag is not also used.
+
+The -f flag suppresses shell function lookup.
+
+The -P flag forces a PATH search for each NAME, even if it is an alias,
+builtin, or function, and returns the name of the disk file that would
+be executed.
$END
#include <config.h>
@@ -82,6 +88,12 @@ extern char *this_command_name;
-a Returns all occurrences of words, whether they
be a filename in the path, alias, function,
or builtin.
+
+ -f Suppress shell function lookup, like `command'.
+
+ -P Force a path search even in the presence of other
+ definitions.
+
Order of evaluation:
alias
keyword
@@ -94,72 +106,62 @@ int
type_builtin (list)
WORD_LIST *list;
{
- int path_only, type_only, all, verbose;
- int successful_finds, opt;
- WORD_LIST *prev, *this;
+ int dflags, successful_finds, opt;
+ WORD_LIST *this;
if (list == 0)
return (EXECUTION_SUCCESS);
- path_only = type_only = all = 0;
+ dflags = CDESC_SHORTDESC; /* default */
successful_finds = 0;
/* Handle the obsolescent `-type', `-path', and `-all' by prescanning
- the arguments and removing those options from the list before calling
- internal_getopt. Recognize `--type', `--path', and `--all' also.
- THIS SHOULD REALLY GO AWAY. */
- for (this = list; this && this->word->word[0] == '-'; )
+ the arguments and converting those options to the form that
+ internal_getopt recognizes. Converts `--type', `--path', and `--all'
+ also. THIS SHOULD REALLY GO AWAY. */
+ for (this = list; this && this->word->word[0] == '-'; this = this->next)
{
char *flag = &(this->word->word[1]);
if (STREQ (flag, "type") || STREQ (flag, "-type"))
{
- type_only = 1;
- path_only = 0;
+ this->word->word[1] = 't';
+ this->word->word[2] = '\0';
}
else if (STREQ (flag, "path") || STREQ (flag, "-path"))
{
- path_only = 1;
- type_only = 0;
+ this->word->word[1] = 'p';
+ this->word->word[2] = '\0';
}
else if (STREQ (flag, "all") || STREQ (flag, "-all"))
- all = 1;
- else
- {
- prev = this;
- this = this->next;
- continue;
- }
-
- /* We found a long option; remove it from the argument list. Don't
- free it if it's the head of the argument list, though -- the
- argument list will be freed by the caller. */
- if (this == list)
- this = list = list->next;
- else
{
- prev->next = this->next;
- this->next = (WORD_LIST *)NULL;
- dispose_words (this);
- this = prev->next;
+ this->word->word[1] = 'a';
+ this->word->word[2] = '\0';
}
}
reset_internal_getopt ();
- while ((opt = internal_getopt (list, "apt")) != -1)
+ while ((opt = internal_getopt (list, "afptP")) != -1)
{
switch (opt)
{
- case 't':
- type_only = 1;
- path_only = 0;
+ case 'a':
+ dflags |= CDESC_ALL;
+ break;
+ case 'f':
+ dflags |= CDESC_NOFUNCS;
break;
case 'p':
- path_only = 1;
- type_only = 0;
+ dflags |= CDESC_PATH_ONLY;
+ dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC);
break;
- case 'a':
- all = 1;
+ case 't':
+ dflags |= CDESC_TYPE;
+ dflags &= ~(CDESC_PATH_ONLY|CDESC_SHORTDESC);
+ break;
+ case 'P': /* shorthand for type -ap */
+ dflags |= (CDESC_PATH_ONLY|CDESC_FORCE_PATH);
+ dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC);
break;
default:
builtin_usage ();
@@ -168,23 +170,14 @@ type_builtin (list)
}
list = loptend;
- if (type_only)
- verbose = 1;
- else if (path_only == 0)
- verbose = 2;
- else if (path_only)
- verbose = 3;
- else
- verbose = 0;
-
while (list)
{
int found;
- found = describe_command (list->word->word, verbose, all);
+ found = describe_command (list->word->word, dflags);
- if (!found && !path_only && !type_only)
- builtin_error ("%s: not found", list->word->word);
+ if (!found && (dflags & (CDESC_PATH_ONLY|CDESC_TYPE)) == 0)
+ sh_notfound (list->word->word);
successful_finds += found;
list = list->next;
@@ -196,43 +189,45 @@ type_builtin (list)
}
/*
- * Describe COMMAND as required by the type builtin.
+ * Describe COMMAND as required by the type and command builtins.
*
- * If VERBOSE == 0, don't print anything
- * If VERBOSE == 1, print short description as for `type -t'
- * If VERBOSE == 2, print long description as for `type' and `command -V'
- * If VERBOSE == 3, print path name only for disk files
- * If VERBOSE == 4, print string used to invoke COMMAND, for `command -v'
+ * Behavior is controlled by DFLAGS. Flag values are
+ * CDESC_ALL print all descriptions of a command
+ * CDESC_SHORTDESC print the description for type and command -V
+ * CDESC_REUSABLE print in a format that may be reused as input
+ * CDESC_TYPE print the type for type -t
+ * CDESC_PATH_ONLY print the path for type -p
+ * CDESC_FORCE_PATH force a path search for type -P
+ * CDESC_NOFUNCS skip function lookup for type -f
*
- * ALL says whether or not to look for all occurrences of COMMAND, or
+ * CDESC_ALL says whether or not to look for all occurrences of COMMAND, or
* return after finding it once.
*/
int
-describe_command (command, verbose, all)
+describe_command (command, dflags)
char *command;
- int verbose, all;
+ int dflags;
{
- int found, i, found_file, f;
+ int found, i, found_file, f, all;
char *full_path, *x;
SHELL_VAR *func;
#if defined (ALIAS)
alias_t *alias;
#endif
+ all = (dflags & CDESC_ALL) != 0;
found = found_file = 0;
full_path = (char *)NULL;
#if defined (ALIAS)
/* Command is an alias? */
- alias = find_alias (command);
-
- if (alias)
+ if (((dflags & CDESC_FORCE_PATH) == 0) && (alias = find_alias (command)))
{
- if (verbose == 1)
+ if (dflags & CDESC_TYPE)
puts ("alias");
- else if (verbose == 2)
+ else if (dflags & CDESC_SHORTDESC)
printf ("%s is aliased to `%s'\n", command, alias->value);
- else if (verbose == 4)
+ else if (dflags & CDESC_REUSABLE)
{
x = sh_single_quote (alias->value);
printf ("alias %s=%s\n", command, x);
@@ -247,14 +242,13 @@ describe_command (command, verbose, all)
#endif /* ALIAS */
/* Command is a shell reserved word? */
- i = find_reserved_word (command);
- if (i >= 0)
+ if (((dflags & CDESC_FORCE_PATH) == 0) && (i = find_reserved_word (command)) >= 0)
{
- if (verbose == 1)
+ if (dflags & CDESC_TYPE)
puts ("keyword");
- else if (verbose == 2)
+ else if (dflags & CDESC_SHORTDESC)
printf ("%s is a shell keyword\n", command);
- else if (verbose == 4)
+ else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
found = 1;
@@ -264,13 +258,11 @@ describe_command (command, verbose, all)
}
/* Command is a function? */
- func = find_function (command);
-
- if (func)
+ if (((dflags & (CDESC_FORCE_PATH|CDESC_NOFUNCS)) == 0) && (func = find_function (command)))
{
- if (verbose == 1)
+ if (dflags & CDESC_TYPE)
puts ("function");
- else if (verbose == 2)
+ else if (dflags & CDESC_SHORTDESC)
{
#define PRETTY_PRINT_FUNC 1
char *result;
@@ -285,7 +277,7 @@ describe_command (command, verbose, all)
printf ("%s\n", result);
#undef PRETTY_PRINT_FUNC
}
- else if (verbose == 4)
+ else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
found = 1;
@@ -295,13 +287,13 @@ describe_command (command, verbose, all)
}
/* Command is a builtin? */
- if (find_shell_builtin (command))
+ if (((dflags & CDESC_FORCE_PATH) == 0) && find_shell_builtin (command))
{
- if (verbose == 1)
+ if (dflags & CDESC_TYPE)
puts ("builtin");
- else if (verbose == 2)
+ else if (dflags & CDESC_SHORTDESC)
printf ("%s is a shell builtin\n", command);
- else if (verbose == 4)
+ else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
found = 1;
@@ -318,11 +310,11 @@ describe_command (command, verbose, all)
f = file_status (command);
if (f & FS_EXECABLE)
{
- if (verbose == 1)
+ if (dflags & CDESC_TYPE)
puts ("file");
- else if (verbose == 2)
+ else if (dflags & CDESC_SHORTDESC)
printf ("%s is %s\n", command, command);
- else if (verbose == 3 || verbose == 4)
+ else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
printf ("%s\n", command);
/* There's no use looking in the hash table or in $PATH,
@@ -334,15 +326,15 @@ describe_command (command, verbose, all)
/* If the user isn't doing "-a", then we might care about
whether the file is present in our hash table. */
- if (all == 0)
+ if (all == 0 || (dflags & CDESC_FORCE_PATH))
{
- if ((full_path = find_hashed_filename (command)) != (char *)NULL)
+ if (full_path = phash_search (command))
{
- if (verbose == 1)
+ if (dflags & CDESC_TYPE)
puts ("file");
- else if (verbose == 2)
+ else if (dflags & CDESC_SHORTDESC)
printf ("%s is hashed (%s)\n", command, full_path);
- else if (verbose == 3 || verbose == 4)
+ else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
printf ("%s\n", full_path);
free (full_path);
@@ -376,18 +368,18 @@ describe_command (command, verbose, all)
if (all == 0)
break;
}
- else if (verbose >= 2)
+ else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY|CDESC_SHORTDESC))
full_path = sh_makepath ((char *)NULL, full_path, MP_DOCWD);
}
found_file++;
found = 1;
- if (verbose == 1)
+ if (dflags & CDESC_TYPE)
puts ("file");
- else if (verbose == 2)
+ else if (dflags & CDESC_SHORTDESC)
printf ("%s is %s\n", command, full_path);
- else if (verbose == 3 || verbose == 4)
+ else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
printf ("%s\n", full_path);
free (full_path);
diff --git a/builtins/ulimit.def b/builtins/ulimit.def
index a830fb5..3e147b4 100644
--- a/builtins/ulimit.def
+++ b/builtins/ulimit.def
@@ -1,7 +1,7 @@
This file is ulimit.def, from which is created ulimit.c.
It implements the builtin "ulimit" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -327,7 +327,7 @@ ulimit_builtin (list)
{
if (STREQ (list->word->word, "unlimited") == 0)
{
- builtin_error ("invalid limit argument: %s", list->word->word);
+ builtin_error ("%s: invalid limit argument", list->word->word);
return (EXECUTION_FAILURE);
}
return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
@@ -353,7 +353,7 @@ ulimit_builtin (list)
limind = _findlim (cmdlist[c].cmd);
if (limind == -1)
{
- builtin_error ("bad command: `%c'", cmdlist[c].cmd);
+ builtin_error ("`%c': bad command", cmdlist[c].cmd);
return (EX_USAGE);
}
}
@@ -382,8 +382,8 @@ ulimit_internal (cmd, cmdarg, mode, multiple)
opt = get_limit (limind, &soft_limit, &hard_limit);
if (opt < 0)
{
- builtin_error ("cannot get %s limit: %s", limits[limind].description,
- strerror (errno));
+ builtin_error ("%s: cannot get limit: %s", limits[limind].description,
+ strerror (errno));
return (EXECUTION_FAILURE);
}
@@ -408,20 +408,20 @@ ulimit_internal (cmd, cmdarg, mode, multiple)
if ((real_limit / block_factor) != limit)
{
- builtin_error ("limit out of range: %s", cmdarg);
+ sh_erange (cmdarg, "limit");
return (EXECUTION_FAILURE);
}
}
else
{
- builtin_error ("bad non-numeric arg `%s'", cmdarg);
+ sh_invalidnum (cmdarg);
return (EXECUTION_FAILURE);
}
if (set_limit (limind, real_limit, mode) < 0)
{
- builtin_error ("cannot modify %s limit: %s", limits[limind].description,
- strerror (errno));
+ builtin_error ("%s: cannot modify limit: %s", limits[limind].description,
+ strerror (errno));
return (EXECUTION_FAILURE);
}
@@ -618,23 +618,19 @@ static int
getmaxuprc (valuep)
RLIMTYPE *valuep;
{
-# if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
long maxchild;
- maxchild = sysconf (_SC_CHILD_MAX);
+
+ maxchild = getmaxchild ();
if (maxchild < 0)
- return -1;
+ {
+ errno = EINVAL;
+ return -1;
+ }
else
- *valuep = (RLIMTYPE) maxchild;
- return 0;
-# else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
-# if defined (MAXUPRC)
- *valuep = (RLIMTYPE) MAXUPRC;
- return 0;
-# else /* MAXUPRC */
- errno = EINVAL;
- return -1;
-# endif /* !MAXUPRC */
-# endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
+ {
+ *valuep = (RLIMTYPE) maxchild;
+ return 0;
+ }
}
static void
@@ -650,7 +646,8 @@ print_all_limits (mode)
for (i = 0; limits[i].option > 0; i++)
{
if (get_limit (i, &softlim, &hardlim) < 0)
- builtin_error ("cannot get %s limit: %s", limits[i].description, strerror (errno));
+ builtin_error ("%s: cannot get limit: %s", limits[i].description,
+ strerror (errno));
else
printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
}
@@ -716,8 +713,8 @@ set_all_limits (mode, newlim)
for (retval = i = 0; limits[i].option > 0; i++)
if (set_limit (i, newlim, mode) < 0)
{
- builtin_error ("cannot modify %s limit: %s", limits[i].description,
- strerror (errno));
+ builtin_error ("%s: cannot modify limit: %s", limits[i].description,
+ strerror (errno));
retval = 1;
}
return retval;
diff --git a/builtins/umask.def b/builtins/umask.def
index 4d62184..19a0ac0 100644
--- a/builtins/umask.def
+++ b/builtins/umask.def
@@ -1,7 +1,7 @@
This file is umask.def, from which is created umask.c.
It implements the builtin "umask" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -107,8 +107,7 @@ umask_builtin (list)
is lousy. */
if (umask_value == -1)
{
- builtin_error ("`%s' is not an octal number from 000 to 777",
- list->word->word);
+ sh_erange (list->word->word, "octal number");
return (EXECUTION_FAILURE);
}
}
@@ -222,7 +221,7 @@ parse_symbolic_mode (mode, initial_bits)
case '=':
break;
default:
- builtin_error ("bad symbolic mode operator: %c", op);
+ builtin_error ("`%c': invalid symbolic mode operator", op);
return (-1);
}
@@ -275,7 +274,7 @@ parse_symbolic_mode (mode, initial_bits)
}
else
{
- builtin_error ("bad character in symbolic mode: %c", *s);
+ builtin_error ("`%c': invalid symbolic mode character", *s);
return (-1);
}
}
diff --git a/builtins/wait.def b/builtins/wait.def
index f34da8d..23c8b19 100644
--- a/builtins/wait.def
+++ b/builtins/wait.def
@@ -1,7 +1,7 @@
This file is wait.def, from which is created wait.c.
It implements the builtin "wait" in Bash.
-Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -60,6 +60,7 @@ $END
#include "bashgetopt.h"
extern int interrupt_immediately;
+extern int wait_signal_received;
procenv_t wait_intr_buf;
@@ -87,8 +88,7 @@ wait_builtin (list)
if (no_options (list))
return (EX_USAGE);
- if (list != loptend)
- list = loptend;
+ list = loptend;
old_interrupt_immediately = interrupt_immediately;
interrupt_immediately++;
@@ -104,7 +104,7 @@ wait_builtin (list)
code = setjmp (wait_intr_buf);
if (code)
{
- status = 128 + SIGINT;
+ status = 128 + wait_signal_received;
WAIT_RETURN (status);
}
@@ -124,7 +124,7 @@ wait_builtin (list)
{
pid_t pid;
char *w;
- long pid_value;
+ intmax_t pid_value;
w = list->word->word;
if (DIGIT (*w))
@@ -136,7 +136,7 @@ wait_builtin (list)
}
else
{
- builtin_error ("`%s' is not a pid or valid job spec", w);
+ sh_badpid (w);
WAIT_RETURN (EXECUTION_FAILURE);
}
}
@@ -153,7 +153,7 @@ wait_builtin (list)
if (job < 0 || job >= job_slots || !jobs[job])
{
if (job != DUP_JOB)
- builtin_error ("%s: no such job", list->word->word);
+ sh_badjob (list->word->word);
UNBLOCK_CHILD (oset);
status = 127; /* As per Posix.2, section 4.70.2 */
list = list->next;
@@ -167,13 +167,13 @@ wait_builtin (list)
else if (job_control == 0 && *w == '%')
{
/* can't use jobspecs as arguments if job control is not active. */
- builtin_error ("job control not enabled");
+ sh_nojobs ((char *)NULL);
status = EXECUTION_FAILURE;
}
#endif /* JOB_CONTROL */
else
{
- builtin_error ("`%s' is not a pid or valid job spec", w);
+ sh_badpid (w);
status = EXECUTION_FAILURE;
}
list = list->next;