Imported from ../bash-3.1.tar.gz.
This commit is contained in:
parent
eb87367179
commit
95732b497d
267 changed files with 24541 additions and 18843 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
if (string_array)
|
||||
fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n");
|
||||
filename_p = flags & HELPFILE;
|
||||
|
||||
for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
|
||||
if (string_array)
|
||||
{
|
||||
/* Allow #ifdef's to be written out verbatim. */
|
||||
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 = last_cpp = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
|
||||
{
|
||||
/* 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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -680,6 +791,37 @@ bexpand (string, len, sawc, lenp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,10 @@
|
|||
#include "../command.h"
|
||||
#include "../general.h"
|
||||
#include "../sig.h"
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
int nw;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -220,6 +229,9 @@ static RESOURCE_LIMITS limits[] = {
|
|||
#endif
|
||||
#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 }
|
||||
};
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue