aboutsummaryrefslogtreecommitdiffstats
path: root/builtins
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>1997-06-05 14:59:13 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:50 +0000
commitd166f048818e10cf3799aa24a174fb22835f1acc (patch)
tree1ca27f9243900f8b236d0cde6a3862002aea9e19 /builtins
parentccc6cda312fea9f0468ee65b8f368e9653e1380b (diff)
downloadandroid_external_bash-d166f048818e10cf3799aa24a174fb22835f1acc.tar.gz
android_external_bash-d166f048818e10cf3799aa24a174fb22835f1acc.tar.bz2
android_external_bash-d166f048818e10cf3799aa24a174fb22835f1acc.zip
Imported from ../bash-2.01.tar.gz.
Diffstat (limited to 'builtins')
-rw-r--r--builtins/Makefile.in91
-rw-r--r--builtins/alias.def2
-rw-r--r--builtins/break.def22
-rw-r--r--builtins/cd.def30
-rw-r--r--builtins/command.def16
-rw-r--r--builtins/common.c105
-rw-r--r--builtins/common.h16
-rw-r--r--builtins/declare.def3
-rw-r--r--builtins/echo.def20
-rw-r--r--builtins/enable.def9
-rw-r--r--builtins/eval.def5
-rw-r--r--builtins/evalfile.c24
-rw-r--r--builtins/evalstring.c33
-rw-r--r--builtins/exec.def20
-rw-r--r--builtins/exit.def10
-rw-r--r--builtins/fc.def54
-rw-r--r--builtins/fg_bg.def2
-rw-r--r--builtins/getopt.c4
-rw-r--r--builtins/getopt.h6
-rw-r--r--builtins/getopts.def5
-rw-r--r--builtins/hash.def106
-rw-r--r--builtins/hashcom.h35
-rw-r--r--builtins/help.def19
-rw-r--r--builtins/history.def8
-rw-r--r--builtins/jobs.def19
-rw-r--r--builtins/kill.def3
-rw-r--r--builtins/let.def17
-rw-r--r--builtins/mkbuiltins.c18
-rw-r--r--builtins/psize.c4
-rw-r--r--builtins/pushd.def13
-rw-r--r--builtins/read.def25
-rw-r--r--builtins/return.def2
-rw-r--r--builtins/set.def57
-rw-r--r--builtins/setattr.def95
-rw-r--r--builtins/shift.def2
-rw-r--r--builtins/shopt.def31
-rw-r--r--builtins/suspend.def5
-rw-r--r--builtins/trap.def11
-rw-r--r--builtins/type.def2
-rw-r--r--builtins/ulimit.def27
-rw-r--r--builtins/umask.def19
-rw-r--r--builtins/wait.def5
42 files changed, 603 insertions, 397 deletions
diff --git a/builtins/Makefile.in b/builtins/Makefile.in
index f38917b..205f4fc 100644
--- a/builtins/Makefile.in
+++ b/builtins/Makefile.in
@@ -1,29 +1,31 @@
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
#
-MKBUILTINS = mkbuiltins
-RANLIB = @RANLIB@
-CFLAGS = @CFLAGS@
-LOCAL_CFLAGS = @LOCAL_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
SHELL = /bin/sh
+RANLIB = @RANLIB@
CC = @CC@
AR = @AR@
RM = rm -f
CP = cp
-LIBS = @LIBS@
-
srcdir = @srcdir@
VPATH = .:@srcdir@
topdir = @top_srcdir@
includedir = @includedir@
+PROFILE_FLAGS =
+CFLAGS = @CFLAGS@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+CPPFLAGS = @CPPFLAGS@
DEFS = @DEFS@
+LOCAL_DEFS = @LOCAL_DEFS@
+LIBS = @LIBS@
INCLUDES = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(srcdir)
-CCFLAGS = $(DEFS) $(SYSTEM_FLAGS) $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS)
+CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) $(CPPFLAGS) \
+ ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS)
+MKBUILTINS = mkbuiltins
DIRECTDEFINE = -D $(srcdir)
# xxx this is bad style
@@ -158,13 +160,57 @@ wait.o: wait.def
getopts.o: getopts.def
reserved.o: reserved.def
-common.o: $(topdir)/shell.h $(topdir)/command.h ../config.h
-common.o: $(topdir)/memalloc.h $(topdir)/general.h
-common.o: $(topdir)/variables.h $(topdir)/input.h $(srcdir)/hashcom.h
-common.o: $(topdir)/bashhist.h $(topdir)/quit.h $(topdir)/unwind_prot.h
-common.o: $(topdir)/maxpath.h $(topdir)/jobs.h $(topdir)/builtins.h
-common.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-common.o: $(topdir)/execute_cmd.h $(topdir)/error.h $(topdir)/externs.h
+# C files
+bashgetopt.o: ../config.h $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
+bashgetopt.o: $(topdir)/shell.h $(topdir)/bashjmp.h
+bashgetopt.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/error.h
+bashgetopt.o: $(topdir)/variables.h $(topdir)/quit.h $(topdir)/maxpath.h
+bashgetopt.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
+bashgetopt.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
+bashgetopt.o: $(topdir)/pathnames.h $(topdir)/externs.h $(srcdir)/common.h
+common.o: $(topdir)/bashtypes.h $(topdir)/posixstat.h $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
+common.o: $(topdir)/shell.h ../config.h $(topdir)/bashjmp.h $(topdir)/posixjmp.h
+common.o: $(topdir)/sig.h $(topdir)/command.h
+common.o: $(topdir)/general.h $(topdir)/stdc.h $(topdir)/memalloc.h
+common.o: $(topdir)/variables.h $(topdir)/input.h
+common.o: $(topdir)/siglist.h $(topdir)/bashhist.h $(topdir)/quit.h
+common.o: $(topdir)/unwind_prot.h $(topdir)/maxpath.h $(topdir)/jobs.h
+common.o: $(topdir)/builtins.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
+common.o: $(topdir)/subst.h $(topdir)/execute_cmd.h $(topdir)/error.h
+common.o: $(topdir)/externs.h $(topdir)/pathnames.h ./builtext.h
+evalfile.o: $(topdir)/bashtypes.h $(topdir)/posixstat.h $(topdir)/filecntl.h
+evalfile.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
+evalfile.o: $(topdir)/shell.h ../config.h $(topdir)/bashjmp.h
+evalfile.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/error.h
+evalfile.o: $(topdir)/variables.h $(topdir)/quit.h $(topdir)/maxpath.h
+evalfile.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
+evalfile.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
+evalfile.o: $(topdir)/pathnames.h $(topdir)/externs.h
+evalfile.o: $(topdir)/jobs.h $(topdir)/builtins.h $(topdir)/flags.h
+evalfile.o: $(topdir)/input.h $(topdir)/execute_cmd.h
+evalfile.o: $(topdir)/bashhist.h $(srcdir)/common.h
+evalstring.o: ../config.h $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
+evalstring.o: $(topdir)/shell.h $(topdir)/bashjmp.h $(topdir)/posixjmp.h
+evalstring.o: $(topdir)/sig.h $(topdir)/command.h $(topdir)/siglist.h
+evalstring.o: $(topdir)/memalloc.h $(topdir)/variables.h $(topdir)/input.h
+evalstring.o: $(topdir)/quit.h $(topdir)/unwind_prot.h
+evalstring.o: $(topdir)/maxpath.h $(topdir)/jobs.h $(topdir)/builtins.h
+evalstring.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
+evalstring.o: $(topdir)/externs.h $(topdir)/jobs.h $(topdir)/builtins.h
+evalstring.o: $(topdir)/flags.h $(topdir)/input.h $(topdir)/execute_cmd.h
+evalstring.o: $(topdir)/bashhist.h $(srcdir)/common.h
+getopt.o: ../config.h $(topdir)/memalloc.h
+getopt.o: $(topdir)/shell.h $(topdir)/bashjmp.h $(topdir)/command.h
+getopt.o: $(topdir)/general.h $(topdir)/error.h $(topdir)/variables.h
+getopt.o: $(topdir)/quit.h $(topdir)/maxpath.h $(topdir)/unwind_prot.h
+getopt.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
+getopt.o: $(topdir)/sig.h $(topdir)/pathnames.h $(topdir)/externs.h
+getopt.o: $(srcdir)/getopt.h
+mkbuiltins.o: ../config.h $(topdir)/bashtypes.h $(topdir)/posixstat.h
+mkbuiltins.o: $(topdir)/filecntl.h
+mkbuiltins.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
+
+# def files
alias.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
alias.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/maxpath.h
alias.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -217,18 +263,21 @@ eval.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
eval.o: $(topdir)/subst.h $(topdir)/externs.h
eval.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
eval.o: $(topdir)/maxpath.h
+exec.o: $(topdir)/bashtypes.h
exec.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
exec.o: $(topdir)/error.h $(topdir)/general.h
exec.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
exec.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/flags.h
exec.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
exec.o: $(srcdir)/common.h $(topdir)/execute_cmd.h $(topdir)/maxpath.h
+exit.o: $(topdir)/bashtypes.h
exit.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
exit.o: $(topdir)/error.h $(topdir)/general.h
exit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
exit.o: $(topdir)/subst.h $(topdir)/externs.h
exit.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
-exit.o: $(topdir)/maxpath.h
+exit.o: $(topdir)/maxpath.h ./builtext.h
+fc.o: $(topdir)/bashtypes.h $(topdir)/posixstat.h
fc.o: $(topdir)/builtins.h $(topdir)/command.h $(srcdir)/bashgetopt.h
fc.o: $(topdir)/bashhist.h
fc.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h $(topdir)/error.h
@@ -236,6 +285,8 @@ fc.o: $(topdir)/general.h $(topdir)/maxpath.h
fc.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
fc.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/shell.h
fc.o: $(topdir)/flags.h $(topdir)/unwind_prot.h $(topdir)/variables.h
+fc.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
+fg_bg.o: $(topdir)/bashtypes.h
fg_bg.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
fg_bg.o: $(topdir)/error.h $(topdir)/general.h
fg_bg.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -257,6 +308,7 @@ help.o: $(topdir)/error.h $(topdir)/general.h
help.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
help.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
help.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
+history.o: $(topdir)/bashtypes.h
history.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
history.o: $(topdir)/error.h $(topdir)/general.h
history.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -288,7 +340,7 @@ pushd.o: $(topdir)/error.h $(topdir)/general.h
pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
pushd.o: $(topdir)/subst.h $(topdir)/externs.h
pushd.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
-pushd.o: $(topdir)/maxpath.h $(srcdir)/common.h
+pushd.o: $(topdir)/maxpath.h $(srcdir)/common.h ./builtext.h
read.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
read.o: $(topdir)/error.h $(topdir)/general.h
read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -345,7 +397,7 @@ type.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
type.o: $(topdir)/error.h $(topdir)/general.h
type.o: $(topdir)/quit.h $(srcdir)/common.h $(topdir)/maxpath.h
type.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
-type.o: $(topdir)/externs.h
+type.o: $(topdir)/externs.h $(topdir)/hashcmd.h
type.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
ulimit.o: $(topdir)/command.h ../config.h $(topdir)/memalloc.h
ulimit.o: $(topdir)/error.h $(topdir)/general.h
@@ -368,8 +420,5 @@ shopt.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
shopt.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/maxpath.h
shopt.o: $(topdir)/shell.h $(topdir)/unwind_prot.h $(topdir)/variables.h
shopt.o: $(srcdir)/common.h $(srcdir)/bashgetopt.h
-bashgetopt.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
-mkbuiltins.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
-fc.o: $(topdir)/bashansi.h $(topdir)/ansi_stdlib.h
#bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h
diff --git a/builtins/alias.def b/builtins/alias.def
index 42955b7..044b44d 100644
--- a/builtins/alias.def
+++ b/builtins/alias.def
@@ -40,6 +40,8 @@ $END
# include <unistd.h>
#endif
+# include "../bashansi.h"
+
# include <stdio.h>
# include "../shell.h"
# include "../alias.h"
diff --git a/builtins/break.def b/builtins/break.def
index d6f8598..5354ef6 100644
--- a/builtins/break.def
+++ b/builtins/break.def
@@ -57,13 +57,17 @@ break_builtin (list)
{
int newbreak;
- if (!check_loop_level ())
+ if (check_loop_level () == 0)
return (EXECUTION_FAILURE);
- newbreak = get_numeric_arg (list);
+ newbreak = get_numeric_arg (list, 1);
if (newbreak <= 0)
- return (EXECUTION_FAILURE);
+ {
+ builtin_error ("loop count must be > 0");
+ breaking = loop_level;
+ return (EXECUTION_FAILURE);
+ }
if (newbreak > loop_level)
newbreak = loop_level;
@@ -88,13 +92,17 @@ continue_builtin (list)
{
int newcont;
- if (!check_loop_level ())
+ if (check_loop_level () == 0)
return (EXECUTION_FAILURE);
- newcont = get_numeric_arg (list);
+ newcont = get_numeric_arg (list, 1);
if (newcont <= 0)
- return (EXECUTION_FAILURE);
+ {
+ builtin_error ("loop count must be > 0");
+ breaking = loop_level;
+ return (EXECUTION_FAILURE);
+ }
if (newcont > loop_level)
newcont = loop_level;
@@ -110,7 +118,7 @@ static int
check_loop_level ()
{
#if defined (BREAK_COMPLAINS)
- if (!loop_level)
+ if (loop_level == 0)
builtin_error ("only meaningful in a `for', `while', or `until' loop");
#endif /* BREAK_COMPLAINS */
diff --git a/builtins/cd.def b/builtins/cd.def
index e6611d0..4bbad7e 100644
--- a/builtins/cd.def
+++ b/builtins/cd.def
@@ -49,13 +49,16 @@ extern int errno;
#endif /* !errno */
extern int posixly_correct, interactive;
+extern int array_needs_making;
extern char *bash_getcwd_errstr;
static int change_to_directory ();
static char *cdspell ();
static int spname (), mindist (), spdist ();
-int cdspelling = 1;
+
+/* Change this to 1 to get cd spelling correction by default. */
+int cdspelling = 0;
int cdable_vars;
@@ -118,8 +121,9 @@ static int
bindpwd (no_symlinks)
int no_symlinks;
{
- char *dirname;
- int old_symlinks;
+ char *dirname, *pwdvar;
+ int old_symlinks, old_anm;
+ SHELL_VAR *tvar;
if (no_symlinks)
{
@@ -132,7 +136,22 @@ bindpwd (no_symlinks)
dirname = get_working_directory ("cd");
bind_variable ("OLDPWD", get_string_value ("PWD"));
- bind_variable ("PWD", dirname);
+
+ old_anm = array_needs_making;
+ tvar = bind_variable ("PWD", dirname);
+ /* This is an efficiency hack. If PWD is exported, we will need to
+ remake the exported environment every time we change directories.
+ If there is no other reason to make the exported environment, just
+ update PWD in place and mark the exported environment as no longer
+ needing a remake. */
+ if (old_anm == 0 && array_needs_making && exported_p (tvar))
+ {
+ pwdvar = xmalloc (strlen (dirname) + 5); /* 5 = "PWD" + '=' + '\0' */
+ strcpy (pwdvar, "PWD=");
+ strcpy (pwdvar + 4, dirname);
+ add_or_supercede_exported_var (pwdvar, 0);
+ array_needs_making = 0;
+ }
FREE (dirname);
return (EXECUTION_SUCCESS);
@@ -547,6 +566,9 @@ mindist(dir, guess, best)
}
(void)closedir(fd);
+ /* Don't return `.' */
+ if (best[0] == '.' && best[1] == '\0')
+ dist = 3;
return dist;
}
diff --git a/builtins/command.def b/builtins/command.def
index 3a14dc6..6e6e5f6 100644
--- a/builtins/command.def
+++ b/builtins/command.def
@@ -117,13 +117,10 @@ command_builtin (list)
if (use_standard_path)
{
old_path = get_string_value ("PATH");
+ /* If old_path is NULL, $PATH is unset. If so, we want to make sure
+ it's unset after this command completes. */
if (old_path)
old_path = savestring (old_path);
- else
- {
- old_path = xmalloc (1);
- old_path[0] = '\0';
- }
add_unwind_protect ((Function *)restore_path, old_path);
standard_path = get_standard_path ();
@@ -162,8 +159,13 @@ static void
restore_path (var)
char *var;
{
- bind_variable ("PATH", var);
- free (var);
+ if (var)
+ {
+ bind_variable ("PATH", var);
+ free (var);
+ }
+ else
+ unbind_variable ("PATH");
}
/* Return a value for PATH that is guaranteed to find all of the standard
diff --git a/builtins/common.c b/builtins/common.c
index 2936b88..1b82032 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -23,7 +23,7 @@
#endif
#include <stdio.h>
-#include <sys/types.h>
+#include "../bashtypes.h"
#include "../posixstat.h"
#include <signal.h>
@@ -45,9 +45,9 @@
#include "../input.h"
#include "../execute_cmd.h"
#include "../trap.h"
-#include "hashcom.h"
#include "bashgetopt.h"
#include "common.h"
+#include "builtext.h"
#include <tilde/tilde.h>
#if defined (HISTORY)
@@ -59,14 +59,16 @@ extern int indirection_level, startup_state, subshell_environment;
extern int line_number;
extern int last_command_exit_value;
extern int running_trap;
-extern int hashing_enabled;
extern int variable_context;
extern int posixly_correct;
extern char *this_command_name, *shell_name;
extern COMMAND *global_command;
-extern HASH_TABLE *hashed_filenames;
extern char *bash_getcwd_errstr;
+/* Used by some builtins and the mainline code. */
+Function *last_shell_builtin = (Function *)NULL;
+Function *this_shell_builtin = (Function *)NULL;
+
/* **************************************************************** */
/* */
/* Error reporting, usage, and option processing */
@@ -317,10 +319,13 @@ set_dollar_vars_changed ()
/* Read a numeric arg for this_command_name, the name of the shell builtin
that wants it. LIST is the word list that the arg is to come from.
Accept only the numeric argument; report an error if other arguments
- follow. */
+ 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. */
int
-get_numeric_arg (list)
+get_numeric_arg (list, fatal)
WORD_LIST *list;
+ int fatal;
{
long count = 1;
@@ -332,7 +337,10 @@ get_numeric_arg (list)
if (!arg || (legal_number (arg, &count) == 0))
{
builtin_error ("bad non-numeric arg `%s'", list->word->word);
- throw_to_top_level ();
+ if (fatal)
+ throw_to_top_level ();
+ else
+ jump_to_top_level (DISCARD);
}
no_args (list->next);
}
@@ -362,80 +370,6 @@ read_octal (string)
/* **************************************************************** */
/* */
-/* Command name hashing */
-/* */
-/* **************************************************************** */
-
-/* Return the full pathname that FILENAME hashes to. If FILENAME
- is hashed, but (data->flags & HASH_CHKDOT) is non-zero, check
- ./FILENAME and return that if it is executable. */
-char *
-find_hashed_filename (filename)
- char *filename;
-{
- register BUCKET_CONTENTS *item;
- char *path, *dotted_filename, *tail;
- int same;
-
- if (hashing_enabled == 0)
- return ((char *)NULL);
-
- item = find_hash_item (filename, hashed_filenames);
-
- if (item == NULL)
- return ((char *)NULL);
-
- /* If this filename is hashed, but `.' comes before it in the path,
- see if ./filename is executable. If the hashed value is not an
- absolute pathname, see if ./`hashed-value' exists. */
- path = pathdata(item)->path;
- if (pathdata(item)->flags & (HASH_CHKDOT|HASH_RELPATH))
- {
- tail = (pathdata(item)->flags & HASH_RELPATH) ? path : filename;
- dotted_filename = xmalloc (3 + strlen (tail));
- dotted_filename[0] = '.'; dotted_filename[1] = '/';
- strcpy (dotted_filename + 2, tail);
-
- if (executable_file (dotted_filename))
- return (dotted_filename);
-
- free (dotted_filename);
-
-#if 0
- if (pathdata(item)->flags & HASH_RELPATH)
- return ((char *)NULL);
-#endif
-
- /* Watch out. If this file was hashed to "./filename", and
- "./filename" is not executable, then return NULL. */
-
- /* Since we already know "./filename" is not executable, what
- we're really interested in is whether or not the `path'
- portion of the hashed filename is equivalent to the current
- directory, but only if it starts with a `.'. (This catches
- ./. and so on.) same_file () tests general Unix file
- equivalence -- same device and inode. */
- if (*path == '.')
- {
- same = 0;
- tail = (char *)strrchr (path, '/');
-
- if (tail)
- {
- *tail = '\0';
- same = same_file (".", path, (struct stat *)NULL, (struct stat *)NULL);
- *tail = '/';
- }
-
- return same ? (char *)NULL : path;
- }
- }
-
- return (path);
-}
-
-/* **************************************************************** */
-/* */
/* Manipulating the current working directory */
/* */
/* **************************************************************** */
@@ -635,7 +569,13 @@ display_signal_list (list, forcecols)
list = list->next;
continue;
}
+#if defined (JOB_CONTROL)
+ /* POSIX.2 says that `kill -l signum' prints the signal name without
+ the `SIG' prefix. */
+ printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
+#else
printf ("%s\n", name);
+#endif
}
else
{
@@ -852,6 +792,9 @@ backslash_quote (string)
*r++ = c;
break;
case '#': /* comment char */
+#if 0
+ case '~': /* tilde expansion */
+#endif
if (s == string)
*r++ = '\\';
/* FALLTHROUGH */
diff --git a/builtins/common.h b/builtins/common.h
index ce831f7..eec5444 100644
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -25,6 +25,11 @@
#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
+
extern void builtin_error __P((const char *, ...));
extern void builtin_usage ();
extern void bad_option ();
@@ -69,18 +74,15 @@ extern char *double_quote ();
extern char *backslash_quote ();
extern int contains_shell_metas ();
-/* Functions from hash.def */
-extern void initialize_filename_hashing ();
-extern void flush_hashed_filenames ();
-extern char *find_hashed_filename ();
-extern void remove_hashed_filename ();
-extern void remember_filename ();
-
/* Functions from set.def */
extern void initialize_shell_options ();
extern void list_minus_o_opts ();
extern int set_minus_o_option ();
extern int minus_o_option_value ();
+extern void reset_shell_options ();
+
+/* Functions from shopt.def */
+extern void reset_shopt_options ();
/* Functions from type.def */
extern int describe_command ();
diff --git a/builtins/declare.def b/builtins/declare.def
index 68514d3..10a3146 100644
--- a/builtins/declare.def
+++ b/builtins/declare.def
@@ -268,7 +268,8 @@ declare_internal (list, local_var)
{
if (offset) /* declare -f [-rix] foo=bar */
{
- builtin_error ("Can't use `-f' to make functions");
+ builtin_error ("cannot use `-f' to make functions");
+ free (name);
return (EXECUTION_FAILURE);
}
else /* declare -f [-rx] name [name...] */
diff --git a/builtins/echo.def b/builtins/echo.def
index 74ca0f4..e8b6edb 100644
--- a/builtins/echo.def
+++ b/builtins/echo.def
@@ -26,6 +26,8 @@ $PRODUCES echo.c
# include <unistd.h>
#endif
+#include "../bashansi.h"
+
#include <stdio.h>
#include "../shell.h"
@@ -72,8 +74,8 @@ int
echo_builtin (list)
WORD_LIST *list;
{
- int display_return, do_v9, i;
- char *temp;
+ int display_return, do_v9, i, len;
+ char *temp, *s;
#if defined (DEFAULT_ECHO_TO_USG)
/* System V machines already have a /bin/sh with a v9 behaviour. We
@@ -130,13 +132,21 @@ just_echo:
while (list)
{
- i = 0;
- temp = do_v9 ? ansicstr (list->word->word, STRLEN (list->word->word), &i)
+ i = len = 0;
+ temp = do_v9 ? ansicstr (list->word->word, STRLEN (list->word->word), &i, &len)
: list->word->word;
if (temp)
{
- printf ("%s", temp);
+ if (do_v9)
+ {
+ for (s = temp; len > 0; len--)
+ putchar (*s++);
+ }
+ else
+ printf ("%s", temp);
+#if defined (SunOS5)
fflush (stdout); /* Fix for bug in SunOS 5.5 printf(3) */
+#endif
}
if (do_v9 && temp)
free (temp);
diff --git a/builtins/enable.def b/builtins/enable.def
index 37c4f2b..049a7f0 100644
--- a/builtins/enable.def
+++ b/builtins/enable.def
@@ -238,7 +238,10 @@ enable_shell_command (name, disable_p)
}
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
-#include <dlfcn.h>
+
+#if defined (HAVE_DLFCN_H)
+# include <dlfcn.h>
+#endif
static int
dyn_load_builtin (list, flags, filename)
@@ -359,7 +362,11 @@ delete_builtin (b)
struct builtin *new_shell_builtins;
/* XXX - funky pointer arithmetic - XXX */
+#ifdef __STDC__
+ ind = b - shell_builtins;
+#else
ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
+#endif
size = num_shell_builtins * sizeof (struct builtin);
new_shell_builtins = (struct builtin *)xmalloc (size);
diff --git a/builtins/eval.def b/builtins/eval.def
index a394896..62db712 100644
--- a/builtins/eval.def
+++ b/builtins/eval.def
@@ -34,8 +34,7 @@ $END
#include "../shell.h"
#include "bashgetopt.h"
-
-extern int parse_and_execute ();
+#include "common.h"
/* Parse the string that these words make, and execute the command found. */
int
@@ -46,5 +45,5 @@ eval_builtin (list)
return (EX_USAGE);
/* Note that parse_and_execute () frees the string it is passed. */
- return (list ? parse_and_execute (string_list (list), "eval", -1) : EXECUTION_SUCCESS);
+ return (list ? parse_and_execute (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS);
}
diff --git a/builtins/evalfile.c b/builtins/evalfile.c
index 14fbc4d..3ffccbe 100644
--- a/builtins/evalfile.c
+++ b/builtins/evalfile.c
@@ -22,7 +22,7 @@
# include <unistd.h>
#endif
-#include <sys/types.h>
+#include "../bashtypes.h"
#include "../posixstat.h"
#include "../filecntl.h"
@@ -55,6 +55,7 @@ extern int errno;
#define FEVAL_UNWINDPROT 0x004
#define FEVAL_NONINT 0x008
#define FEVAL_LONGJMP 0x010
+#define FEVAL_HISTORY 0x020
extern int interactive, interactive_shell, posixly_correct;
extern int indirection_level, startup_state, subshell_environment;
@@ -71,7 +72,7 @@ _evalfile (filename, flags)
{
volatile int old_interactive;
procenv_t old_return_catch;
- int return_val, fd, result;
+ int return_val, fd, result, pflags;
char *string;
struct stat finfo;
VFunction *errfunc;
@@ -151,6 +152,9 @@ file_error_and_exit:
return_catch_flag++;
sourcelevel++;
+ /* set the flags to be passed to parse_and_execute */
+ pflags = (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
+
if (flags & FEVAL_BUILTIN)
result = EXECUTION_SUCCESS;
@@ -164,7 +168,7 @@ file_error_and_exit:
result = return_catch_value;
}
else
- result = parse_and_execute (string, filename, -1);
+ result = parse_and_execute (string, filename, pflags);
if (flags & FEVAL_UNWINDPROT)
run_unwind_frame ("_evalfile");
@@ -197,6 +201,20 @@ maybe_execute_file (fname, force_noninteractive)
return result;
}
+#if defined (HISTORY)
+int
+fc_execute_file (filename)
+ char *filename;
+{
+ int flags;
+
+ /* We want these commands to show up in the history list if
+ remember_on_history is set. */
+ flags = FEVAL_ENOENTOK|FEVAL_HISTORY;
+ return (_evalfile (filename, flags));
+}
+#endif /* HISTORY */
+
int
source_file (filename)
char *filename;
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
index 2e84068..bf4a8a5 100644
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -40,6 +40,8 @@
#include "common.h"
+extern void run_trap_cleanup ();
+
extern int interactive, interactive_shell;
extern int indirection_level, startup_state, subshell_environment;
extern int line_number;
@@ -62,14 +64,19 @@ parse_and_execute_cleanup ()
}
/* Parse and execute the commands in STRING. Returns whatever
- execute_command () returns. This frees STRING. INTERACT is
- the new value for `interactive' while the commands are being
- executed. A value of -1 means don't change it. */
+ execute_command () returns. This frees STRING. FLAGS is a
+ flags word; look in common.h for the possible values. Actions
+ are:
+ (flags & SEVAL_NONINT) -> interactive = 0;
+ (flags & SEVAL_INTERACT) -> interactive = 1;
+ (flags & SEVAL_NOHIST) -> call bash_history_disable ()
+*/
+
int
-parse_and_execute (string, from_file, interact)
+parse_and_execute (string, from_file, flags)
char *string;
char *from_file;
- int interact;
+ int flags;
{
int code;
volatile int should_jump_to_top_level, last_result;
@@ -83,17 +90,17 @@ parse_and_execute (string, from_file, interact)
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
- if (interact != -1 && interactive != interact)
+ if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
#if defined (HISTORY)
+ unwind_protect_int (remember_on_history); /* can be used in scripts */
+# if defined (BANG_HISTORY)
if (interactive_shell)
{
- unwind_protect_int (remember_on_history);
-# if defined (BANG_HISTORY)
unwind_protect_int (history_expansion_inhibited);
-# endif /* BANG_HISTORY */
}
+# endif /* BANG_HISTORY */
#endif /* HISTORY */
add_unwind_protect (pop_stream, (char *)NULL);
@@ -104,11 +111,12 @@ parse_and_execute (string, from_file, interact)
parse_and_execute_level++;
push_stream (1); /* reset the line number */
indirection_level++;
- if (interact != -1)
- interactive = interact;
+ if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
+ interactive = (flags & SEVAL_NONINT) ? 0 : 1;
#if defined (HISTORY)
- bash_history_disable ();
+ if (flags & SEVAL_NOHIST)
+ bash_history_disable ();
#endif /* HISTORY */
code = should_jump_to_top_level = 0;
@@ -177,6 +185,7 @@ parse_and_execute (string, from_file, interact)
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
begin_unwind_frame ("pe_dispose");
add_unwind_protect (dispose_fd_bitmap, bitmap);
+ add_unwind_protect (dispose_command, command); /* XXX */
global_command = (COMMAND *)NULL;
diff --git a/builtins/exec.def b/builtins/exec.def
index c14af75..cc7f5a9 100644
--- a/builtins/exec.def
+++ b/builtins/exec.def
@@ -36,7 +36,7 @@ $END
#include <config.h>
-#include <sys/types.h>
+#include "../bashtypes.h"
#include "../posixstat.h"
#include <signal.h>
#include <errno.h>
@@ -65,7 +65,7 @@ $END
extern int errno;
#endif /* !errno */
-extern int interactive, subshell_environment;
+extern int interactive, interactive_shell, subshell_environment;
extern REDIRECT *redirection_undo_list;
int no_exit_on_failed_exec;
@@ -90,7 +90,7 @@ exec_builtin (list)
{
int exit_value = EXECUTION_FAILURE;
int cleanenv, login, opt;
- char *argv0, *command, **args, **env, *newname;
+ char *argv0, *command, **args, **env, *newname, *com2;
cleanenv = login = 0;
argv0 = (char *)NULL;
@@ -143,7 +143,13 @@ exec_builtin (list)
goto failed_exec;
}
- command = full_pathname (command);
+ com2 = full_pathname (command);
+ if (com2)
+ {
+ if (command != args[0])
+ free (command);
+ command = com2;
+ }
if (argv0)
{
@@ -172,7 +178,8 @@ exec_builtin (list)
}
#if defined (HISTORY)
- maybe_save_shell_history ();
+ if (interactive_shell && subshell_environment == 0)
+ maybe_save_shell_history ();
#endif /* HISTORY */
restore_original_signals ();
@@ -201,6 +208,9 @@ failed_exec:
if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
exit_shell (exit_value);
+ if (args)
+ free_array (args);
+
initialize_traps ();
reinitialize_signals ();
diff --git a/builtins/exit.def b/builtins/exit.def
index 23a89ca..ee02b38 100644
--- a/builtins/exit.def
+++ b/builtins/exit.def
@@ -30,7 +30,7 @@ $END
#include <config.h>
-#include <sys/types.h>
+#include "../bashtypes.h"
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
@@ -45,6 +45,8 @@ $END
extern int interactive, login_shell;
extern int last_command_exit_value;
+extern Function *this_shell_builtin;
+extern Function *last_shell_builtin;
static int exit_or_logout ();
static int sourced_logout;
@@ -82,10 +84,6 @@ logout_builtin (list)
return (exit_or_logout (list));
}
-/* Clean up work for exiting or logging out. */
-Function *last_shell_builtin = (Function *)NULL;
-Function *this_shell_builtin = (Function *)NULL;
-
static int
exit_or_logout (list)
WORD_LIST *list;
@@ -121,7 +119,7 @@ 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_numeric_arg (list) : last_command_exit_value;
+ exit_value = list ? get_numeric_arg (list, 1) : last_command_exit_value;
/* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
if (login_shell && sourced_logout++ == 0)
diff --git a/builtins/fc.def b/builtins/fc.def
index 16eb8d2..e88ba12 100644
--- a/builtins/fc.def
+++ b/builtins/fc.def
@@ -50,8 +50,8 @@ $END
#if defined (HISTORY)
#include <sys/param.h>
-#include "bashtypes.h"
-#include "posixstat.h"
+#include "../bashtypes.h"
+#include "../posixstat.h"
#include <sys/file.h>
#if defined (HAVE_UNISTD_H)
@@ -77,9 +77,13 @@ extern int errno;
#endif /* !errno */
extern int echo_input_at_read;
+extern int current_command_line_count;
+extern int literal_history;
extern int unlink ();
+extern int fc_execute_file ();
+
/* **************************************************************** */
/* */
/* The K*rn shell style fc command (Fix Command) */
@@ -252,7 +256,7 @@ fc_builtin (list)
fprintf (stderr, "%s\n", command);
fc_replhist (command); /* replace `fc -s' with command */
- return (parse_and_execute (command, "fc", -1));
+ return (parse_and_execute (command, "fc", SEVAL_NOHIST));
}
/* This is the second form of the command (the list-or-edit-and-rerun
@@ -266,9 +270,11 @@ fc_builtin (list)
("fc blah..." and so on) is already part of the history list by
the time we get to this point. This just skips over that command
and makes the last command that this deals with be the last command
- the user entered before the fc. */
+ the user entered before the fc. We need to check whether the
+ line was actually added (HISTIGNORE may have caused it to not be),
+ so we check hist_last_line_added. */
- last_hist = i - 2;
+ last_hist = i - 1 - hist_last_line_added;
if (list)
{
@@ -317,6 +323,7 @@ fc_builtin (list)
else
{
numbering = 0;
+ /* XXX - this is raceable */
sprintf (fn, "/tmp/bash%d", (int)time ((time_t *) 0) + (int)getpid ());
stream = fopen (fn, "w");
@@ -354,7 +361,7 @@ fc_builtin (list)
command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn));
sprintf (command, "%s %s", FC_EDIT_COMMAND, fn);
}
- retval = parse_and_execute (command, "fc", -1);
+ retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
if (retval != EXECUTION_SUCCESS)
{
unlink (fn);
@@ -375,10 +382,18 @@ fc_builtin (list)
retval = EXECUTION_SUCCESS;
first = 1;
+#if 1
+ /* Make sure parse_and_execute doesn't turn this off, even though a
+ call to parse_and_execute farther up the function call stack (e.g.,
+ if this is called by vi_edit_and_execute_command) may have already
+ called bash_history_disable. */
+ remember_on_history = 1;
+#else
/* First, write the commands to the history file. This will not happen
when we call parse_and_execute, since parse_and_execute disables
the command line history while it executes. */
-
+
+ opt = current_command_line_count;
while ((line = fc_readline (stream)) != NULL)
{
if (line[0] == '\n')
@@ -390,23 +405,36 @@ fc_builtin (list)
if (first)
{
first = 0;
+ /* If we retrieved only one command from the history file, but we
+ read multiple lines from the edited file, and literal_history
+ has been set by `shopt', we assume that it was a compound
+ command stored with embedded newlines. In this case, we want
+ the history code to store it as one command again. */
+ if (literal_history && histbeg == histend)
+ current_command_line_count = 1;
fc_replhist (line);
}
else
- fc_addhist (line);
+ {
+ if (literal_history && histbeg == histend)
+ current_command_line_count++;
+ fc_addhist (line);
+ }
free (line);
}
fclose (stream);
+ current_command_line_count = opt;
+#endif
- /* Turn on the `v' flag while maybe_execute_file runs so the commands
+ /* Turn on the `v' flag while fc_execute_file runs so the commands
will be echoed as they are read by the parser. */
begin_unwind_frame ("fc builtin");
add_unwind_protect (unlink, fn);
unwind_protect_int (echo_input_at_read);
echo_input_at_read = 1;
- retval = maybe_execute_file (fn, 0);
+ retval = fc_execute_file (fn);
run_unwind_frame ("fc builtin");
@@ -447,8 +475,10 @@ fc_gethnum (command, hlist)
("fc blah..." and so on) is already part of the history list by
the time we get to this point. This just skips over that command
and makes the last command that this deals with be the last command
- the user entered before the fc. */
- i -= 2;
+ the user entered before the fc. We need to check whether the
+ line was actually added (HISTIGNORE may have caused it to not be),
+ so we check hist_last_line_added. */
+ i -= 1 + hist_last_line_added;
/* No specification defaults to most recent command. */
if (command == NULL)
diff --git a/builtins/fg_bg.def b/builtins/fg_bg.def
index 49d0200..2f1b826 100644
--- a/builtins/fg_bg.def
+++ b/builtins/fg_bg.def
@@ -32,7 +32,7 @@ $END
#include <config.h>
-#include <sys/types.h>
+#include "../bashtypes.h"
#include <signal.h>
#if defined (HAVE_UNISTD_H)
diff --git a/builtins/getopt.c b/builtins/getopt.c
index bc69489..b5f8bc4 100644
--- a/builtins/getopt.c
+++ b/builtins/getopt.c
@@ -115,7 +115,7 @@ sh_getopt (argc, argv, optstring)
sh_optarg = 0;
- if (sh_optind > argc || sh_optind < 0)
+ if (sh_optind >= argc || sh_optind < 0) /* XXX was sh_optind > argc */
{
sh_optind = argc;
return (EOF);
@@ -144,7 +144,7 @@ sh_getopt (argc, argv, optstring)
if (nextchar == 0 || *nextchar == '\0')
{
/* If we have done all the ARGV-elements, stop the scan. */
- if (sh_optind == argc)
+ if (sh_optind >= argc)
return EOF;
temp = argv[sh_optind];
diff --git a/builtins/getopt.h b/builtins/getopt.h
index 7086bb7..cf5854a 100644
--- a/builtins/getopt.h
+++ b/builtins/getopt.h
@@ -17,8 +17,8 @@
/* XXX THIS HAS BEEN MODIFIED FOR INCORPORATION INTO BASH XXX */
-#ifndef _GETOPT_H
-#define _GETOPT_H 1
+#ifndef _SH_GETOPT_H
+#define _SH_GETOPT_H 1
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
@@ -57,4 +57,4 @@ extern int sh_badopt;
extern int sh_getopt ();
extern void sh_getopt_restore_state ();
-#endif /* _GETOPT_H */
+#endif /* _SH_GETOPT_H */
diff --git a/builtins/getopts.def b/builtins/getopts.def
index f3d9aee..a9c5116 100644
--- a/builtins/getopts.def
+++ b/builtins/getopts.def
@@ -292,7 +292,10 @@ getopts_builtin (list)
int ac, ret;
if (list == 0)
- return EXECUTION_FAILURE;
+ {
+ builtin_usage ();
+ return EX_USAGE;
+ }
reset_internal_getopt ();
while ((ret = internal_getopt (list, "")) != -1)
diff --git a/builtins/hash.def b/builtins/hash.def
index 2f69f65..813cb03 100644
--- a/builtins/hash.def
+++ b/builtins/hash.def
@@ -33,9 +33,6 @@ $END
#include <config.h>
-#include <sys/types.h>
-#include "../posixstat.h"
-
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
@@ -46,9 +43,9 @@ $END
#include "../shell.h"
#include "../builtins.h"
-#include "../flags.h"
#include "../execute_cmd.h"
-#include "hashcom.h"
+#include "../flags.h"
+#include "../hashcmd.h"
#include "common.h"
#include "bashgetopt.h"
@@ -58,54 +55,6 @@ extern char *this_command_name;
static int add_hashed_command ();
static int print_hashed_commands ();
-static int hashing_initialized = 0;
-
-HASH_TABLE *hashed_filenames;
-
-void
-initialize_filename_hashing ()
-{
- if (hashing_initialized == 0)
- {
- hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
- hashing_initialized = 1;
- }
-}
-
-static void
-free_filename_data (data)
- char *data;
-{
- free (((PATH_DATA *)data)->path);
- free (data);
-}
-
-void
-flush_hashed_filenames ()
-{
- flush_hash_table (hashed_filenames, free_filename_data);
-}
-
-/* Remove FILENAME from the table of hashed commands. */
-void
-remove_hashed_filename (filename)
- char *filename;
-{
- register BUCKET_CONTENTS *item;
-
- if (hashing_enabled == 0)
- return;
-
- item = remove_hash_item (filename, hashed_filenames);
- if (item)
- {
- if (item->data)
- free_filename_data (item->data);
- free (item->key);
- free (item);
- }
-}
-
/* Print statistics on the current state of hashed commands. If LIST is
not empty, then rehash (or hash in the first place) the specified
commands. */
@@ -161,56 +110,16 @@ hash_builtin (list)
word = list->word->word;
if (pathname)
remember_filename (word, pathname, 0, 0);
- else
- {
- if (absolute_program (word))
- {
- list = list->next;
- continue;
- }
-
- if (add_hashed_command (word))
- opt = EXECUTION_FAILURE;
- }
+ else if (absolute_program (word))
+ continue;
+ else if (add_hashed_command (word, 0))
+ opt = EXECUTION_FAILURE;
}
fflush (stdout);
-
return (opt);
}
-/* Place FILENAME (key) and FULL_PATHNAME (data->path) into the
- hash table. CHECK_DOT if non-null is for future calls to
- find_hashed_filename (); it means that this file was found
- in a directory in $PATH that is not an absolute pathname.
- FOUND is the initial value for times_found. */
-void
-remember_filename (filename, full_pathname, check_dot, found)
- char *filename, *full_pathname;
- int check_dot, found;
-{
- register BUCKET_CONTENTS *item;
-
- if (hashing_enabled == 0)
- return;
-
- item = add_hash_item (filename, hashed_filenames);
- if (item->data)
- free (pathdata(item)->path);
- else
- {
- item->key = savestring (filename);
- item->data = xmalloc (sizeof (PATH_DATA));
- }
- pathdata(item)->path = savestring (full_pathname);
- pathdata(item)->flags = 0;
- if (check_dot)
- pathdata(item)->flags |= HASH_CHKDOT;
- if (*full_pathname != '/')
- pathdata(item)->flags |= HASH_RELPATH;
- item->times_found = found;
-}
-
static int
add_hashed_command (word, quiet)
char *word;
@@ -244,6 +153,9 @@ print_hashed_commands ()
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);
diff --git a/builtins/hashcom.h b/builtins/hashcom.h
deleted file mode 100644
index 5943b5b..0000000
--- a/builtins/hashcom.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* hashcom.h - Common defines for hashing filenames. */
-
-/* Copyright (C) 1993 Free Software Foundation, Inc.
-
- This file is part of GNU Bash, the Bourne Again SHell.
-
- Bash is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2, or (at your option) any later
- version.
-
- Bash is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License along
- with Bash; see the file COPYING. If not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "../hashlib.h"
-
-#define FILENAME_HASH_BUCKETS 631
-
-extern HASH_TABLE *hashed_filenames;
-
-typedef struct {
- char *path; /* The full pathname of the file. */
- int flags;
-} PATH_DATA;
-
-#define HASH_RELPATH 0x01 /* this filename is a relative pathname. */
-#define HASH_CHKDOT 0x02 /* check `.' since it was earlier in $PATH */
-
-#define pathdata(x) ((PATH_DATA *)(x)->data)
diff --git a/builtins/help.def b/builtins/help.def
index e5e82d5..9c47910 100644
--- a/builtins/help.def
+++ b/builtins/help.def
@@ -46,7 +46,10 @@ $END
#include <glob/fnmatch.h>
#include <glob/glob.h>
-static void show_builtin_command_help ();
+extern void builtin_error ();
+extern void builtin_usage ();
+
+static void show_builtin_command_help ();
/* 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
@@ -59,13 +62,6 @@ help_builtin (list)
char *pattern, *name;
int plen, match_found;
- if (list == 0)
- {
- show_shell_version (0);
- show_builtin_command_help ();
- return (EXECUTION_SUCCESS);
- }
-
/* Placeholder for future options. */
reset_internal_getopt ();
while ((i = internal_getopt (list, "")) != -1)
@@ -79,6 +75,13 @@ help_builtin (list)
}
list = loptend;
+ if (list == 0)
+ {
+ show_shell_version (0);
+ show_builtin_command_help ();
+ return (EXECUTION_SUCCESS);
+ }
+
/* We should consider making `help bash' do something. */
if (glob_pattern_p (list->word->word))
diff --git a/builtins/history.def b/builtins/history.def
index 939eb25..b1e3ab3 100644
--- a/builtins/history.def
+++ b/builtins/history.def
@@ -45,7 +45,7 @@ $END
#include <config.h>
#if defined (HISTORY)
-#include <sys/types.h>
+#include "../bashtypes.h"
#include <sys/file.h>
#include "../posixstat.h"
#include "../filecntl.h"
@@ -193,7 +193,7 @@ display_history (list)
if (list)
{
limited = 1;
- limit = get_numeric_arg (list);
+ limit = get_numeric_arg (list, 0);
}
else
limited = limit = 0;
@@ -259,7 +259,7 @@ push_history (list)
{
char *s;
- if (delete_last_history () == 0)
+ if (hist_last_line_added && delete_last_history () == 0)
return;
s = string_list (list);
maybe_add_history (s); /* Obeys HISTCONTROL setting. */
@@ -274,7 +274,7 @@ expand_and_print_history (list)
char *s;
int r, result;
- if (delete_last_history () == 0)
+ if (hist_last_line_added && delete_last_history () == 0)
return EXECUTION_FAILURE;
result = EXECUTION_SUCCESS;
while (list)
diff --git a/builtins/jobs.def b/builtins/jobs.def
index 2896a76..2c818af 100644
--- a/builtins/jobs.def
+++ b/builtins/jobs.def
@@ -237,14 +237,28 @@ disown_builtin (list)
list = loptend;
retval = EXECUTION_SUCCESS;
+#if 0
+ /* For the future `disown -a' */
+ if (list == 0)
+ {
+ if (nohup_only)
+ nohup_all_jobs ();
+ else
+ delete_all_jobs ();
+ return (EXECUTION_SUCCESS);
+ }
+#endif
+
do
{
BLOCK_CHILD (set, oset);
- job = get_job_spec (list);
+ job = (list && all_digits(list->word->word))
+ ? get_job_by_pid (atoi(list->word->word), 0)
+ : get_job_spec (list);
if (job == NO_JOB || jobs == 0 || jobs[job] == 0)
{
- builtin_error ("no such job %s", list->word->word);
+ builtin_error ("%s: no such job", list ? list->word->word : "current");
retval = EXECUTION_FAILURE;
}
else if (nohup_only)
@@ -257,6 +271,7 @@ disown_builtin (list)
list = list->next;
}
while (list);
+
return (retval);
}
#endif /* JOB_CONTROL */
diff --git a/builtins/kill.def b/builtins/kill.def
index ba779bf..ea78bd5 100644
--- a/builtins/kill.def
+++ b/builtins/kill.def
@@ -56,6 +56,7 @@ extern int errno;
#if defined (JOB_CONTROL)
extern int interactive;
+extern int job_control;
extern int posixly_correct;
#if !defined (CONTINUE_AFTER_KILL_ERROR)
@@ -166,7 +167,7 @@ kill_builtin (list)
builtin_error ("%s: no such pid", list->word->word);
CONTINUE_OR_FAIL;
}
- else if (interactive)
+ else if (interactive || job_control)
/* Posix.2 says you can kill without job control active (4.32.4) */
{ /* Must be a job spec. Check it out. */
int job;
diff --git a/builtins/let.def b/builtins/let.def
index 60b6675..b747962 100644
--- a/builtins/let.def
+++ b/builtins/let.def
@@ -75,6 +75,7 @@ let_builtin (list)
WORD_LIST *list;
{
long ret;
+ int expok;
if (list == 0)
{
@@ -83,17 +84,22 @@ let_builtin (list)
}
for (; list; list = list->next)
- ret = evalexp (list->word->word);
+ {
+ ret = evalexp (list->word->word, &expok);
+ if (expok == 0)
+ return (EXECUTION_FAILURE);
+ }
return ((ret == 0L) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
+#ifdef INCLUDE_UNUSED
int
exp_builtin (list)
WORD_LIST *list;
{
char *exp;
- int ret;
+ int ret, expok;
if (list == 0)
{
@@ -102,7 +108,8 @@ exp_builtin (list)
}
exp = string_list (list);
- ret = evalexp (exp);
- free (exp);
- return ((ret == 0L) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
+ ret = evalexp (exp, &expok);
+ (void)free (exp);
+ return (((ret == 0L) || (expok == 0)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
+#endif
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
index ae93bd4..983bada 100644
--- a/builtins/mkbuiltins.c
+++ b/builtins/mkbuiltins.c
@@ -25,23 +25,17 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
# include <unistd.h>
#endif
-#include "../bashansi.h"
-#include "../config.h"
-#include <stdio.h>
-#include <sys/types.h>
+#include "../bashtypes.h"
#include <sys/file.h>
-#include <sys/stat.h>
+#include "../posixstat.h"
#include "../filecntl.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else /* !HAVE_STRING_H */
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
+#include "../bashansi.h"
+#include <stdio.h>
#define DOCFILE "builtins.texi"
@@ -351,9 +345,9 @@ array_add (element, array)
(array->array, (array->size += array->growth_rate) * array->width);
#if defined (HAVE_BCOPY)
- bcopy (&element, &(array->array[array->sindex]), array->width);
+ bcopy (&element, (char *) &(array->array[array->sindex]), array->width);
array->sindex++;
- bzero (&(array->array[array->sindex]), array->width);
+ bzero ((char *) &(array->array[array->sindex]), array->width);
#else
array->array[array->sindex++] = element;
array->array[array->sindex] = (char *)NULL;
diff --git a/builtins/psize.c b/builtins/psize.c
index 0ba1c51..6037d7a 100644
--- a/builtins/psize.c
+++ b/builtins/psize.c
@@ -28,7 +28,7 @@
#endif
#include <stdio.h>
-#include <sys/types.h>
+#include "../bashtypes.h"
#include <signal.h>
#include <errno.h>
@@ -47,6 +47,7 @@ sigpipe (sig)
exit (0);
}
+int
main (argc, argv)
int argc;
char **argv;
@@ -66,4 +67,5 @@ main (argc, argv)
n = write (1, buf, 128);
nw += n;
}
+ return (0);
}
diff --git a/builtins/pushd.def b/builtins/pushd.def
index 3eadae0..87300dc 100644
--- a/builtins/pushd.def
+++ b/builtins/pushd.def
@@ -30,10 +30,12 @@ the stack, making the new top of the stack the current working
directory. With no arguments, exchanges the top two directories.
+N Rotates the stack so that the Nth directory (counting
- from the left of the list shown by `dirs') is at the top.
+ from the left of the list shown by `dirs', starting with
+ zero) is at the top.
-N Rotates the stack so that the Nth directory (counting
- from the right) is at the top.
+ from the right of the list shown by `dirs', starting with
+ zero) is at the top.
-n suppress the normal change of directory when adding directories
to the stack, so only the stack is manipulated.
@@ -257,6 +259,8 @@ pushd_builtin (list)
{
add_dirstack_element ((flags & NOCD) ? savestring (list->word->word) : current_directory);
dirs_builtin ((WORD_LIST *)NULL);
+ if (flags & NOCD)
+ free (current_directory);
return (EXECUTION_SUCCESS);
}
else
@@ -277,7 +281,9 @@ popd_builtin (list)
long which;
int flags;
char direction;
+ char *which_word;
+ which_word = (char *)NULL;
for (flags = 0, which = 0L, direction = '+'; list; list = list->next)
{
if (ISOPTION (list->word->word, 'n'))
@@ -297,6 +303,7 @@ popd_builtin (list)
builtin_usage ();
return (EXECUTION_FAILURE);
}
+ which_word = list->word->word;
}
else if (*list->word->word == '-')
{
@@ -310,7 +317,7 @@ popd_builtin (list)
if (which > directory_list_offset || (directory_list_offset == 0 && which == 0))
{
- pushd_error (directory_list_offset, list ? list->word->word : "");
+ pushd_error (directory_list_offset, which_word ? which_word : "");
return (EXECUTION_FAILURE);
}
diff --git a/builtins/read.def b/builtins/read.def
index eb04a30..64a4a11 100644
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -164,7 +164,7 @@ read_builtin (list)
{
if (rlbuf && rlbuf[rlind] == '\0')
{
- free (rlbuf);
+ xfree (rlbuf);
rlbuf = (char *)0;
}
if (rlbuf == 0)
@@ -247,13 +247,28 @@ read_builtin (list)
assign_array_var_from_word_list (var, alist);
dispose_words (alist);
}
- free (input_string);
+ xfree (input_string);
return (retval);
}
#endif /* ARRAY_VARS */
- if (!list)
+ /* If there are no variables, save the text of the line read to the
+ variable $REPLY. ksh93 strips leading and trailing IFS whitespace,
+ so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
+ same way, but I believe that the difference in behaviors is useful
+ enough to not do it. Without the bash behavior, there is no way
+ to read a line completely without interpretation or modification.
+ If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
+ if (list == 0)
{
+#if 0
+ orig_input_string = input_string;
+ for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
+ ;
+ input_string = t;
+ input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
+#endif
+
if (saw_escape)
{
t = dequote_string (input_string);
@@ -263,7 +278,11 @@ read_builtin (list)
else
var = bind_variable ("REPLY", input_string);
var->attributes &= ~att_invisible;
+#if 0
+ free (orig_input_string);
+#else
free (input_string);
+#endif
return (retval);
}
diff --git a/builtins/return.def b/builtins/return.def
index 2ab01ef..da5b76b 100644
--- a/builtins/return.def
+++ b/builtins/return.def
@@ -48,7 +48,7 @@ int
return_builtin (list)
WORD_LIST *list;
{
- return_catch_value = list ? get_numeric_arg (list) : last_command_exit_value;
+ return_catch_value = list ? get_numeric_arg (list, 1) : last_command_exit_value;
if (return_catch_flag)
longjmp (return_catch, 1);
diff --git a/builtins/set.def b/builtins/set.def
index d31e77e..74f2e5c 100644
--- a/builtins/set.def
+++ b/builtins/set.def
@@ -78,6 +78,9 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
#if defined (BANG_HISTORY)
histexpand same as -H
#endif /* BANG_HISTORY */
+#if defined (HISTORY)
+ history enable command history
+#endif
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
@@ -110,12 +113,12 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
#if defined (BRACE_EXPANSION)
-B the shell will perform brace expansion
#endif /* BRACE_EXPANSION */
+ -C If set, disallow existing regular files to be overwritten
+ by redirection of output.
#if defined (BANG_HISTORY)
-H Enable ! style history substitution. This flag is on
by default.
#endif /* BANG_HISTORY */
- -C If set, disallow existing regular files to be overwritten
- by redirection of output.
-P If set, do not follow symbolic links when executing commands
such as cd which change the current directory.
@@ -127,6 +130,7 @@ ARGs are given, all shell variables are printed.
$END
static int set_ignoreeof ();
+static int set_posix_mode ();
#if defined (READLINE)
static int set_edit_mode ();
@@ -183,7 +187,7 @@ struct {
#endif
{ "ignoreeof", &ignoreeof, set_ignoreeof, (Function *)NULL },
{ "interactive-comments", &interactive_comments, (Function *)NULL, (Function *)NULL },
- { "posix", &posixly_correct, (Function *)NULL, (Function *)NULL },
+ { "posix", &posixly_correct, set_posix_mode, (Function *)NULL },
#if defined (READLINE)
{ "emacs", (int *)NULL, set_edit_mode, get_edit_mode },
{ "vi", (int *)NULL, set_edit_mode, get_edit_mode },
@@ -283,6 +287,20 @@ set_ignoreeof (on_or_off, option_name)
return 0;
}
+static int
+set_posix_mode (on_or_off, option_name)
+ int on_or_off;
+ char *option_name;
+{
+ posixly_correct = on_or_off == FLAG_ON;
+ if (posixly_correct == 0)
+ unbind_variable ("POSIXLY_CORRECT");
+ else
+ bind_variable ("POSIXLY_CORRECT", "y");
+ sv_strict_posix ("POSIXLY_CORRECT");
+ return (0);
+}
+
#if defined (READLINE)
/* Magic. This code `knows' how readline handles rl_editing_mode. */
static int
@@ -435,7 +453,9 @@ set_shellopts ()
vptr += strlen (binary_o_options[i].name);
value[vptr++] = ':';
}
- value[--vptr] = '\0'; /* cut off trailing colon */
+ if (vptr)
+ vptr--; /* cut off trailing colon */
+ value[vptr] = '\0';
v = find_variable ("SHELLOPTS");
if (v)
@@ -465,15 +485,34 @@ void
initialize_shell_options ()
{
char *temp;
+ SHELL_VAR *var;
+ var = find_variable ("SHELLOPTS");
/* set up any shell options we may have inherited. */
- if (temp = get_string_value ("SHELLOPTS"))
- parse_shellopts (temp);
+ if (var && imported_p (var))
+ {
+ temp = (array_p (var)) ? (char *)NULL : savestring (value_cell (var));
+ if (temp)
+ {
+ parse_shellopts (temp);
+ free (temp);
+ }
+ }
/* Set up the $SHELLOPTS variable. */
set_shellopts ();
}
+/* Reset the values of the -o options that are not also shell flags. */
+void
+reset_shell_options ()
+{
+#if defined (HISTORY)
+ remember_on_history = 1;
+#endif
+ ignoreeof = posixly_correct = 0;
+}
+
/* Set some flags from the word values in the input list. If LIST is empty,
then print out the values of the variables instead. If LIST contains
non-flags, then set $1 - $9 to the successive words of LIST. */
@@ -691,6 +730,12 @@ unset_builtin (list)
}
#endif
+ if (legal_identifier (name) == 0)
+ {
+ builtin_error ("`%s': not a valid identifier", name);
+ NEXT_VARIABLE ();
+ }
+
var = unset_function ? find_function (name) : find_variable (name);
if (var && !unset_function && non_unsettable_p (var))
diff --git a/builtins/setattr.def b/builtins/setattr.def
index a83f348..e465eec 100644
--- a/builtins/setattr.def
+++ b/builtins/setattr.def
@@ -34,8 +34,17 @@ $PRODUCES setattr.c
#include "common.h"
#include "bashgetopt.h"
+extern int posixly_correct;
extern int array_needs_making;
extern char *this_command_name;
+extern Function *this_shell_builtin;
+
+#ifdef ARRAY_VARS
+extern int declare_builtin ();
+#endif
+
+#define READONLY_OR_EXPORT \
+ (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
$BUILTIN export
$FUNCTION export_builtin
@@ -94,6 +103,10 @@ set_or_show_attributes (list, attribute, nodefs)
register SHELL_VAR *var;
int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt;
char *name;
+#if defined (ARRAY_VARS)
+ WORD_LIST *nlist, *tlist;
+ WORD_DESC *w;
+#endif
undo = functions_only = arrays_only = any_failed = assign_error = 0;
/* Read arguments from the front of the list. */
@@ -159,7 +172,10 @@ set_or_show_attributes (list, attribute, nodefs)
if (legal_identifier (name) == 0)
{
builtin_error ("`%s': not a valid identifier", name);
- assign_error++;
+ if (assign)
+ assign_error++;
+ else
+ any_failed++;
list = list->next;
continue;
}
@@ -167,6 +183,24 @@ set_or_show_attributes (list, attribute, nodefs)
if (assign) /* xxx [-np] name=value */
{
name[assign] = '=';
+#if defined (ARRAY_VARS)
+ /* Let's try something here. Turn readonly -a xxx=yyy into
+ declare -ra xxx=yyy and see what that gets us. */
+ if (arrays_only)
+ {
+ tlist = list->next;
+ list->next = (WORD_LIST *)NULL;
+ w = make_word ("-ra");
+ nlist = make_word_list (w, list);
+ opt = declare_builtin (nlist);
+ if (opt != EXECUTION_SUCCESS)
+ assign_error++;
+ list->next = tlist;
+ dispose_word (w);
+ free (nlist);
+ }
+ else
+#endif
/* This word has already been expanded once with command
and parameter expansion. Call do_assignment_no_expand (),
which does not do command or parameter substitution. If
@@ -212,7 +246,7 @@ set_or_show_attributes (list, attribute, nodefs)
continue;
#endif
if ((var->attributes & attribute) && invisible_p (var) == 0)
- show_var_attributes (var, nodefs);
+ show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
}
free (variable_list);
}
@@ -223,43 +257,70 @@ set_or_show_attributes (list, attribute, nodefs)
: EXECUTION_FAILURE));
}
+/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
+ don't show function definitions along with the name. If PATTR is
+ non-zero, it indicates we're being called from `export' or `readonly'.
+ In POSIX mode, this prints the name of the calling builtin (`export'
+ or `readonly') instead of `declare', and doesn't print function defs
+ when called by `export' or `readonly'. */
int
-show_var_attributes (var, nodefs)
+show_var_attributes (var, pattr, nodefs)
SHELL_VAR *var;
- int nodefs;
+ int pattr, nodefs;
{
char flags[6], *x;
int i;
i = 0;
+ /* pattr == 0 means we are called from `declare'. */
+ if (pattr == 0 || posixly_correct == 0)
+ {
#if defined (ARRAY_VARS)
- if (array_p (var))
- flags[i++] = 'a';
+ if (array_p (var))
+ flags[i++] = 'a';
#endif
- if (function_p (var))
- flags[i++] = 'f';
+ if (function_p (var))
+ flags[i++] = 'f';
- if (integer_p (var))
- flags[i++] = 'i';
+ if (integer_p (var))
+ flags[i++] = 'i';
- if (readonly_p (var))
- flags[i++] = 'r';
+ if (readonly_p (var))
+ flags[i++] = 'r';
- if (exported_p (var))
- flags[i++] = 'x';
+ if (exported_p (var))
+ flags[i++] = 'x';
+ }
+ else
+ {
+#if defined (ARRAY_VARS)
+ if (array_p (var))
+ flags[i++] = 'a';
+#endif
+
+ if (function_p (var))
+ flags[i++] = 'f';
+ }
flags[i] = '\0';
- printf ("declare -%s ", i ? flags : "-");
+ if (pattr == 0 || posixly_correct == 0)
+ printf ("declare -%s ", i ? flags : "-");
+ else if (i)
+ printf ("%s -%s ", this_command_name, flags);
+ else
+ printf ("%s ", this_command_name);
#if defined (ARRAY_VARS)
if (array_p (var))
print_array_assignment (var, 1);
else
#endif
- if (nodefs)
+ /* force `readline' 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);
else if (function_p (var))
printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
@@ -285,7 +346,7 @@ show_name_attributes (name, nodefs)
if (var && invisible_p (var) == 0)
{
- show_var_attributes (var, nodefs);
+ show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
}
else
diff --git a/builtins/shift.def b/builtins/shift.def
index 8af4d5d..293c31b 100644
--- a/builtins/shift.def
+++ b/builtins/shift.def
@@ -53,7 +53,7 @@ shift_builtin (list)
register int count;
WORD_LIST *temp;
- times = get_numeric_arg (list);
+ times = get_numeric_arg (list, 0);
if (times == 0)
return (EXECUTION_SUCCESS);
diff --git a/builtins/shopt.def b/builtins/shopt.def
index 5372bbb..bc26a96 100644
--- a/builtins/shopt.def
+++ b/builtins/shopt.def
@@ -61,15 +61,17 @@ extern int cdspelling, expand_aliases;
extern int check_window_size;
#if defined (HISTORY)
-extern int hist_verify, literal_history, command_oriented_history;
+extern int literal_history, command_oriented_history;
extern int force_append_history;
#endif
#if defined (READLINE)
-extern int history_reediting, perform_hostname_completion;
+extern int hist_verify, history_reediting, perform_hostname_completion;
extern void enable_hostname_completion ();
#endif
+extern void set_shellopts ();
+
static int set_interactive_comments ();
static struct {
@@ -92,9 +94,9 @@ static struct {
#endif
#if defined (HISTORY)
{ "histappend", &force_append_history, (Function *)NULL },
- { "histverify", &hist_verify, (Function *)NULL },
#endif
#if defined (READLINE)
+ { "histverify", &hist_verify, (Function *)NULL },
{ "hostcomplete", &perform_hostname_completion, (Function *)enable_hostname_completion },
#endif
{ "interactive_comments", &interactive_comments, set_interactive_comments },
@@ -178,6 +180,29 @@ shopt_builtin (list)
return (rval);
}
+/* Reset the options managed by `shopt' to the values they would have at
+ shell startup. */
+void
+reset_shopt_options ()
+{
+ allow_null_glob_expansion = glob_dot_filenames = 0;
+ cdable_vars = mail_warning = 0;
+ no_exit_on_failed_exec = print_shift_error = 0;
+ check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
+
+ source_uses_path = promptvars = 1;
+
+#if defined (HISTORY)
+ literal_history = force_append_history = 0;
+ command_oriented_history = 1;
+#endif
+
+#if defined (READLINE)
+ hist_verify = history_reediting = 0;
+ perform_hostname_completion = 1;
+#endif
+}
+
static int
find_shopt (name)
char *name;
diff --git a/builtins/suspend.def b/builtins/suspend.def
index 151c34d..82ec71b 100644
--- a/builtins/suspend.def
+++ b/builtins/suspend.def
@@ -46,7 +46,10 @@ $END
extern int job_control;
-static SigHandler *old_cont, *old_stop;
+static SigHandler *old_cont;
+#if 0
+static SigHandler *old_stop;
+#endif
/* Continue handler. */
sighandler
diff --git a/builtins/trap.def b/builtins/trap.def
index f6a8ee4..2d5daca 100644
--- a/builtins/trap.def
+++ b/builtins/trap.def
@@ -23,17 +23,17 @@ $PRODUCES trap.c
$BUILTIN trap
$FUNCTION trap_builtin
-$SHORT_DOC trap [arg] [signal_spec] or trap -l
+$SHORT_DOC trap [arg] [signal_spec ...] or trap -l
The command ARG is to be read and executed when the shell receives
signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are
reset to their original values. If ARG is the null string each
SIGNAL_SPEC is ignored by the shell and by the commands it invokes.
-If SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from
-the shell. If SIGNAL_SPEC is DEBUG, ARG is executed after every
+If a SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from
+the shell. If a SIGNAL_SPEC is DEBUG, ARG is executed after every
command. If ARG is `-p' then the trap commands associated with
each SIGNAL_SPEC are displayed. If no arguments are supplied or if
only `-p' is given, trap prints the list of commands associated with
-each signal number. SIGNAL_SPEC is either a signal name in <signal.h>
+each signal number. Each SIGNAL_SPEC is either a signal name in <signal.h>
or a signal number. `trap -l' prints a list of signal names and their
corresponding numbers. Note that a signal can be sent to the shell
with "kill -signal $$".
@@ -115,7 +115,8 @@ trap_builtin (list)
operation = SET;
first_arg = list->word->word;
- if (first_arg && *first_arg && signal_object_p (first_arg))
+ if (first_arg && *first_arg && (*first_arg != '-' || first_arg[1]) &&
+ signal_object_p (first_arg))
operation = REVERT;
else
{
diff --git a/builtins/type.def b/builtins/type.def
index 5e828c6..3af018f 100644
--- a/builtins/type.def
+++ b/builtins/type.def
@@ -57,6 +57,7 @@ $END
#include "../shell.h"
#include "../execute_cmd.h"
+#include "../hashcmd.h"
#if defined (ALIAS)
#include "../alias.h"
@@ -307,6 +308,7 @@ describe_command (command, verbose, all)
else if (verbose == 3 || verbose == 4)
printf ("%s\n", full_path);
+ free (full_path);
return (1);
}
}
diff --git a/builtins/ulimit.def b/builtins/ulimit.def
index 546dfd4..3cdf26a 100644
--- a/builtins/ulimit.def
+++ b/builtins/ulimit.def
@@ -35,7 +35,7 @@ option is given, it is interpreted as follows:
-c the maximum size of core files created
-d the maximum size of a process's data segment
-f the maximum size of files created by the shell
- -l the maximum size a process may lock into memory
+ -l the maximum size a process may lock into memory
-m the maximum resident set size
-n the maximum number of open file descriptors
-p the pipe buffer size
@@ -215,6 +215,17 @@ static ULCMD *cmdlist;
static int ncmd;
static int cmdlistsz;
+#if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
+long
+ulimit (cmd, newlim)
+ int cmd;
+ long newlim;
+{
+ errno = EINVAL;
+ return -1;
+}
+#endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
+
static int
_findlim (opt)
int opt;
@@ -368,6 +379,12 @@ ulimit_internal (cmd, cmdarg, mode, multiple)
block_factor = (limit == RLIM_INFINITY) ? 1 : limits[limind].block_factor;
real_limit = limit * block_factor;
+ if (real_limit < 0 || (real_limit == 0 && limit != 0))
+ {
+ builtin_error ("limit out of range: %d", limit);
+ return (EXECUTION_FAILURE);
+ }
+
if (set_limit (limind, real_limit, mode) < 0)
{
builtin_error ("cannot modify limit: %s", strerror (errno));
@@ -444,6 +461,9 @@ set_limit (ind, newlim, mode)
case RLIMIT_FILESIZE:
#if !defined (HAVE_RESOURCE)
return (ulimit (2, newlim / 512L));
+#else
+ errno = EINVAL;
+ return -1;
#endif
case RLIMIT_OPENFILES:
@@ -462,8 +482,9 @@ set_limit (ind, newlim, mode)
#if defined (HAVE_RESOURCE)
if (getrlimit (limits[ind].parameter, &limit) < 0)
return -1;
- val = (current_user.euid != 0 && newlim == RLIM_INFINITY)
- ? limit.rlim_max : newlim;
+ val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
+ (limit.rlim_cur <= limit.rlim_max))
+ ? limit.rlim_max : newlim;
if (mode & LIMIT_SOFT)
limit.rlim_cur = val;
if (mode & LIMIT_HARD)
diff --git a/builtins/umask.def b/builtins/umask.def
index 5ef8f3b..85bf220 100644
--- a/builtins/umask.def
+++ b/builtins/umask.def
@@ -64,6 +64,7 @@ umask_builtin (list)
WORD_LIST *list;
{
int print_symbolically, opt, umask_value;
+ mode_t umask_arg;
print_symbolically = 0;
reset_internal_getopt ();
@@ -105,19 +106,20 @@ umask_builtin (list)
if (umask_value == -1)
return (EXECUTION_FAILURE);
}
- umask (umask_value);
+ umask_arg = (mode_t)umask_value;
+ umask (umask_arg);
if (print_symbolically)
- print_symbolic_umask (umask_value);
+ print_symbolic_umask (umask_arg);
}
else /* Display the UMASK for this user. */
{
- umask_value = umask (022);
- umask (umask_value);
+ umask_arg = umask (022);
+ umask (umask_arg);
if (print_symbolically)
- print_symbolic_umask (umask_value);
+ print_symbolic_umask (umask_arg);
else
- printf ("%03o\n", umask_value);
+ printf ("%03o\n", umask_arg);
}
fflush (stdout);
@@ -128,7 +130,7 @@ umask_builtin (list)
printed if the corresponding bit is clear in the umask. */
static void
print_symbolic_umask (um)
- int um;
+ mode_t um;
{
char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */
int i;
@@ -267,9 +269,12 @@ symbolic_umask (list)
umc |= perm;
break;
+#if 0
+ /* No other values are possible. */
default:
builtin_error ("bad symbolic mode operator: %c", op);
return (-1);
+#endif
}
if (!*s)
diff --git a/builtins/wait.def b/builtins/wait.def
index b9290d9..741ff5c 100644
--- a/builtins/wait.def
+++ b/builtins/wait.def
@@ -50,9 +50,12 @@ $END
# include <unistd.h>
#endif
+#include "../bashansi.h"
+
#include "../shell.h"
#include "../jobs.h"
#include "common.h"
+#include "bashgetopt.h"
extern int interrupt_immediately;
@@ -71,6 +74,8 @@ wait_builtin (list)
if (no_options (list))
return (EX_USAGE);
+ if (list != loptend)
+ list = loptend;
begin_unwind_frame ("wait_builtin");
unwind_protect_int (interrupt_immediately);