summaryrefslogtreecommitdiff
path: root/builtins
diff options
context:
space:
mode:
Diffstat (limited to 'builtins')
-rw-r--r--builtins/Makefile.in20
-rw-r--r--builtins/caller.def9
-rw-r--r--builtins/cd.def62
-rw-r--r--builtins/command.def10
-rw-r--r--builtins/common.c27
-rw-r--r--builtins/common.h2
-rw-r--r--builtins/declare.def28
-rw-r--r--builtins/echo.def8
-rw-r--r--builtins/evalfile.c12
-rw-r--r--builtins/evalstring.c14
-rw-r--r--builtins/exec.def3
-rw-r--r--builtins/exit.def4
-rw-r--r--builtins/fc.def62
-rw-r--r--builtins/fg_bg.def32
-rw-r--r--builtins/getopts.def12
-rw-r--r--builtins/hash.def11
-rw-r--r--builtins/help.def2
-rw-r--r--builtins/history.def30
-rw-r--r--builtins/jobs.def12
-rw-r--r--builtins/kill.def14
-rw-r--r--builtins/mkbuiltins.c91
-rw-r--r--builtins/printf.def192
-rw-r--r--builtins/psize.c3
-rw-r--r--builtins/pushd.def51
-rw-r--r--builtins/read.def53
-rw-r--r--builtins/reserved.def31
-rw-r--r--builtins/set.def12
-rw-r--r--builtins/setattr.def23
-rw-r--r--builtins/shopt.def9
-rw-r--r--builtins/trap.def3
-rw-r--r--builtins/type.def18
-rw-r--r--builtins/ulimit.def37
-rw-r--r--builtins/wait.def4
33 files changed, 644 insertions, 257 deletions
diff --git a/builtins/Makefile.in b/builtins/Makefile.in
index 4bb4ea5e..965b8bd8 100644
--- a/builtins/Makefile.in
+++ b/builtins/Makefile.in
@@ -1,6 +1,6 @@
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
#
-# Copyright (C) 1996-2003 Free Software Foundation, Inc.
+# Copyright (C) 1996-2005 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -54,7 +54,7 @@ LIBBUILD = ${BUILD_DIR}/lib
PROFILE_FLAGS = @PROFILE_FLAGS@
CFLAGS = @CFLAGS@
-CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ @CROSS_COMPILE@
CPPFLAGS = @CPPFLAGS@
CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
@@ -96,6 +96,7 @@ GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
MKBUILTINS = mkbuiltins$(EXEEXT)
DIRECTDEFINE = -D $(srcdir)
HELPDIRDEFINE = @HELPDIRDEFINE@
+HELPSTRINGS = @HELPSTRINGS@
# xxx this is bad style
RL_LIBSRC = $(topdir)/lib/readline
@@ -160,7 +161,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) $(HELPDIRDEFINE) $(DEFSRC)
+ -noproduction $(DIRECTDEFINE) $(HELPDIRDEFINE) $(HELPSTRINGS) $(DEFSRC)
@-if cmp -s old-builtext.h builtext.h 2>/dev/null; then \
mv old-builtext.h builtext.h; \
else \
@@ -178,8 +179,7 @@ helpdoc: $(MKBUILTINS) $(DEFSRC)
install-help:
@-if test -n "${HELPDIR}" && test -d helpfiles ; then \
test -d ${HELPDIR} || ${SHELL} ${MKDIRS} $(DESTDIR)$(HELPDIR) ;\
- ( cd helpfiles ; \
- for f in *; do \
+ ( for f in helpfiles/*; do \
echo installing $$f; \
${INSTALL_DATA} $$f $(DESTDIR)$(HELPDIR); \
done; ) ; \
@@ -404,12 +404,12 @@ 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)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
exec.o: $(srcdir)/common.h $(topdir)/execute_cmd.h $(BASHINCDIR)/maxpath.h
-exec.o: $(topdir)/findcmd.h
+exec.o: $(topdir)/findcmd.h $(topdir)/jobs.h
exit.o: $(topdir)/bashtypes.h
exit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
exit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.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)/subst.h $(topdir)/externs.h $(topdir)/jobs.h
exit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
exit.o: $(BASHINCDIR)/maxpath.h ./builtext.h
fc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
@@ -427,6 +427,7 @@ 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
fg_bg.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
fg_bg.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
+fg_bg.o: $(topdir)/jobs.h
getopts.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
getopts.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
getopts.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -458,7 +459,7 @@ inlib.o: $(BASHINCDIR)/maxpath.h $(topdir)/subst.h $(topdir)/externs.h
inlib.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
jobs.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
jobs.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(srcdir)/bashgetopt.h
-jobs.o: $(BASHINCDIR)/maxpath.h $(topdir)/externs.h
+jobs.o: $(BASHINCDIR)/maxpath.h $(topdir)/externs.h $(topdir)/jobs.h
jobs.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
jobs.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
kill.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
@@ -466,6 +467,7 @@ kill.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/exte
kill.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
kill.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/trap.h $(topdir)/unwind_prot.h
kill.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/maxpath.h
+kill.o: $(topdir)/jobs.h
let.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
let.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
let.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -525,6 +527,7 @@ suspend.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
suspend.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
suspend.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
suspend.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
+suspend.o: $(topdir)/jobs.h
test.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
test.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
test.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
@@ -565,6 +568,7 @@ wait.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
wait.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
wait.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
wait.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
+wait.o: $(topdir)/jobs.h
wait.o: $(BASHINCDIR)/chartypes.h
shopt.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
shopt.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
diff --git a/builtins/caller.def b/builtins/caller.def
index d372c588..5142cab9 100644
--- a/builtins/caller.def
+++ b/builtins/caller.def
@@ -55,6 +55,7 @@ $END
#include "../shell.h"
#include "common.h"
#include "builtext.h"
+#include "bashgetopt.h"
#ifdef LOADABLE_BUILTIN
# include "builtins.h"
@@ -88,6 +89,10 @@ caller_builtin (list)
if (bash_source_a == 0 || array_empty (bash_source_a))
return (EXECUTION_FAILURE);
+ if (no_options (list))
+ return (EX_USAGE);
+ list = loptend; /* skip over possible `--' */
+
/* If there is no argument list, then give short form: line filename. */
if (list == 0)
{
@@ -125,11 +130,11 @@ caller_builtin (list)
#ifdef LOADABLE_BUILTIN
static char *caller_doc[] = {
N_("Returns the context of the current subroutine call."),
- N_(""),
+ N_(" "),
N_("Without EXPR, returns returns \"$line $filename\". With EXPR,"),
N_("returns \"$line $subroutine $filename\"; this extra information"),
N_("can be used used to provide a stack trace."),
- N_(""),
+ N_(" "),
N_("The value of EXPR indicates how many call frames to go back before the"),
N_("current one; the top frame is frame 0."),
(char *)NULL
diff --git a/builtins/cd.def b/builtins/cd.def
index 2be86d11..025e4f5e 100644
--- a/builtins/cd.def
+++ b/builtins/cd.def
@@ -1,7 +1,7 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" in Bash.
-Copyright (C) 1987-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -59,6 +59,7 @@ extern int array_needs_making;
extern char *bash_getcwd_errstr;
static int bindpwd __P((int));
+static void setpwd __P((char *));
static int change_to_directory __P((char *, int));
static char *cdspell __P((char *));
@@ -84,6 +85,23 @@ instead of following symbolic links; the -L option forces symbolic links
to be followed.
$END
+/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */
+static void
+setpwd (dirname)
+ char *dirname;
+{
+ int old_anm;
+ SHELL_VAR *tvar;
+
+ old_anm = array_needs_making;
+ tvar = bind_variable ("PWD", dirname ? dirname : "", 0);
+ if (old_anm == 0 && array_needs_making && exported_p (tvar))
+ {
+ update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
+ array_needs_making = 0;
+ }
+}
+
static int
bindpwd (no_symlinks)
int no_symlinks;
@@ -100,19 +118,14 @@ bindpwd (no_symlinks)
old_anm = array_needs_making;
pwdvar = get_string_value ("PWD");
- tvar = bind_variable ("OLDPWD", pwdvar);
+ tvar = bind_variable ("OLDPWD", pwdvar, 0);
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
array_needs_making = 0;
}
- tvar = bind_variable ("PWD", dirname ? dirname : "");
- if (old_anm == 0 && array_needs_making && exported_p (tvar))
- {
- update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
- array_needs_making = 0;
- }
+ setpwd (dirname);
if (dirname && dirname != the_current_working_directory)
free (dirname);
@@ -233,9 +246,13 @@ cd_builtin (list)
printf ("%s\n", path);
free (temp);
+#if 0
/* Posix.2 says that after using CDPATH, the resultant
value of $PWD will not contain `.' or `..'. */
return (bindpwd (posixly_correct || no_symlinks));
+#else
+ return (bindpwd (no_symlinks));
+#endif
}
else
free (temp);
@@ -298,7 +315,7 @@ cd_builtin (list)
$BUILTIN pwd
$FUNCTION pwd_builtin
-$SHORT_DOC pwd [-PL]
+$SHORT_DOC pwd [-LP]
Print the current working directory. With the -P option, pwd prints
the physical directory, without any symbolic links; the -L option
makes pwd follow symbolic links.
@@ -314,16 +331,17 @@ pwd_builtin (list)
WORD_LIST *list;
{
char *directory;
- int opt;
+ int opt, pflag;
verbatim_pwd = no_symbolic_links;
+ pflag = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "LP")) != -1)
{
switch (opt)
{
case 'P':
- verbatim_pwd = 1;
+ verbatim_pwd = pflag = 1;
break;
case 'L':
verbatim_pwd = 0;
@@ -342,7 +360,8 @@ pwd_builtin (list)
/* Try again using getcwd() if canonicalization fails (for instance, if
the file system has changed state underneath bash). */
- if (tcwd && directory == 0)
+ if ((tcwd && directory == 0) ||
+ (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
directory = resetpwd ("pwd");
#undef tcwd
@@ -350,12 +369,15 @@ pwd_builtin (list)
if (directory)
{
printf ("%s\n", directory);
+ /* This is dumb but posix-mandated. */
+ if (posixly_correct && pflag)
+ setpwd (directory);
if (directory != the_current_working_directory)
free (directory);
fflush (stdout);
if (ferror (stdout))
{
- builtin_error (_("write error: %s"), strerror (errno));
+ sh_wrerror ();
clearerr (stdout);
return (EXECUTION_FAILURE);
}
@@ -378,7 +400,7 @@ change_to_directory (newdir, nolinks)
int nolinks;
{
char *t, *tdir;
- int err, canon_failed, r;
+ int err, canon_failed, r, ndlen, dlen;
tdir = (char *)NULL;
@@ -396,6 +418,9 @@ change_to_directory (newdir, nolinks)
tdir = nolinks ? sh_physpath (t, 0)
: sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
+ ndlen = strlen (newdir);
+ dlen = strlen (t);
+
/* Use the canonicalized version of NEWDIR, or, if canonicalization
failed, use the non-canonical form. */
canon_failed = 0;
@@ -411,7 +436,7 @@ change_to_directory (newdir, nolinks)
/* 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)
+ if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
{
#if defined ENAMETOOLONG
if (errno != ENOENT && errno != ENAMETOOLONG)
@@ -419,6 +444,7 @@ change_to_directory (newdir, nolinks)
if (errno != ENOENT)
#endif
errno = ENOTDIR;
+ free (tdir);
return (0);
}
@@ -436,13 +462,17 @@ change_to_directory (newdir, nolinks)
else
set_working_directory (tdir);
+ free (tdir);
return (1);
}
/* We failed to change to the appropriate directory name. If we tried
what the user passed (nolinks != 0), punt now. */
if (nolinks)
- return (0);
+ {
+ free (tdir);
+ return (0);
+ }
err = errno;
diff --git a/builtins/command.def b/builtins/command.def
index dcbbec14..dbc1e9a1 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-2002 Free Software Foundation, Inc.
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -78,7 +78,7 @@ command_builtin (list)
use_standard_path = 1;
break;
case 'V':
- verbose = CDESC_SHORTDESC; /* look in common.h for constants */
+ verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */
break;
case 'v':
verbose = CDESC_REUSABLE; /* ditto */
@@ -101,7 +101,7 @@ command_builtin (list)
{
found = describe_command (list->word->word, verbose);
- if (found == 0)
+ if (found == 0 && verbose != CDESC_REUSABLE)
sh_notfound (list->word->word);
any_found += found;
@@ -131,7 +131,7 @@ command_builtin (list)
add_unwind_protect ((Function *)restore_path, old_path);
standard_path = get_standard_path ();
- bind_variable ("PATH", standard_path ? standard_path : "");
+ bind_variable ("PATH", standard_path ? standard_path : "", 0);
FREE (standard_path);
}
@@ -170,7 +170,7 @@ restore_path (var)
{
if (var)
{
- bind_variable ("PATH", var);
+ bind_variable ("PATH", var, 0);
free (var);
}
else
diff --git a/builtins/common.c b/builtins/common.c
index 3d3dd594..9d8f09ab 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -270,6 +270,12 @@ sh_notbuiltin (s)
builtin_error (_("%s: not a shell builtin"), s);
}
+void
+sh_wrerror ()
+{
+ builtin_error (_("write error: %s"), strerror (errno));
+}
+
/* **************************************************************** */
/* */
/* Shell positional parameter manipulation */
@@ -508,15 +514,17 @@ get_job_by_name (name, flags)
{
register int i, wl, cl, match, job;
register PROCESS *p;
+ register JOB *j;
job = NO_JOB;
wl = strlen (name);
- for (i = job_slots - 1; i >= 0; i--)
+ for (i = js.j_jobslots - 1; i >= 0; i--)
{
- if (jobs[i] == 0 || ((flags & JM_STOPPED) && JOBSTATE(i) != JSTOPPED))
+ j = get_job_by_jid (i);
+ if (j == 0 || ((flags & JM_STOPPED) && J_JOBSTATE(j) != JSTOPPED))
continue;
- p = jobs[i]->pipe;
+ p = j->pipe;
do
{
if (flags & JM_EXACT)
@@ -547,7 +555,7 @@ get_job_by_name (name, flags)
else
job = i;
}
- while (p != jobs[i]->pipe);
+ while (p != j->pipe);
}
return (job);
@@ -562,7 +570,7 @@ get_job_spec (list)
int job, jflags;
if (list == 0)
- return (current_job);
+ return (js.j_current);
word = list->word->word;
@@ -575,20 +583,19 @@ get_job_spec (list)
if (DIGIT (*word) && all_digits (word))
{
job = atoi (word);
- return (job > job_slots ? NO_JOB : job - 1);
+ return (job > js.j_jobslots ? NO_JOB : job - 1);
}
jflags = 0;
switch (*word)
{
case 0:
- return NO_JOB;
case '%':
case '+':
- return (current_job);
+ return (js.j_current);
case '-':
- return (previous_job);
+ return (js.j_previous);
case '?': /* Substring search requested. */
jflags |= JM_SUBSTRING;
diff --git a/builtins/common.h b/builtins/common.h
index 411ce1eb..df303252 100644
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -40,6 +40,7 @@
#define CDESC_PATH_ONLY 0x010 /* type -p */
#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */
#define CDESC_NOFUNCS 0x040 /* type -f */
+#define CDESC_ABSPATH 0x080 /* convert to absolute path, no ./ */
/* Flags for get_job_by_name */
#define JM_PREFIX 0x01 /* prefix of job name */
@@ -76,6 +77,7 @@ extern void sh_readonly __P((const char *));
extern void sh_nojobs __P((char *));
extern void sh_restricted __P((char *));
extern void sh_notbuiltin __P((char *));
+extern void sh_wrerror __P((void));
extern char **make_builtin_argv __P((WORD_LIST *, int *));
extern void remember_args __P((WORD_LIST *, int));
diff --git a/builtins/declare.def b/builtins/declare.def
index fe112dd6..d94118f5 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -222,18 +222,24 @@ declare_internal (list, local_var)
while (list) /* declare [-afFirx] name [name ...] */
{
char *value, *name;
- int offset;
+ int offset, aflags;
#if defined (ARRAY_VARS)
int making_array_special, compound_array_assign, simple_array_assign;
#endif
name = savestring (list->word->word);
offset = assignment (name, 0);
+ aflags = 0;
if (offset) /* declare [-afFirx] name=value */
{
name[offset] = '\0';
value = name + offset + 1;
+ if (name[offset - 1] == '+')
+ {
+ aflags |= ASS_APPEND;
+ name[offset - 1] = '\0';
+ }
}
else
value = "";
@@ -353,7 +359,7 @@ declare_internal (list, local_var)
var = make_new_array_variable (name);
else
#endif
- var = bind_variable (name, "");
+ var = bind_variable (name, "", 0);
}
/* Cannot use declare +r to turn off readonly attribute. */
@@ -377,7 +383,13 @@ declare_internal (list, local_var)
#if defined (ARRAY_VARS)
if ((making_array_special || (flags_on & att_array) || array_p (var)) && offset)
{
+ int vlen;
+ vlen = STRLEN (value);
+#if 0
if (value[0] == '(' && strchr (value, ')'))
+#else
+ if (value[0] == '(' && value[vlen-1] == ')')
+#endif
compound_array_assign = 1;
else
simple_array_assign = 1;
@@ -401,23 +413,23 @@ declare_internal (list, local_var)
#if defined (ARRAY_VARS)
if (offset && compound_array_assign)
- assign_array_var_from_string (var, value);
+ assign_array_var_from_string (var, value, aflags);
else if (simple_array_assign && subscript_start)
{
/* declare [-a] name[N]=value */
*subscript_start = '['; /* ] */
- var = assign_array_element (name, value);
+ var = assign_array_element (name, value, 0); /* XXX - not aflags */
*subscript_start = '\0';
}
else if (simple_array_assign)
/* let bind_array_variable take care of this. */
- bind_array_variable (name, 0, value);
+ bind_array_variable (name, 0, value, aflags);
else
#endif
/* bind_variable_value duplicates the essential internals of
bind_variable() */
if (offset)
- bind_variable_value (var, value);
+ bind_variable_value (var, value, aflags);
/* If we found this variable in the temporary environment, as with
`var=value declare -x var', make sure it is treated identically
@@ -437,7 +449,7 @@ declare_internal (list, local_var)
if (tv)
{
tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring ("");
- tv = bind_variable (var->name, tvalue);
+ tv = bind_variable (var->name, tvalue, 0);
tv->attributes |= var->attributes & ~att_tempvar;
if (tv->context > 0)
VSETATTR (tv, att_propagate);
diff --git a/builtins/echo.def b/builtins/echo.def
index a91c8e4c..6792659a 100644
--- a/builtins/echo.def
+++ b/builtins/echo.def
@@ -72,12 +72,14 @@ $END
existing system shells won't barf. Regrettably, the SUS v2 has
standardized the Sys V echo behavior. This variable is external
so that we can have a `shopt' variable to control it at runtime. */
-#if defined (DEFAULT_ECHO_TO_XPG)
+#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
int xpg_echo = 1;
#else
int xpg_echo = 0;
#endif /* DEFAULT_ECHO_TO_XPG */
+extern int posixly_correct;
+
/* Print the words in LIST to standard output. If the first word is
`-n', then don't print a trailing newline. We also support the
echo syntax from Version 9 Unix systems. */
@@ -91,6 +93,9 @@ echo_builtin (list)
do_v9 = xpg_echo;
display_return = 1;
+ if (posixly_correct && xpg_echo)
+ goto just_echo;
+
for (; list && (temp = list->word->word) && *temp == '-'; list = list->next)
{
/* If it appears that we are handling options, then make sure that
@@ -170,6 +175,7 @@ just_echo:
fflush (stdout);
if (ferror (stdout))
{
+ sh_wrerror ();
clearerr (stdout);
return (EXECUTION_FAILURE);
}
diff --git a/builtins/evalfile.c b/builtins/evalfile.c
index c17e547b..81be017b 100644
--- a/builtins/evalfile.c
+++ b/builtins/evalfile.c
@@ -39,6 +39,7 @@
#include "../flags.h"
#include "../input.h"
#include "../execute_cmd.h"
+#include "../trap.h"
#if defined (HISTORY)
# include "../bashhist.h"
@@ -82,7 +83,7 @@ _evalfile (filename, flags)
size_t file_size;
sh_vmsg_func_t *errfunc;
#if defined (ARRAY_VARS)
- SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
+ SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
# if defined (DEBUGGER)
SHELL_VAR *bash_argv_v, *bash_argc_v;
@@ -246,9 +247,16 @@ file_error_and_exit:
}
#if defined (ARRAY_VARS)
+ /* These two variables cannot be unset, and cannot be affected by the
+ sourced file. */
array_pop (bash_source_a);
array_pop (bash_lineno_a);
- array_pop (funcname_a);
+
+ /* FUNCNAME can be unset, and so can potentially be changed by the
+ sourced file. */
+ GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
+ if (nfv == funcname_v)
+ array_pop (funcname_a);
# if defined (DEBUGGER)
if ((flags & FEVAL_NOPUSHARGS) == 0)
{
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
index 88d6a9e5..04afac3d 100644
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -1,4 +1,6 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Evaluate a string as one or more shell commands.
+
+ Copyright (C) 1996-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -58,6 +60,7 @@ extern int indirection_level, startup_state, subshell_environment;
extern int line_number;
extern int last_command_exit_value;
extern int running_trap;
+extern int loop_level;
extern int posixly_correct;
int parse_and_execute_level = 0;
@@ -105,6 +108,7 @@ parse_and_execute (string, from_file, flags)
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
+ unwind_protect_int (loop_level);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
@@ -231,17 +235,21 @@ parse_and_execute (string, from_file, flags)
* IF
* we were invoked as `bash -c' (startup_state == 2) AND
* parse_and_execute has not been called recursively AND
+ * we're not running a trap AND
* we have parsed the full command (string == '\0') AND
* we have a simple command without redirections AND
- * the command is not being timed
+ * the command is not being timed AND
+ * the command's return status is not being inverted
* THEN
* tell the execution code that we don't need to fork
*/
if (startup_state == 2 && parse_and_execute_level == 1 &&
+ running_trap == 0 &&
*bash_input.location.string == '\0' &&
command->type == cm_simple &&
!command->redirects && !command->value.Simple->redirects &&
- ((command->flags & CMD_TIME_PIPELINE) == 0))
+ ((command->flags & CMD_TIME_PIPELINE) == 0) &&
+ ((command->flags & CMD_INVERT_RETURN) == 0))
{
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
diff --git a/builtins/exec.def b/builtins/exec.def
index acfdae10..0818a25e 100644
--- a/builtins/exec.def
+++ b/builtins/exec.def
@@ -221,7 +221,8 @@ failed_exec:
initialize_signals (1);
#if defined (JOB_CONTROL)
- restart_job_control ();
+ if (interactive_shell || job_control)
+ restart_job_control ();
#endif /* JOB_CONTROL */
return (exit_value);
diff --git a/builtins/exit.def b/builtins/exit.def
index 9384adef..ddaa5d31 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -105,7 +105,7 @@ exit_or_logout (list)
if (!exit_immediate_okay)
{
register int i;
- for (i = 0; i < job_slots; i++)
+ for (i = 0; i < js.j_jobslots; i++)
if (jobs[i] && STOPPED (i))
{
fprintf (stderr, _("There are stopped jobs.\n"));
diff --git a/builtins/fc.def b/builtins/fc.def
index 93c7ae3d..ebe36832 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -84,10 +84,12 @@ extern int errno;
extern int echo_input_at_read;
extern int current_command_line_count;
extern int literal_history;
+extern int posixly_correct;
extern int unlink __P((const char *));
extern FILE *sh_mktmpfp __P((char *, int, char **));
+extern int delete_last_history __P((void));
/* **************************************************************** */
/* */
@@ -155,6 +157,11 @@ static void fc_addhist __P((char *));
/* String to execute on a file that we want to edit. */
#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
+#if defined (STRICT_POSIX)
+# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}"
+#else
+# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
+#endif
int
fc_builtin (list)
@@ -166,7 +173,7 @@ fc_builtin (list)
int histbeg, histend, last_hist, retval, opt;
FILE *stream;
REPL *rlist, *rl;
- char *ename, *command, *newcom;
+ char *ename, *command, *newcom, *fcedit;
HIST_ENTRY **hlist;
char *fn;
@@ -284,6 +291,11 @@ fc_builtin (list)
line was actually added (HISTIGNORE may have caused it to not be),
so we check hist_last_line_added. */
+ /* "When not listing, he fc command that caused the editing shall not be
+ entered into the history list." */
+ if (listing == 0 && hist_last_line_added)
+ delete_last_history ();
+
last_hist = i - 1 - hist_last_line_added;
if (list)
@@ -302,7 +314,7 @@ fc_builtin (list)
if (listing)
{
histend = last_hist;
- histbeg = histend - 16;
+ histbeg = histend - 16 + 1; /* +1 because loop below uses >= */
if (histbeg < 0)
histbeg = 0;
}
@@ -347,7 +359,12 @@ fc_builtin (list)
if (numbering)
fprintf (stream, "%d", i + history_base);
if (listing)
- fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
+ {
+ if (posixly_correct)
+ fputs ("\t", stream);
+ else
+ fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
+ }
fprintf (stream, "%s\n", histline (i));
}
@@ -364,8 +381,9 @@ fc_builtin (list)
}
else
{
- command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn));
- sprintf (command, "%s %s", FC_EDIT_COMMAND, fn);
+ fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND;
+ command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn));
+ sprintf (command, "%s %s", fcedit, fn);
}
retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
if (retval != EXECUTION_SUCCESS)
@@ -489,7 +507,7 @@ fc_gethist (command, hlist)
{
int i;
- if (!hlist)
+ if (hlist == 0)
return ((char *)NULL);
i = fc_gethnum (command, hlist);
@@ -573,41 +591,18 @@ static void
fc_replhist (command)
char *command;
{
- register int i;
- HIST_ENTRY **hlist, *histent, *discard;
int n;
if (command == 0 || *command == '\0')
return;
- hlist = history_list ();
-
- if (hlist == NULL)
- return;
-
- for (i = 0; hlist[i]; i++);
- i--;
-
- /* History_get () takes a parameter that should be
- offset by history_base. */
-
- histent = history_get (history_base + i); /* Don't free this */
- if (histent == NULL)
- return;
-
n = strlen (command);
-
if (command[n - 1] == '\n')
command[n - 1] = '\0';
if (command && *command)
{
- discard = remove_history (i);
- if (discard)
- {
- FREE (discard->line);
- free ((char *) discard);
- }
+ delete_last_history ();
maybe_add_history (command); /* Obeys HISTCONTROL setting. */
}
}
@@ -620,13 +615,16 @@ fc_addhist (line)
{
register int n;
+ if (line == 0 || *line == 0)
+ return;
+
n = strlen (line);
if (line[n - 1] == '\n')
line[n - 1] = '\0';
if (line && *line)
- maybe_add_history (line);
+ maybe_add_history (line); /* Obeys HISTCONTROL setting. */
}
#endif
diff --git a/builtins/fg_bg.def b/builtins/fg_bg.def
index ea13bef3..c14381b6 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -82,8 +82,8 @@ fg_builtin (list)
$BUILTIN bg
$FUNCTION bg_builtin
$DEPENDS_ON JOB_CONTROL
-$SHORT_DOC bg [job_spec]
-Place JOB_SPEC in the background, as if it had been started with
+$SHORT_DOC bg [job_spec ...]
+Place each JOB_SPEC in the background, as if it had been started with
`&'. If JOB_SPEC is not present, the shell's notion of the current
job is used.
$END
@@ -94,6 +94,8 @@ int
bg_builtin (list)
WORD_LIST *list;
{
+ int r;
+
if (job_control == 0)
{
sh_nojobs ((char *)NULL);
@@ -104,7 +106,19 @@ bg_builtin (list)
return (EX_USAGE);
list = loptend;
- return (fg_bg (list, 0));
+ /* This relies on the fact that fg_bg() takes a WORD_LIST *, but only acts
+ on the first member (if any) of that list. */
+ r = EXECUTION_SUCCESS;
+ do
+ {
+ if (fg_bg (list, 0) == EXECUTION_FAILURE)
+ r = EXECUTION_FAILURE;
+ if (list)
+ list = list->next;
+ }
+ while (list);
+
+ return r;
}
/* How to put a job into the foreground/background. */
@@ -115,11 +129,12 @@ fg_bg (list, foreground)
{
sigset_t set, oset;
int job, status, old_async_pid;
+ JOB *j;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
- if (job < 0 || job >= job_slots || jobs[job] == 0)
+ if (INVALID_JOB (job))
{
if (job != DUP_JOB)
sh_badjob (list ? list->word->word : "current");
@@ -127,7 +142,8 @@ fg_bg (list, foreground)
goto failure;
}
- /* Or if jobs[job]->pgrp == shell_pgrp. */
+ j = get_job_by_jid (job);
+ /* Or if j->pgrp == shell_pgrp. */
if (IS_JOBCONTROL (job) == 0)
{
builtin_error (_("job %d started without job control"), job + 1);
@@ -137,7 +153,7 @@ fg_bg (list, foreground)
if (foreground == 0)
{
old_async_pid = last_asynchronous_pid;
- last_asynchronous_pid = jobs[job]->pgrp; /* As per Posix.2 5.4.2 */
+ last_asynchronous_pid = j->pgrp; /* As per Posix.2 5.4.2 */
}
status = start_job (job, foreground);
@@ -146,7 +162,7 @@ fg_bg (list, foreground)
{
/* win: */
UNBLOCK_CHILD (oset);
- return (status);
+ return (foreground ? status : EXECUTION_SUCCESS);
}
else
{
diff --git a/builtins/getopts.def b/builtins/getopts.def
index eb0a31d1..a9aad62b 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-2002 Free Software Foundation, Inc.
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -101,7 +101,7 @@ getopts_bind_variable (name, value)
if (legal_identifier (name))
{
- v = bind_variable (name, value);
+ v = bind_variable (name, value, 0);
return (v && (readonly_p (v) == 0)) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
}
else
@@ -228,7 +228,7 @@ dogetopts (argc, argv)
}
while (n /= 10);
}
- bind_variable ("OPTIND", numval + i);
+ bind_variable ("OPTIND", numval + i, 0);
/* If an error occurred, decide which one it is and set the return
code appropriately. In all cases, the option character in error
@@ -259,7 +259,7 @@ dogetopts (argc, argv)
{
strval[0] = (char)sh_optopt;
strval[1] = '\0';
- bind_variable ("OPTARG", strval);
+ bind_variable ("OPTARG", strval, 0);
}
else
unbind_variable ("OPTARG");
@@ -276,7 +276,7 @@ dogetopts (argc, argv)
strval[0] = (char)sh_optopt;
strval[1] = '\0';
- bind_variable ("OPTARG", strval);
+ bind_variable ("OPTARG", strval, 0);
}
else
{
@@ -286,7 +286,7 @@ dogetopts (argc, argv)
return (ret);
}
- bind_variable ("OPTARG", sh_optarg);
+ bind_variable ("OPTARG", sh_optarg, 0);
strval[0] = (char) ret;
strval[1] = '\0';
diff --git a/builtins/hash.def b/builtins/hash.def
index d311ac90..b2959521 100644
--- a/builtins/hash.def
+++ b/builtins/hash.def
@@ -125,7 +125,7 @@ hash_builtin (list)
if (list == 0 && expunge_hash_table == 0)
{
if (print_hashed_commands (list_portably) == 0)
- printf (_("%s: hash table empty\n"), this_command_name);
+ fprintf (stderr, _("%s: hash table empty\n"), this_command_name);
return (EXECUTION_SUCCESS);
}
@@ -165,10 +165,13 @@ hash_builtin (list)
}
else if (absolute_program (w))
continue;
- else if (delete && phash_remove (w))
+ else if (delete)
{
- sh_notfound (w);
- opt = EXECUTION_FAILURE;
+ if (phash_remove (w))
+ {
+ sh_notfound (w);
+ opt = EXECUTION_FAILURE;
+ }
}
else if (add_hashed_command (w, 0))
opt = EXECUTION_FAILURE;
diff --git a/builtins/help.def b/builtins/help.def
index 1935b64e..35a6de9c 100644
--- a/builtins/help.def
+++ b/builtins/help.def
@@ -169,7 +169,7 @@ show_longdoc (i)
}
else
for (j = 0; doc[j]; j++)
- printf (" %s\n", _(doc[j]));
+ printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
}
static void
diff --git a/builtins/history.def b/builtins/history.def
index 52b1113f..efee0052 100644
--- a/builtins/history.def
+++ b/builtins/history.def
@@ -77,11 +77,13 @@ extern int errno;
#endif
extern int current_command_line_count;
+extern int force_append_history; /* shopt -s histappend */
+
+int delete_last_history __P((void));
static char *histtime __P((HIST_ENTRY *, const char *));
static void display_history __P((WORD_LIST *));
static int delete_histent __P((int));
-static int delete_last_history __P((void));
static void push_history __P((WORD_LIST *));
static int expand_and_print_history __P((WORD_LIST *));
@@ -214,15 +216,19 @@ history_builtin (list)
using_history ();
history_lines_in_file = where_history ();
- /* The question is whether we reset history_lines_this_session to 0,
- losing any history entries we had before we read the new entries
- from the history file, or whether we count the new entries we just
- read from the file as history lines added during this session.
+
+ /* If we're rewriting the history file at shell exit rather than just
+ appending the lines from this session to it, the question is whether
+ we reset history_lines_this_session to 0, losing any history entries
+ we had before we read the new entries from the history file, or
+ whether we count the new entries we just read from the file as
+ history lines added during this session.
Right now, we do the latter. This will cause these history entries
to be written to the history file along with any intermediate entries
we add when we do a `history -a', but the alternative is losing
them altogether. */
- history_lines_this_session += history_lines_in_file - old_history_lines +
+ if (force_append_history == 0)
+ history_lines_this_session += history_lines_in_file - old_history_lines +
history_base - obase;
}
@@ -310,7 +316,7 @@ delete_histent (i)
return 1;
}
-static int
+int
delete_last_history ()
{
register int i;
@@ -353,9 +359,11 @@ push_history (list)
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)
+ if (hist_last_line_pushed == 0 && hist_last_line_added && delete_last_history () == 0)
#else
- if ((hist_last_line_added || (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
+ if (hist_last_line_pushed == 0 &&
+ (hist_last_line_added ||
+ (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
&& delete_last_history () == 0)
#endif
return;
@@ -368,6 +376,8 @@ push_history (list)
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 */
+
+ hist_last_line_pushed = 1; /* XXX */
free (s);
}
@@ -379,7 +389,7 @@ expand_and_print_history (list)
char *s;
int r, result;
- if (hist_last_line_added && delete_last_history () == 0)
+ if (hist_last_line_pushed == 0 && 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 76d1957f..4c3ba6a7 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-2004 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -141,7 +141,7 @@ jobs_builtin (list)
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
- if ((job == NO_JOB) || !jobs || !jobs[job])
+ if ((job == NO_JOB) || jobs == 0 || get_job_by_jid (job) == 0)
{
sh_badjob (list->word->word);
any_failed++;
@@ -162,6 +162,7 @@ execute_list_with_replacements (list)
register WORD_LIST *l;
int job, result;
COMMAND *command;
+ JOB *j;
/* First do the replacement of job specifications with pids. */
for (l = list; l; l = l->next)
@@ -171,11 +172,12 @@ execute_list_with_replacements (list)
job = get_job_spec (l);
/* A bad job spec is not really a job spec! Pass it through. */
- if (job < 0 || job >= job_slots || !jobs[job])
+ if (INVALID_JOB (job))
continue;
+ j = get_job_by_jid (job);
free (l->word->word);
- l->word->word = itos (jobs[job]->pgrp);
+ l->word->word = itos (j->pgrp);
}
}
@@ -257,7 +259,7 @@ disown_builtin (list)
? get_job_by_pid ((pid_t) pid_value, 0)
: get_job_spec (list);
- if (job == NO_JOB || jobs == 0 || job < 0 || job >= job_slots || jobs[job] == 0)
+ if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
{
sh_badjob (list ? list->word->word : "current");
retval = EXECUTION_FAILURE;
diff --git a/builtins/kill.def b/builtins/kill.def
index d1b9f6da..bedbb1a6 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-2004 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,8 +23,8 @@ $PRODUCES kill.c
$BUILTIN kill
$FUNCTION kill_builtin
-$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] [pid | job]... or kill -l [sigspec]
-Send the processes named by PID (or JOB) the signal SIGSPEC. If
+$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
+Send the processes named by PID (or JOBSPEC) the signal SIGSPEC. If
SIGSPEC is not present, then SIGTERM is assumed. An argument of `-l'
lists the signal names; if arguments follow `-l' they are assumed to
be signal numbers for which names should be listed. Kill is a shell
@@ -170,7 +170,7 @@ kill_builtin (list)
{
pid = (pid_t) pid_value;
- if ((pid < -1 ? kill_pid (-pid, sig, 1) : kill_pid (pid, sig, 0)) < 0)
+ if (kill_pid (pid, sig, pid < -1) < 0)
{
if (errno == EINVAL)
sh_invalidsig (sigspec);
@@ -192,11 +192,12 @@ kill_builtin (list)
{ /* Must be a job spec. Check it out. */
int job;
sigset_t set, oset;
+ JOB *j;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
- if (job < 0 || job >= job_slots || !jobs[job])
+ if (INVALID_JOB (job))
{
if (job != DUP_JOB)
sh_badjob (list->word->word);
@@ -204,11 +205,12 @@ kill_builtin (list)
CONTINUE_OR_FAIL;
}
+ j = get_job_by_jid (job);
/* Job spec used. Kill the process group. If the job was started
without job control, then its pgrp == shell_pgrp, so we have
to be careful. We take the pid of the first job in the pipeline
in that case. */
- pid = IS_JOBCONTROL (job) ? jobs[job]->pgrp : jobs[job]->pipe->pid;
+ pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid;
UNBLOCK_CHILD (oset);
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
index 278755b4..94953e6c 100644
--- a/builtins/mkbuiltins.c
+++ b/builtins/mkbuiltins.c
@@ -63,6 +63,8 @@ extern char *strcpy ();
#define BUILTIN_FLAG_SPECIAL 0x01
#define BUILTIN_FLAG_ASSIGNMENT 0x02
+#define BASE_INDENT 4
+
/* If this stream descriptor is non-zero, then write
texinfo documentation to it. */
FILE *documentation_file = (FILE *)NULL;
@@ -77,6 +79,10 @@ int inhibit_production = 0;
the builtin name, in `./helpfiles'. */
int separate_helpfiles = 0;
+/* Non-zero means to create single C strings for each `longdoc', with
+ embedded newlines, for ease of translation. */
+int single_longdoc_strings = 1;
+
/* The name of a directory into which the separate external help files will
eventually be installed. */
char *helpfile_directory;
@@ -128,7 +134,7 @@ ARRAY *saved_builtins = (ARRAY *)NULL;
char *special_builtins[] =
{
":", ".", "source", "break", "continue", "eval", "exec", "exit",
- "export", "readonly", "return", "set", "shift", "trap", "unset",
+ "export", "readonly", "return", "set", "shift", "times", "trap", "unset",
(char *)NULL
};
@@ -225,6 +231,8 @@ main (argc, argv)
separate_helpfiles = 1;
helpfile_directory = argv[arg_index++];
}
+ else if (strcmp (arg, "-S") == 0)
+ single_longdoc_strings = 0;
else
{
fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
@@ -373,14 +381,8 @@ array_add (element, array)
array->array = (char **)xrealloc
(array->array, (array->size += array->growth_rate) * array->width);
-#if defined (HAVE_BCOPY)
- bcopy (&element, (char *) &(array->array[array->sindex]), array->width);
- array->sindex++;
- bzero ((char *) &(array->array[array->sindex]), array->width);
-#else
array->array[array->sindex++] = element;
array->array[array->sindex] = (char *)NULL;
-#endif /* !HAVE_BCOPY */
}
/* Free an allocated array and data pointer. */
@@ -1058,9 +1060,10 @@ save_builtin (builtin)
}
/* Flags that mean something to write_documentation (). */
-#define STRING_ARRAY 1
-#define TEXINFO 2
-#define PLAINTEXT 4
+#define STRING_ARRAY 0x01
+#define TEXINFO 0x02
+#define PLAINTEXT 0x04
+#define HELPFILE 0x08
char *structfile_header[] = {
"/* builtins.c -- the built in shell commands. */",
@@ -1271,7 +1274,7 @@ write_longdocs (stream, builtins)
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);
+ write_documentation (stream, sarray, 0, STRING_ARRAY|HELPFILE);
free (sarray[0]);
}
else
@@ -1343,8 +1346,10 @@ write_endifs (stream, defines)
fprintf (stream, " */\n");
}
-/* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes
- and quoting special characters in the string. */
+/* Write DOCUMENTATION to STREAM, perhaps surrounding it with double-quotes
+ and quoting special characters in the string. Handle special things for
+ internationalization (gettext) and the single-string vs. multiple-strings
+ issues. */
void
write_documentation (stream, documentation, indentation, flags)
FILE *stream;
@@ -1353,33 +1358,59 @@ write_documentation (stream, documentation, indentation, flags)
{
register int i, j;
register char *line;
- int string_array, texinfo;
+ int string_array, texinfo, base_indent, last_cpp, filename_p;
if (!stream)
return;
string_array = flags & STRING_ARRAY;
+ filename_p = flags & HELPFILE;
+
if (string_array)
- fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n");
+ {
+ fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n"); /* } */
+ if (single_longdoc_strings)
+ {
+ if (filename_p == 0)
+ fprintf (stream, "N_(\" "); /* the empty string translates specially. */
+ else
+ fprintf (stream, "\"");
+ }
+ }
+
+ base_indent = (string_array && single_longdoc_strings && filename_p == 0) ? BASE_INDENT : 0;
- for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
+ for (i = last_cpp = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
{
- /* Allow #ifdef's to be written out verbatim. */
+ /* Allow #ifdef's to be written out verbatim, but don't put them into
+ separate help files. */
if (*line == '#')
{
- if (string_array)
+ if (string_array && filename_p == 0 && single_longdoc_strings == 0)
fprintf (stream, "%s\n", line);
+ last_cpp = 1;
continue;
}
+ else
+ last_cpp = 0;
/* prefix with N_( for gettext */
- if (string_array)
- fprintf (stream, " N_(\"");
+ if (string_array && single_longdoc_strings == 0)
+ {
+ if (filename_p == 0)
+ fprintf (stream, " N_(\" "); /* the empty string translates specially. */
+ else
+ fprintf (stream, " \"");
+ }
if (indentation)
for (j = 0; j < indentation; j++)
fprintf (stream, " ");
+ /* Don't indent the first line, because of how the help builtin works. */
+ if (i == 0)
+ indentation += base_indent;
+
if (string_array)
{
for (j = 0; line[j]; j++)
@@ -1397,7 +1428,16 @@ write_documentation (stream, documentation, indentation, flags)
}
/* closing right paren for gettext */
- fprintf (stream, "\"),\n");
+ if (single_longdoc_strings == 0)
+ {
+ if (filename_p == 0)
+ fprintf (stream, "\"),\n");
+ else
+ fprintf (stream, "\",\n");
+ }
+ else if (documentation[i+1])
+ /* don't add extra newline after last line */
+ fprintf (stream, "\\n\\\n");
}
else if (texinfo)
{
@@ -1421,6 +1461,15 @@ write_documentation (stream, documentation, indentation, flags)
fprintf (stream, "%s\n", line);
}
+ /* closing right paren for gettext */
+ if (string_array && single_longdoc_strings)
+ {
+ if (filename_p == 0)
+ fprintf (stream, "\"),\n");
+ else
+ fprintf (stream, "\",\n");
+ }
+
if (string_array)
fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
}
diff --git a/builtins/printf.def b/builtins/printf.def
index 9b377a93..e4e31704 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1997-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,7 +23,7 @@ $PRODUCES printf.c
$BUILTIN printf
$FUNCTION printf_builtin
-$SHORT_DOC printf format [arguments]
+$SHORT_DOC printf [-v var] format [arguments]
printf formats and prints ARGUMENTS under control of the FORMAT. FORMAT
is a character string which contains three types of objects: plain
characters, which are simply copied to standard output, character escape
@@ -32,6 +32,8 @@ format specifications, each of which causes printing of the next successive
argument. In addition to the standard printf(1) formats, %b means to
expand backslash escape sequences in the corresponding argument, and %q
means to quote the argument in a way that can be reused as shell input.
+If the -v option is supplied, the output is placed into the value of the
+shell variable VAR rather than being sent to the standard output.
$END
#include <config.h>
@@ -74,28 +76,61 @@ $END
extern int errno;
#endif
+#define PC(c) \
+ do { \
+ char b[2]; \
+ tw++; \
+ b[0] = c; b[1] = '\0'; \
+ if (vflag) \
+ vbadd (b, 1); \
+ else \
+ putchar (c); \
+ } while (0)
+
#define PF(f, func) \
do { \
+ char *b = 0; \
+ int nw; \
if (have_fieldwidth && have_precision) \
- tw += printf(f, fieldwidth, precision, func); \
+ nw = asprintf(&b, f, fieldwidth, precision, func); \
else if (have_fieldwidth) \
- tw += printf(f, fieldwidth, func); \
+ nw = asprintf(&b, f, fieldwidth, func); \
else if (have_precision) \
- tw += printf(f, precision, func); \
+ nw = asprintf(&b, f, precision, func); \
else \
- tw += printf(f, func); \
+ nw = asprintf(&b, f, func); \
+ tw += nw; \
+ if (b) \
+ { \
+ if (vflag) \
+ (void)vbadd (b, nw); \
+ else \
+ (void)fputs (b, stdout); \
+ free (b); \
+ } \
} while (0)
/* We free the buffer used by mklong() if it's `too big'. */
#define PRETURN(value) \
do \
{ \
+ if (vflag) \
+ { \
+ bind_variable (vname, vbuf, 0); \
+ stupidly_hack_special_variables (vname); \
+ } \
if (conv_bufsize > 4096 ) \
{ \
- free(conv_buf); \
+ free (conv_buf); \
conv_bufsize = 0; \
conv_buf = 0; \
} \
+ if (vbsize > 4096) \
+ { \
+ free (vbuf); \
+ vbsize = 0; \
+ vbuf = 0; \
+ } \
fflush (stdout); \
return (value); \
} \
@@ -105,9 +140,10 @@ extern int errno;
#define LENMODS "hjlLtz"
static void printf_erange __P((char *));
-static void printstr __P((char *, char *, int, int, int));
+static int printstr __P((char *, char *, int, int, int));
static int tescape __P((char *, char *, int *));
static char *bexpand __P((char *, int, int *, int *));
+static char *vbadd __P((char *, int));
static char *mklong __P((char *, char *, size_t));
static int getchr __P((void));
static char *getstr __P((void));
@@ -132,6 +168,14 @@ static WORD_LIST *garglist;
static int retval;
static int conversion_error;
+/* printf -v var support */
+static int vflag = 0;
+static char *vbuf, *vname;
+static size_t vbsize;
+static int vblen;
+
+static intmax_t tw;
+
static char *conv_buf;
static size_t conv_bufsize;
@@ -141,14 +185,35 @@ printf_builtin (list)
{
int ch, fieldwidth, precision;
int have_fieldwidth, have_precision;
- intmax_t tw;
char convch, thisch, nextch, *format, *modstart, *fmt, *start;
conversion_error = 0;
retval = EXECUTION_SUCCESS;
- if (no_options (list))
- return (EX_USAGE);
+ vflag = 0;
+
+ reset_internal_getopt ();
+ while ((ch = internal_getopt (list, "v:")) != -1)
+ {
+ switch (ch)
+ {
+ case 'v':
+ if (legal_identifier (vname = list_optarg))
+ {
+ vflag = 1;
+ vblen = 0;
+ }
+ else
+ {
+ sh_invalidid (vname);
+ return (EX_USAGE);
+ }
+ break;
+ default:
+ builtin_usage ();
+ return (EX_USAGE);
+ }
+ }
list = loptend; /* skip over possible `--' */
if (list == 0)
@@ -161,6 +226,7 @@ printf_builtin (list)
return (EXECUTION_SUCCESS);
format = list->word->word;
+ tw = 0;
garglist = list->next;
@@ -189,14 +255,14 @@ printf_builtin (list)
/* A NULL third argument to tescape means to bypass the
special processing for arguments to %b. */
fmt += tescape (fmt, &nextch, (int *)NULL);
- putchar (nextch);
+ PC (nextch);
fmt--; /* for loop will increment it for us again */
continue;
}
if (*fmt != '%')
{
- putchar (*fmt);
+ PC (*fmt);
continue;
}
@@ -205,7 +271,7 @@ printf_builtin (list)
if (*fmt == '%') /* %% prints a % */
{
- putchar ('%');
+ PC ('%');
continue;
}
@@ -235,8 +301,20 @@ printf_builtin (list)
precision = getint ();
}
else
- while (DIGIT (*fmt))
- fmt++;
+ {
+ /* Negative precisions are allowed but treated as if the
+ precision were missing; I would like to allow a leading
+ `+' in the precision number as an extension, but lots
+ of asprintf/fprintf implementations get this wrong. */
+#if 0
+ if (*fmt == '-' || *fmt == '+')
+#else
+ if (*fmt == '-')
+#endif
+ fmt++;
+ while (DIGIT (*fmt))
+ fmt++;
+ }
}
/* skip possible format modifiers */
@@ -297,21 +375,27 @@ printf_builtin (list)
case 'b': /* expand escapes in argument */
{
char *p, *xp;
- int rlen;
+ int rlen, r;
p = getstr ();
- ch = rlen = 0;
+ ch = rlen = r = 0;
xp = bexpand (p, strlen (p), &ch, &rlen);
if (xp)
{
/* Have to use printstr because of possible NUL bytes
in XP -- printf does not handle that well. */
- printstr (start, xp, rlen, fieldwidth, precision);
+ r = printstr (start, xp, rlen, fieldwidth, precision);
+ if (r < 0)
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ retval = EXECUTION_FAILURE;
+ }
free (xp);
}
- if (ch)
+ if (ch || r < 0)
PRETURN (retval);
break;
}
@@ -319,7 +403,9 @@ printf_builtin (list)
case 'q': /* print with shell quoting */
{
char *p, *xp;
+ int r;
+ r = 0;
p = getstr ();
if (ansic_shouldquote (p))
xp = ansic_quote (p, 0, (int *)0);
@@ -328,9 +414,17 @@ printf_builtin (list)
if (xp)
{
/* Use printstr to get fieldwidth and precision right. */
- printstr (start, xp, strlen (xp), fieldwidth, precision);
+ r = printstr (start, xp, strlen (xp), fieldwidth, precision);
+ if (r < 0)
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ }
free (xp);
}
+
+ if (r < 0)
+ PRETURN (EXECUTION_FAILURE);
break;
}
@@ -412,6 +506,13 @@ printf_builtin (list)
modstart[0] = thisch;
modstart[1] = nextch;
}
+
+ if (ferror (stdout))
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ PRETURN (EXECUTION_FAILURE);
+ }
}
while (garglist && garglist != list->next);
@@ -429,7 +530,7 @@ printf_erange (s)
}
/* We duplicate a lot of what printf(3) does here. */
-static void
+static int
printstr (fmt, string, len, fieldwidth, precision)
char *fmt; /* format */
char *string; /* expanded string argument */
@@ -443,7 +544,11 @@ printstr (fmt, string, len, fieldwidth, precision)
int padlen, nc, ljust, i;
int fw, pr; /* fieldwidth and precision */
+#if 0
if (string == 0 || *string == '\0')
+#else
+ if (string == 0 || len == 0)
+#endif
return;
#if 0
@@ -518,15 +623,17 @@ printstr (fmt, string, len, fieldwidth, precision)
/* leading pad characters */
for (; padlen > 0; padlen--)
- putchar (' ');
+ PC (' ');
/* output NC characters from STRING */
for (i = 0; i < nc; i++)
- putchar (string[i]);
+ PC (string[i]);
/* output any necessary trailing padding */
for (; padlen < 0; padlen++)
- putchar (' ');
+ PC (' ');
+
+ return (ferror (stdout) ? -1 : 0);
}
/* Convert STRING by expanding the escape sequences specified by the
@@ -644,7 +751,11 @@ bexpand (string, len, sawc, lenp)
int temp;
char *ret, *r, *s, c;
+#if 0
if (string == 0 || *string == '\0')
+#else
+ if (string == 0 || len == 0)
+#endif
{
if (sawc)
*sawc = 0;
@@ -681,6 +792,37 @@ bexpand (string, len, sawc, lenp)
}
static char *
+vbadd (buf, blen)
+ char *buf;
+ int blen;
+{
+ size_t nlen;
+
+ nlen = vblen + blen + 1;
+ if (nlen >= vbsize)
+ {
+ vbsize = ((nlen + 63) >> 6) << 6;
+ vbuf = (char *)xrealloc (vbuf, vbsize);
+ }
+
+ if (blen == 1)
+ vbuf[vblen++] = buf[0];
+ else
+ {
+ FASTCOPY (buf, vbuf + vblen, blen);
+ vblen += blen;
+ }
+ vbuf[vblen] = '\0';
+
+#ifdef DEBUG
+ if (strlen (vbuf) != vblen)
+ internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, strlen (vbuf));
+#endif
+
+ return vbuf;
+}
+
+static char *
mklong (str, modifiers, mlen)
char *str;
char *modifiers;
diff --git a/builtins/psize.c b/builtins/psize.c
index c2154728..23abb658 100644
--- a/builtins/psize.c
+++ b/builtins/psize.c
@@ -40,7 +40,10 @@
#include "../command.h"
#include "../general.h"
#include "../sig.h"
+
+#ifndef errno
extern int errno;
+#endif
int nw;
diff --git a/builtins/pushd.def b/builtins/pushd.def
index 83b69c44..0978fc93 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -151,13 +151,20 @@ int
pushd_builtin (list)
WORD_LIST *list;
{
+ WORD_LIST *orig_list;
char *temp, *current_directory, *top;
- int j, flags;
+ int j, flags, skipopt;
intmax_t num;
char direction;
+ orig_list = list;
if (list && list->word && ISOPTION (list->word->word, '-'))
- list = list->next;
+ {
+ list = list->next;
+ skipopt = 1;
+ }
+ else
+ skipopt = 0;
/* If there is no argument list then switch current and
top of list. */
@@ -181,7 +188,7 @@ pushd_builtin (list)
return j;
}
- for (flags = 0; list; list = list->next)
+ for (flags = 0; skipopt == 0 && list; list = list->next)
{
if (ISOPTION (list->word->word, 'n'))
{
@@ -265,7 +272,7 @@ pushd_builtin (list)
if (current_directory == 0)
return (EXECUTION_FAILURE);
- j = ((flags & NOCD) == 0) ? cd_builtin (list) : EXECUTION_SUCCESS;
+ j = ((flags & NOCD) == 0) ? cd_builtin (skipopt ? orig_list : list) : EXECUTION_SUCCESS;
if (j == EXECUTION_SUCCESS)
{
add_dirstack_element ((flags & NOCD) ? savestring (list->word->word) : current_directory);
@@ -499,9 +506,11 @@ cd_to_string (name)
char *name;
{
WORD_LIST *tlist;
+ WORD_LIST *dir;
int result;
- tlist = make_word_list (make_word (name), NULL);
+ dir = make_word_list (make_word (name), NULL);
+ tlist = make_word_list (make_word ("--"), dir);
result = cd_builtin (tlist);
dispose_words (tlist);
return (result);
@@ -648,11 +657,11 @@ get_directory_stack ()
}
#ifdef LOADABLE_BUILTIN
-static char *dirs_doc[] = {
+static char * const dirs_doc[] = {
N_("Display the list of currently remembered directories. Directories"),
N_("find their way onto the list with the `pushd' command; you can get"),
N_("back up through the list with the `popd' command."),
- N_(""),
+ N_(" "),
N_("The -l flag specifies that `dirs' should not print shorthand versions"),
N_("of directories which are relative to your home directory. This means"),
N_("that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag"),
@@ -660,54 +669,54 @@ static char *dirs_doc[] = {
N_("prepending the directory name with its position in the stack. The -p"),
N_("flag does the same thing, but the stack position is not prepended."),
N_("The -c flag clears the directory stack by deleting all of the elements."),
- N_(""),
+ N_(" "),
N_("+N displays the Nth entry counting from the left of the list shown by"),
N_(" dirs when invoked without options, starting with zero."),
- N_(""),
+ N_(" "),
N_("-N displays the Nth entry counting from the right of the list shown by"),
N_(" dirs when invoked without options, starting with zero."),
(char *)NULL
};
-static char *pushd_doc[] = {
+static char * const pushd_doc[] = {
N_("Adds a directory to the top of the directory stack, or rotates"),
N_("the stack, making the new top of the stack the current working"),
N_("directory. With no arguments, exchanges the top two directories."),
- N_(""),
+ N_(" "),
N_("+N Rotates the stack so that the Nth directory (counting"),
N_(" from the left of the list shown by `dirs', starting with"),
N_(" zero) is at the top."),
- N_(""),
+ N_(" "),
N_("-N Rotates the stack so that the Nth directory (counting"),
N_(" from the right of the list shown by `dirs', starting with"),
N_(" zero) is at the top."),
- N_(""),
+ N_(" "),
N_("-n suppress the normal change of directory when adding directories"),
N_(" to the stack, so only the stack is manipulated."),
- N_(""),
+ N_(" "),
N_("dir adds DIR to the directory stack at the top, making it the"),
N_(" new current working directory."),
- N_(""),
+ N_(" "),
N_("You can see the directory stack with the `dirs' command."),
(char *)NULL
};
-static char *popd_doc[] = {
+static char * const popd_doc[] = {
N_("Removes entries from the directory stack. With no arguments,"),
N_("removes the top directory from the stack, and cd's to the new"),
N_("top directory."),
- N_(""),
+ N_(" "),
N_("+N removes the Nth entry counting from the left of the list"),
N_(" shown by `dirs', starting with zero. For example: `popd +0'"),
N_(" removes the first directory, `popd +1' the second."),
- N_(""),
+ N_(" "),
N_("-N removes the Nth entry counting from the right of the list"),
N_(" shown by `dirs', starting with zero. For example: `popd -0'"),
N_(" removes the last directory, `popd -1' the next to last."),
- N_(""),
+ N_(" "),
N_("-n suppress the normal change of directory when removing directories"),
N_(" from the stack, so only the stack is manipulated."),
- N_(""),
+ N_(" "),
N_("You can see the directory stack with the `dirs' command."),
(char *)NULL
};
diff --git a/builtins/read.def b/builtins/read.def
index cdac9c4b..914ebd7d 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-2004 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -79,6 +79,10 @@ $END
#include <readline/readline.h>
#endif
+#if defined (BUFFERED_INPUT)
+# include "input.h"
+#endif
+
#if !defined(errno)
extern int errno;
#endif
@@ -124,7 +128,7 @@ read_builtin (list)
WORD_LIST *list;
{
register char *varname;
- int size, i, pass_next, saw_escape, eof, opt, retval, code;
+ int size, i, nr, pass_next, saw_escape, eof, opt, retval, code;
int input_is_tty, input_is_pipe, unbuffered_read;
int raw, edit, nchars, silent, have_timeout, fd;
unsigned int tmout;
@@ -173,7 +177,7 @@ read_builtin (list)
#endif
tmout = 0; /* no timeout */
- nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
+ nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
delim = '\n'; /* read until newline */
reset_internal_getopt ();
@@ -273,10 +277,15 @@ read_builtin (list)
begin_unwind_frame ("read_builtin");
+#if defined (BUFFERED_INPUT)
+ if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd))
+ sync_buffered_stream (default_buffered_input);
+#endif
+
input_is_tty = isatty (fd);
if (input_is_tty == 0)
#ifndef __CYGWIN__
- input_is_pipe = (lseek (0, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
+ input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
#else
input_is_pipe = 1;
#endif
@@ -425,11 +434,11 @@ read_builtin (list)
newline pair still disappears from the input. */
if (pass_next)
{
+ pass_next = 0;
if (c == '\n')
i--; /* back up over the CTLESC */
else
- input_string[i++] = c;
- pass_next = 0;
+ goto add_char;
continue;
}
@@ -450,9 +459,11 @@ read_builtin (list)
input_string[i++] = CTLESC;
}
+add_char:
input_string[i++] = c;
+ nr++;
- if (nchars > 0 && i >= nchars)
+ if (nchars > 0 && nr >= nchars)
break;
}
input_string[i] = '\0';
@@ -515,7 +526,7 @@ read_builtin (list)
if (alist)
{
word_list_remove_quoted_nulls (alist);
- assign_array_var_from_word_list (var, alist);
+ assign_array_var_from_word_list (var, alist, 0);
dispose_words (alist);
}
xfree (input_string);
@@ -544,11 +555,11 @@ read_builtin (list)
if (saw_escape)
{
t = dequote_string (input_string);
- var = bind_variable ("REPLY", t);
+ var = bind_variable ("REPLY", t, 0);
free (t);
}
else
- var = bind_variable ("REPLY", input_string);
+ var = bind_variable ("REPLY", input_string, 0);
VUNSETATTR (var, att_invisible);
free (input_string);
@@ -627,10 +638,24 @@ read_builtin (list)
return (EXECUTION_FAILURE);
}
+#if 0
/* This has to be done this way rather than using string_list
and list_string because Posix.2 says that the last variable gets the
remaining words and their intervening separators. */
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
+#else
+ /* Check whether or not the number of fields is exactly the same as the
+ number of variables. */
+ if (*input_string)
+ {
+ t1 = input_string;
+ t = get_word_from_string (&input_string, ifs_chars, &e);
+ if (*input_string == 0)
+ input_string = t;
+ else
+ input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
+ }
+#endif
if (saw_escape)
{
@@ -654,11 +679,11 @@ bind_read_variable (name, value)
{
#if defined (ARRAY_VARS)
if (valid_array_reference (name) == 0)
- return (bind_variable (name, value));
+ return (bind_variable (name, value, 0));
else
- return (assign_array_element (name, value));
+ return (assign_array_element (name, value, 0));
#else /* !ARRAY_VARS */
- return bind_variable (name, value);
+ return bind_variable (name, value, 0);
#endif /* !ARRAY_VARS */
}
@@ -672,7 +697,7 @@ edit_line (p)
char *ret;
int len;
- if (!bash_readline_initialized)
+ if (bash_readline_initialized == 0)
initialize_readline ();
old_attempted_completion_function = rl_attempted_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
diff --git a/builtins/reserved.def b/builtins/reserved.def
index 0f293d39..5482f5f3 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-2002 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -73,12 +73,13 @@ $END
$BUILTIN if
$SHORT_DOC if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
-The if COMMANDS are executed. If the exit status is zero, then the then
-COMMANDS are executed. Otherwise, each of the elif COMMANDS are executed
-in turn, and if the exit status is zero, the corresponding then COMMANDS
-are executed and the if command completes. Otherwise, the else COMMANDS
-are executed, if present. The exit status is the exit status of the last
-command executed, or zero if no condition tested true.
+The `if COMMANDS' list is executed. If its exit status is zero, then the
+`then COMMANDS' list is executed. Otherwise, each `elif COMMANDS' list is
+executed in turn, and if its exit status is zero, the corresponding
+`then COMMANDS' list is executed and the if command completes. Otherwise,
+the `else COMMANDS' list is executed, if present. The exit status of the
+entire construct is the exit status of the last command executed, or zero
+if no condition tested true.
$END
$BUILTIN while
@@ -109,11 +110,12 @@ $END
$BUILTIN %
$DOCNAME fg_percent
-$SHORT_DOC %[DIGITS | WORD] [&]
-This is similar to the `fg' command. Resume a stopped or background
-job. If you specifiy DIGITS, then that job is used. If you specify
-WORD, then the job whose name begins with WORD is used. Following the
-job specification with a `&' places the job in the background.
+$SHORT_DOC JOB_SPEC [&]
+Equivalent to the JOB_SPEC argument to the `fg' command. Resume a
+stopped or background job. JOB_SPEC can specify either a job name
+or a job number. Following JOB_SPEC with a `&' places the job in
+the background, as if the job specification had been supplied as an
+argument to `bg'.
$END
$BUILTIN (( ... ))
@@ -145,9 +147,8 @@ $BUILTIN variables
$DOCNAME variable_help
$SHORT_DOC variables - Some variable names and meanings
BASH_VERSION Version information for this Bash.
-CDPATH A colon separated list of directories to search
- when the argument to `cd' is not found in the current
- directory.
+CDPATH A colon-separated list of directories to search
+ for directries given as arguments to `cd'.
GLOBIGNORE A colon-separated list of patterns describing filenames to
be ignored by pathname expansion.
#if defined (HISTORY)
diff --git a/builtins/set.def b/builtins/set.def
index 02cc16a1..3bb32704 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-2002 Free Software Foundation, Inc.
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -128,11 +128,13 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
-E If set, the ERR trap is inherited by shell functions.
#if defined (BANG_HISTORY)
-H Enable ! style history substitution. This flag is on
- by default.
+ by default when the shell is interactive.
#endif /* BANG_HISTORY */
-P If set, do not follow symbolic links when executing commands
such as cd which change the current directory.
-T If set, the DEBUG trap is inherited by shell functions.
+ - Assign any remaining arguments to the positional parameters.
+ The -x and -v options are turned off.
Using + rather than - causes these flags to be turned off. The
flags can also be used upon invocation of the shell. The current
@@ -311,7 +313,7 @@ set_ignoreeof (on_or_off, option_name)
ignoreeof = on_or_off == FLAG_ON;
unbind_variable ("ignoreeof");
if (ignoreeof)
- bind_variable ("IGNOREEOF", "10");
+ bind_variable ("IGNOREEOF", "10", 0);
else
unbind_variable ("IGNOREEOF");
sv_ignoreeof ("IGNOREEOF");
@@ -327,7 +329,7 @@ set_posix_mode (on_or_off, option_name)
if (posixly_correct == 0)
unbind_variable ("POSIXLY_CORRECT");
else
- bind_variable ("POSIXLY_CORRECT", "y");
+ bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
return (0);
}
@@ -503,7 +505,7 @@ set_shellopts ()
else
exported = 0;
- v = bind_variable ("SHELLOPTS", value);
+ v = bind_variable ("SHELLOPTS", value, 0);
/* Turn the read-only attribute back on, and turn off the export attribute
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
diff --git a/builtins/setattr.def b/builtins/setattr.def
index d211dbc4..28102bc4 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -111,6 +111,7 @@ set_or_show_attributes (list, attribute, nodefs)
{
register SHELL_VAR *var;
int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt;
+ int aflags;
char *name;
#if defined (ARRAY_VARS)
WORD_LIST *nlist, *tlist;
@@ -175,8 +176,16 @@ set_or_show_attributes (list, attribute, nodefs)
/* xxx [-np] name[=value] */
assign = assignment (name, 0);
+ aflags = 0;
if (assign)
- name[assign] = '\0';
+ {
+ name[assign] = '\0';
+ if (name[assign - 1] == '+')
+ {
+ aflags |= ASS_APPEND;
+ name[assign - 1] = '\0';
+ }
+ }
if (legal_identifier (name) == 0)
{
@@ -192,6 +201,8 @@ set_or_show_attributes (list, attribute, nodefs)
if (assign) /* xxx [-np] name=value */
{
name[assign] = '=';
+ if (aflags & ASS_APPEND)
+ name[assign - 1] = '+';
#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. */
@@ -217,6 +228,8 @@ set_or_show_attributes (list, attribute, nodefs)
if (do_assignment_no_expand (name) == 0)
assign_error++;
name[assign] = '\0';
+ if (aflags & ASS_APPEND)
+ name[assign - 1] = '\0';
}
set_var_attribute (name, attribute, undo);
@@ -396,13 +409,15 @@ set_var_attribute (name, attribute, undo)
{
tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
- var = bind_variable (tv->name, tvalue);
+ var = bind_variable (tv->name, tvalue, 0);
var->attributes |= tv->attributes & ~att_tempvar;
VSETATTR (tv, att_propagate);
if (var->context != 0)
VSETATTR (var, att_propagate);
SETVARATTR (tv, attribute, undo); /* XXX */
+ stupidly_hack_special_variables (tv->name);
+
free (tvalue);
}
else
@@ -410,7 +425,7 @@ set_var_attribute (name, attribute, undo)
var = find_variable_internal (name, 0);
if (var == 0)
{
- var = bind_variable (name, (char *)NULL);
+ var = bind_variable (name, (char *)NULL, 0);
VSETATTR (var, att_invisible);
}
else if (var->context != 0)
diff --git a/builtins/shopt.def b/builtins/shopt.def
index ad432e0c..ae100ace 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1994-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -64,7 +64,7 @@ extern int check_hashed_filenames, promptvars;
extern int cdspelling, expand_aliases;
extern int extended_quote;
extern int check_window_size;
-extern int glob_ignore_case;
+extern int glob_ignore_case, match_ignore_case;
extern int hup_on_exit;
extern int xpg_echo;
extern int gnu_error_format;
@@ -134,13 +134,13 @@ static struct {
{ "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
#if defined (READLINE)
{ "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
- { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
- { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
#endif
+ { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
#if defined (HISTORY)
{ "histappend", &force_append_history, (shopt_set_func_t *)NULL },
#endif
#if defined (READLINE)
+ { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
{ "histverify", &hist_verify, (shopt_set_func_t *)NULL },
{ "hostcomplete", &perform_hostname_completion, enable_hostname_completion },
#endif
@@ -155,6 +155,7 @@ static struct {
{ "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
#endif
{ "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
+ { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
{ "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
#if defined (PROGRAMMABLE_COMPLETION)
{ "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
diff --git a/builtins/trap.def b/builtins/trap.def
index 1ecbfbdb..669bea7a 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-2004 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -214,7 +214,6 @@ showtrap (i)
char *t, *p, *sn;
p = trap_list[i];
-
if (p == (char *)DEFAULT_SIG)
return;
diff --git a/builtins/type.def b/builtins/type.def
index 7abcedf2..d03ccb2d 100644
--- a/builtins/type.def
+++ b/builtins/type.def
@@ -74,7 +74,7 @@ $END
extern int find_reserved_word __P((char *));
extern char *this_command_name;
-extern int expand_aliases;
+extern int expand_aliases, posixly_correct;
/* For each word in LIST, find out what the shell is going to do with
it as a simple command. i.e., which file would this shell use to
@@ -201,6 +201,7 @@ type_builtin (list)
* 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
+ * CDESC_ABSPATH convert to absolute path, no ./ prefix
*
* CDESC_ALL says whether or not to look for all occurrences of COMMAND, or
* return after finding it once.
@@ -359,8 +360,9 @@ describe_command (command, dflags)
/* If we found the command as itself by looking through $PATH, it
probably doesn't exist. Check whether or not the command is an
- executable file. If it's not, don't report a match. */
- if (STREQ (full_path, command))
+ executable file. If it's not, don't report a match. This is
+ the default posix mode behavior */
+ if (STREQ (full_path, command) || posixly_correct)
{
f = file_status (full_path);
if ((f & FS_EXECABLE) == 0)
@@ -370,9 +372,17 @@ describe_command (command, dflags)
if (all == 0)
break;
}
+ else if (ABSPATH (full_path))
+ ; /* placeholder; don't need to do anything yet */
else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY|CDESC_SHORTDESC))
- full_path = sh_makepath ((char *)NULL, full_path, MP_DOCWD);
+ {
+ f = MP_DOCWD | ((dflags & CDESC_ABSPATH) ? MP_RMDOT : 0);
+ full_path = sh_makepath ((char *)NULL, full_path, f);
+ }
}
+ /* If we require a full path and don't have one, make one */
+ else if ((dflags & CDESC_ABSPATH) && ABSPATH (full_path) == 0)
+ full_path = sh_makepath ((char *)NULL, full_path, MP_DOCWD|MP_RMDOT);
found_file++;
found = 1;
diff --git a/builtins/ulimit.def b/builtins/ulimit.def
index 932a6ea4..8cfcd4fd 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-2003 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -24,7 +24,7 @@ $PRODUCES ulimit.c
$BUILTIN ulimit
$FUNCTION ulimit_builtin
$DEPENDS_ON !_MINIX
-$SHORT_DOC ulimit [-SHacdflmnpstuv] [limit]
+$SHORT_DOC ulimit [-SHacdfilmnpqstuvx] [limit]
Ulimit provides control over the resources available to processes
started by the shell, on systems that allow such control. If an
option is given, it is interpreted as follows:
@@ -35,14 +35,17 @@ 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
+ -i the maximum number of pending signals
-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
+ -q the maximum number of bytes in POSIX message queues
-s the maximum stack size
-t the maximum amount of cpu time in seconds
-u the maximum number of user processes
- -v the size of virtual memory
+ -v the size of virtual memory
+ -x the maximum number of file locks
If LIMIT is given, it is the new value of the specified resource;
the special LIMIT values `soft', `hard', and `unlimited' stand for
@@ -200,6 +203,9 @@ static RESOURCE_LIMITS limits[] = {
{ 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
#endif
{ 'f', RLIMIT_FILESIZE, 1024, "file size", "blocks" },
+#ifdef RLIMIT_SIGPENDING
+ { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
+#endif
#ifdef RLIMIT_MEMLOCK
{ 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
#endif
@@ -208,6 +214,9 @@ static RESOURCE_LIMITS limits[] = {
#endif /* RLIMIT_RSS */
{ 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
{ 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
+#ifdef RLIMIT_MSGQUEUE
+ { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
+#endif
#ifdef RLIMIT_STACK
{ 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
#endif
@@ -221,6 +230,9 @@ static RESOURCE_LIMITS limits[] = {
#ifdef RLIMIT_SWAP
{ 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
#endif
+#ifdef RLIMIT_LOCKS
+ { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL },
+#endif
{ -1, -1, -1, (char *)NULL, (char *)NULL }
};
#define NCMDS (sizeof(limits) / sizeof(limits[0]))
@@ -605,14 +617,19 @@ pipesize (valuep)
*valuep = (RLIMTYPE) PIPE_BUF;
return 0;
#else
-# if defined (PIPESIZE)
+# if defined (_POSIX_PIPE_BUF)
+ *valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
+ return 0;
+# else
+# if defined (PIPESIZE)
/* This is defined by running a program from the Makefile. */
*valuep = (RLIMTYPE) PIPESIZE;
return 0;
-# else
+# else
errno = EINVAL;
return -1;
-# endif /* PIPESIZE */
+# endif /* PIPESIZE */
+# endif /* _POSIX_PIPE_BUF */
#endif /* PIPE_BUF */
}
@@ -647,11 +664,11 @@ print_all_limits (mode)
for (i = 0; limits[i].option > 0; i++)
{
- if (get_limit (i, &softlim, &hardlim) < 0)
+ if (get_limit (i, &softlim, &hardlim) == 0)
+ printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
+ else if (errno != EINVAL)
builtin_error ("%s: cannot get limit: %s", limits[i].description,
strerror (errno));
- else
- printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
}
}
@@ -670,7 +687,7 @@ printone (limind, curlim, pdesc)
else
sprintf (unitstr, "(-%c) ", limits[limind].option);
- printf ("%-18s %16s", limits[limind].description, unitstr);
+ printf ("%-20s %16s", limits[limind].description, unitstr);
}
if (curlim == RLIM_INFINITY)
puts ("unlimited");
diff --git a/builtins/wait.def b/builtins/wait.def
index 9eb66f60..22a92bea 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-2004 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -150,7 +150,7 @@ wait_builtin (list)
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
- if (job < 0 || job >= job_slots || !jobs[job])
+ if (INVALID_JOB (job))
{
if (job != DUP_JOB)
sh_badjob (list->word->word);