From f4b417c62a4f272c4cf9a074d0f7a3a97201f9db Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 17 Apr 2012 11:23:35 +0200 Subject: Update to upstream bash 4.2 This upgrades bash to from 4.1-rc to 4.2-release. See CWRU/changelog for changes. Change-Id: I926269c300cf44fa25964b5b375a148fcf11c4b7 --- builtins/Makefile.in | 1 + builtins/cd.def | 43 +++++++++++---- builtins/common.c | 6 +-- builtins/common.h | 2 +- builtins/complete.def | 4 +- builtins/declare.def | 26 +++++---- builtins/evalfile.c | 7 +-- builtins/evalstring.c | 8 +-- builtins/exec.def | 28 +++++++--- builtins/fc.def | 14 ++++- builtins/getopts.def | 4 +- builtins/hash.def | 9 ++-- builtins/help.def | 8 +-- builtins/kill.def | 6 +-- builtins/let.def | 2 +- builtins/mapfile.def | 29 ++++++---- builtins/mkbuiltins.c | 11 ++-- builtins/printf.def | 147 ++++++++++++++++++++++++++++++++++++++++++++------ builtins/read.def | 22 +++++--- builtins/set.def | 5 +- builtins/setattr.def | 8 +-- builtins/shopt.def | 6 ++- builtins/source.def | 7 +++ builtins/test.def | 8 ++- builtins/trap.def | 36 ++++++++++--- builtins/ulimit.def | 6 ++- 26 files changed, 339 insertions(+), 114 deletions(-) (limited to 'builtins') diff --git a/builtins/Makefile.in b/builtins/Makefile.in index 42f8cb8..3d8bad4 100644 --- a/builtins/Makefile.in +++ b/builtins/Makefile.in @@ -334,6 +334,7 @@ evalstring.o: $(topdir)/externs.h $(topdir)/jobs.h $(topdir)/builtins.h evalstring.o: $(topdir)/flags.h $(topdir)/input.h $(topdir)/execute_cmd.h evalstring.o: $(topdir)/bashhist.h $(srcdir)/common.h evalstring.o: $(topdir)/trap.h $(topdir)/redir.h ../pathnames.h +#evalstring.o: $(topdir)/y.tab.h getopt.o: ../config.h $(BASHINCDIR)/memalloc.h getopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(topdir)/command.h getopt.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h $(topdir)/variables.h $(topdir)/conftypes.h diff --git a/builtins/cd.def b/builtins/cd.def index d53b258..b1aae26 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -58,7 +58,7 @@ extern int array_needs_making; extern const char * const bash_getcwd_errstr; static int bindpwd __P((int)); -static void setpwd __P((char *)); +static int setpwd __P((char *)); static char *resetpwd __P((char *)); static int change_to_directory __P((char *, int)); @@ -67,9 +67,11 @@ int cdspelling = 0; int cdable_vars; +static int eflag; /* file scope so bindpwd() can see it */ + $BUILTIN cd $FUNCTION cd_builtin -$SHORT_DOC cd [-L|-P] [dir] +$SHORT_DOC cd [-L|[-P [-e]]] [dir] Change the shell working directory. Change the current directory to DIR. The default DIR is the value of the @@ -88,15 +90,18 @@ Options: -L force symbolic links to be followed -P use the physical directory structure without following symbolic links + -e if the -P option is supplied, and the current working directory + cannot be determined successfully, exit with a non-zero status The default is to follow symbolic links, as if `-L' were specified. Exit Status: -Returns 0 if the directory is changed; non-zero otherwise. +Returns 0 if the directory is changed, and if $PWD is set successfully when +-P is used; non-zero otherwise. $END /* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */ -static void +static int setpwd (dirname) char *dirname; { @@ -105,11 +110,14 @@ setpwd (dirname) old_anm = array_needs_making; tvar = bind_variable ("PWD", dirname ? dirname : "", 0); - if (old_anm == 0 && array_needs_making && exported_p (tvar)) + if (tvar && readonly_p (tvar)) + return EXECUTION_FAILURE; + if (tvar && old_anm == 0 && array_needs_making && exported_p (tvar)) { update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); array_needs_making = 0; } + return EXECUTION_SUCCESS; } static int @@ -131,13 +139,19 @@ bindpwd (no_symlinks) pwdvar = get_string_value ("PWD"); tvar = bind_variable ("OLDPWD", pwdvar, 0); + if (tvar && readonly_p (tvar)) + r = EXECUTION_FAILURE; + if (old_anm == 0 && array_needs_making && exported_p (tvar)) { update_export_env_inplace ("OLDPWD=", 7, pwdvar); array_needs_making = 0; } - setpwd (dirname); + if (setpwd (dirname) == EXECUTION_FAILURE) + r = EXECUTION_FAILURE; + if (dirname == 0 && eflag) + r = EXECUTION_FAILURE; if (dirname && dirname != the_current_working_directory) free (dirname); @@ -162,7 +176,7 @@ resetpwd (caller) #define LCD_DOVARS 0x001 #define LCD_DOSPELL 0x002 #define LCD_PRINTPATH 0x004 -#define LCD_FREEDIRNAME 0x010 +#define LCD_FREEDIRNAME 0x008 /* This builtin is ultimately the way that all user-visible commands should change the current working directory. It is called by cd_to_string (), @@ -183,6 +197,7 @@ cd_builtin (list) } #endif /* RESTRICTED_SHELL */ + eflag = 0; no_symlinks = no_symbolic_links; reset_internal_getopt (); while ((opt = internal_getopt (list, "LP")) != -1) @@ -195,6 +210,9 @@ cd_builtin (list) case 'L': no_symlinks = 0; break; + case 'e': + eflag = 1; + break; default: builtin_usage (); return (EXECUTION_FAILURE); @@ -204,6 +222,8 @@ cd_builtin (list) lflag = (cdable_vars ? LCD_DOVARS : 0) | ((interactive && cdspelling) ? LCD_DOSPELL : 0); + if (eflag && no_symlinks == 0) + eflag = 0; if (list == 0) { @@ -270,6 +290,7 @@ cd_builtin (list) free (temp); } +#if 0 /* changed for bash-4.2 Posix cd description steps 5-6 */ /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't try the current directory, so we just punt now with an error message if POSIXLY_CORRECT is non-zero. The check for cdpath[0] @@ -280,6 +301,7 @@ cd_builtin (list) builtin_error ("%s: %s", dirname, strerror (ENOENT)); return (EXECUTION_FAILURE); } +#endif } else dirname = list->word->word; @@ -389,13 +411,14 @@ pwd_builtin (list) if (directory) { + opt = EXECUTION_SUCCESS; printf ("%s\n", directory); /* This is dumb but posix-mandated. */ if (posixly_correct && pflag) - setpwd (directory); + opt = setpwd (directory); if (directory != the_current_working_directory) free (directory); - return (sh_chkwrite (EXECUTION_SUCCESS)); + return (sh_chkwrite (opt)); } else return (EXECUTION_FAILURE); diff --git a/builtins/common.c b/builtins/common.c index 03d0d82..83f65d8 100644 --- a/builtins/common.c +++ b/builtins/common.c @@ -1,6 +1,6 @@ /* common.c - utility functions for all builtins */ -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. +/* Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -151,7 +151,7 @@ builtin_usage () { if (this_command_name && *this_command_name) fprintf (stderr, _("%s: usage: "), this_command_name); - fprintf (stderr, "%s\n", current_builtin->short_doc); + fprintf (stderr, "%s\n", _(current_builtin->short_doc)); fflush (stderr); } @@ -367,7 +367,7 @@ make_builtin_argv (list, ip) return argv; } -/* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is +/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is non-zero, then discard whatever the existing arguments are, else only discard the ones that are to be replaced. */ void diff --git a/builtins/common.h b/builtins/common.h index efbb078..caeefea 100644 --- a/builtins/common.h +++ b/builtins/common.h @@ -1,6 +1,6 @@ /* common.h -- extern declarations for functions defined in common.c. */ -/* Copyright (C) 1993-2004 Free Software Foundation, Inc. +/* Copyright (C) 1993-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. diff --git a/builtins/complete.def b/builtins/complete.def index 2267794..b9f0a13 100644 --- a/builtins/complete.def +++ b/builtins/complete.def @@ -1,7 +1,7 @@ This file is complete.def, from which is created complete.c. It implements the builtins "complete", "compgen", and "compopt" in Bash. -Copyright (C) 1999-2009 Free Software Foundation, Inc. +Copyright (C) 1999-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -753,7 +753,7 @@ $SHORT_DOC compopt [-o|+o option] [-DE] [name ...] Modify or display completion options. Modify the completion options for each NAME, or, if no NAMEs are supplied, -the completion currently begin executed. If no OPTIONs are givenm, print +the completion currently being executed. If no OPTIONs are given, print the completion options for each NAME or the current completion specification. Options: diff --git a/builtins/declare.def b/builtins/declare.def index a0ce605..41c5ee3 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -22,7 +22,7 @@ $PRODUCES declare.c $BUILTIN declare $FUNCTION declare_builtin -$SHORT_DOC declare [-aAfFilrtux] [-p] [name[=value] ...] +$SHORT_DOC declare [-aAfFgilrtux] [-p] [name[=value] ...] Set variable values and attributes. Declare variables and give them attributes. If no NAMEs are given, @@ -32,6 +32,8 @@ Options: -f restrict action or display to function names and definitions -F restrict display to function names only (plus line number and source file when debugging) + -g create global variables when used in a shell function; otherwise + ignored -p display the attributes and value of each NAME Options which set attributes: @@ -50,7 +52,7 @@ Variables with the integer attribute have arithmetic evaluation (see the `let' command) performed when the variable is assigned a value. When used in a function, `declare' makes NAMEs local, as with the `local' -command. +command. The `-g' option suppresses this behavior. Exit Status: Returns success unless an invalid option is supplied or an error occurs. @@ -58,7 +60,7 @@ $END $BUILTIN typeset $FUNCTION declare_builtin -$SHORT_DOC typeset [-aAfFilrtux] [-p] name[=value] ... +$SHORT_DOC typeset [-aAfFgilrtux] [-p] name[=value] ... Set variable values and attributes. Obsolete. See `help declare'. @@ -125,9 +127,9 @@ local_builtin (list) } #if defined (ARRAY_VARS) -# define DECLARE_OPTS "+acfilprtuxAF" +# define DECLARE_OPTS "+acfgilprtuxAF" #else -# define DECLARE_OPTS "+cfilprtuxF" +# define DECLARE_OPTS "+cfgilprtuxF" #endif /* The workhorse function. */ @@ -137,12 +139,12 @@ declare_internal (list, local_var) int local_var; { int flags_on, flags_off, *flags; - int any_failed, assign_error, pflag, nodefs, opt; + int any_failed, assign_error, pflag, nodefs, opt, mkglobal; char *t, *subscript_start; SHELL_VAR *var; FUNCTION_DEF *shell_fn; - flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0; + flags_on = flags_off = any_failed = assign_error = pflag = nodefs = mkglobal = 0; reset_internal_getopt (); while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF) { @@ -177,6 +179,10 @@ declare_internal (list, local_var) case 'f': *flags |= att_function; break; + case 'g': + if (flags == &flags_on) + mkglobal = 1; + break; case 'i': *flags |= att_integer; break; @@ -328,7 +334,7 @@ declare_internal (list, local_var) /* XXX - this has consequences when we're making a local copy of a variable that was in the temporary environment. Watch out for this. */ - if (variable_context && ((flags_on & att_function) == 0)) + if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0)) { #if defined (ARRAY_VARS) if (flags_on & att_assoc) @@ -410,7 +416,7 @@ declare_internal (list, local_var) { /* Non-null if we just created or fetched a local variable. */ if (var == 0) - var = find_variable (name); + var = mkglobal ? find_global_variable (name) : find_variable (name); if (var == 0) { diff --git a/builtins/evalfile.c b/builtins/evalfile.c index 972d039..4d69acb 100644 --- a/builtins/evalfile.c +++ b/builtins/evalfile.c @@ -70,6 +70,7 @@ extern int posixly_correct; extern int indirection_level, subshell_environment; extern int return_catch_flag, return_catch_value; extern int last_command_exit_value; +extern int executing_command_builtin; /* How many `levels' of sourced files we have. */ int sourcelevel = 0; @@ -148,10 +149,6 @@ file_error_and_exit: return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1); } -#if defined (__CYGWIN__) && defined (O_TEXT) - setmode (fd, O_TEXT); -#endif - if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX) { string = (char *)xmalloc (1 + file_size); @@ -342,7 +339,7 @@ source_file (filename, sflags) if (sflags) flags |= FEVAL_NOPUSHARGS; /* POSIX shells exit if non-interactive and file error. */ - if (posixly_correct && !interactive_shell) + if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) flags |= FEVAL_LONGJMP; rval = _evalfile (filename, flags); diff --git a/builtins/evalstring.c b/builtins/evalstring.c index 40abe00..333a56e 100644 --- a/builtins/evalstring.c +++ b/builtins/evalstring.c @@ -1,6 +1,6 @@ -/* evalstring.c - evaluate a string as one or more shell commands. +/* evalstring.c - evaluate a string as one or more shell commands. */ -/* Copyright (C) 1996-2009 Free Software Foundation, Inc. +/* Copyright (C) 1996-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -331,13 +331,9 @@ parse_and_execute (string, from_file, flags) (this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) && last_command_exit_value == EX_BADSYNTAX && posixly_correct) { -#if 0 /* XXX - for bash-4.2 */ should_jump_to_top_level = 1; code = ERREXIT; last_command_exit_value = EX_BADUSAGE; -#else - internal_warning (_("syntax errors in . or eval will cause future versions of the shell to abort as Posix requires")); -#endif } /* Since we are shell compatible, syntax errors in a script diff --git a/builtins/exec.def b/builtins/exec.def index 0837a98..5d1e625 100644 --- a/builtins/exec.def +++ b/builtins/exec.def @@ -1,7 +1,7 @@ This file is exec.def, from which is created exec.c. It implements the builtin "exec" in Bash. -Copyright (C) 1987-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -76,6 +76,7 @@ extern int errno; extern int subshell_environment; extern REDIRECT *redirection_undo_list; +extern char *exec_argv0; int no_exit_on_failed_exec; @@ -102,7 +103,7 @@ exec_builtin (list) char *argv0, *command, **args, **env, *newname, *com2; cleanenv = login = 0; - argv0 = (char *)NULL; + exec_argv0 = argv0 = (char *)NULL; reset_internal_getopt (); while ((opt = internal_getopt (list, "cla:")) != -1) @@ -147,8 +148,20 @@ exec_builtin (list) if (command == 0) { - sh_notfound (args[0]); - exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */ + if (file_isdir (args[0])) + { +#if defined (EISDIR) + builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR)); +#else + builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno)); +#endif + exit_value = EX_NOEXEC; + } + else + { + sh_notfound (args[0]); + exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */ + } goto failed_exec; } @@ -164,6 +177,7 @@ exec_builtin (list) { free (args[0]); args[0] = login ? mkdashname (argv0) : savestring (argv0); + exec_argv0 = savestring (args[0]); } else if (login) { @@ -198,7 +212,7 @@ exec_builtin (list) end_job_control (); #endif /* JOB_CONTROL */ - shell_execve (command, args, env); + exit_value = shell_execve (command, args, env); /* We have to set this to NULL because shell_execve has called realloc() to stuff more items at the front of the array, which may have caused @@ -207,7 +221,9 @@ exec_builtin (list) if (cleanenv == 0) adjust_shell_level (1); - if (executable_file (command) == 0) + if (exit_value == EX_NOTFOUND) /* no duplicate error message */ + goto failed_exec; + else if (executable_file (command) == 0) { builtin_error (_("%s: cannot execute: %s"), command, strerror (errno)); exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */ diff --git a/builtins/fc.def b/builtins/fc.def index a378d9d..257029d 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -85,7 +85,7 @@ $END extern int errno; #endif /* !errno */ -extern int current_command_line_count; +extern int current_command_line_count, saved_command_line_count; extern int literal_history; extern int posixly_correct; extern int subshell_environment, interactive_shell; @@ -303,6 +303,16 @@ fc_builtin (list) rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list); last_hist = i - rh - hist_last_line_added; + /* XXX */ + if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0) + while (last_hist >= 0 && hlist[last_hist] == 0) + last_hist--; + if (last_hist < 0) + { + sh_erange ((char *)NULL, _("history specification")); + return (EXECUTION_FAILURE); + } + if (list) { histbeg = fc_gethnum (list->word->word, hlist); diff --git a/builtins/getopts.def b/builtins/getopts.def index c077c8e..1d2a68a 100644 --- a/builtins/getopts.def +++ b/builtins/getopts.def @@ -108,7 +108,9 @@ getopts_bind_variable (name, value) if (legal_identifier (name)) { v = bind_variable (name, value, 0); - return (v && (readonly_p (v) == 0)) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; + if (v && (readonly_p (v) || noassign_p (v))) + return (EX_MISCERROR); + return (v ? EXECUTION_SUCCESS : EXECUTION_FAILURE); } else { diff --git a/builtins/hash.def b/builtins/hash.def index 7a8aced..6724ad1 100644 --- a/builtins/hash.def +++ b/builtins/hash.def @@ -1,7 +1,7 @@ This file is hash.def, from which is created hash.c. It implements the builtin "hash" in Bash. -Copyright (C) 1987-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -159,7 +159,9 @@ hash_builtin (list) { /* Add, remove or rehash the specified commands. */ w = list->word->word; - if (pathname) + if (absolute_program (w)) + continue; + else if (pathname) { if (is_directory (pathname)) { @@ -173,8 +175,6 @@ hash_builtin (list) else phash_insert (w, pathname, 0, 0); } - else if (absolute_program (w)) - continue; else if (delete) { if (phash_remove (w)) @@ -202,6 +202,7 @@ add_hashed_command (w, quiet) rv = 0; if (find_function (w) == 0 && find_shell_builtin (w) == 0) { + phash_remove (w); full_path = find_user_command (w); if (full_path && executable_file (full_path)) phash_insert (w, full_path, dot_found_in_search, 0); diff --git a/builtins/help.def b/builtins/help.def index f857af9..8fb0e2b 100644 --- a/builtins/help.def +++ b/builtins/help.def @@ -155,7 +155,7 @@ help_builtin (list) continue; } - printf ("%s: %s\n", name, shell_builtins[i].short_doc); + printf ("%s: %s\n", name, _(shell_builtins[i].short_doc)); if (sflag == 0) show_longdoc (i); @@ -288,7 +288,7 @@ show_manpage (name, i) /* SYNOPSIS */ printf ("SYNOPSIS\n"); - printf ("%*s%s\n\n", BASE_INDENT, " ", shell_builtins[i].short_doc); + printf ("%*s%s\n\n", BASE_INDENT, " ", _(shell_builtins[i].short_doc)); /* DESCRIPTION */ printf ("DESCRIPTION\n"); @@ -360,7 +360,7 @@ A star (*) next to a name means that the command is disabled.\n\ /* first column */ blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*'; - strncpy (blurb + 1, shell_builtins[i].short_doc, width - 2); + strncpy (blurb + 1, _(shell_builtins[i].short_doc), width - 2); blurb[width - 2] = '>'; /* indicate truncation */ blurb[width - 1] = '\0'; printf ("%s", blurb); @@ -376,7 +376,7 @@ A star (*) next to a name means that the command is disabled.\n\ /* second column */ blurb[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*'; - strncpy (blurb + 1, shell_builtins[i+height].short_doc, width - 3); + strncpy (blurb + 1, _(shell_builtins[i+height].short_doc), width - 3); blurb[width - 3] = '>'; /* indicate truncation */ blurb[width - 2] = '\0'; printf ("%s\n", blurb); diff --git a/builtins/kill.def b/builtins/kill.def index 18c3667..adf022c 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -121,9 +121,7 @@ kill_builtin (list) else sig = decode_signal (sigspec, dflags); list = list->next; -#if 0 - saw_signal++; /* XXX - for bash-4.2 */ -#endif + saw_signal++; } else { diff --git a/builtins/let.def b/builtins/let.def index 2601fb9..811534e 100644 --- a/builtins/let.def +++ b/builtins/let.def @@ -61,7 +61,7 @@ parentheses are evaluated first and may override the precedence rules above. Exit Status: -If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.. +If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise. $END #include diff --git a/builtins/mapfile.def b/builtins/mapfile.def index 0946de3..ec1e32e 100644 --- a/builtins/mapfile.def +++ b/builtins/mapfile.def @@ -2,7 +2,7 @@ This file is mapfile.def, from which is created mapfile.c. It implements the builtin "mapfile" in Bash. Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc. -Copyright (C) 2008,2009 Free Software Foundation, Inc. +Copyright (C) 2008-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -44,7 +44,8 @@ Arguments: If -C is supplied without -c, the default quantum is 5000. When CALLBACK is evaluated, it is supplied the index of the next array -element to be assigned as an additional argument. +element to be assigned and the line to be assigned to that element +as additional arguments. If not supplied with an explicit origin, mapfile will clear ARRAY before assigning to it. @@ -88,7 +89,10 @@ extern int errno; #if defined (ARRAY_VARS) +static int run_callback __P((const char *, unsigned int, const char *)); + #define DEFAULT_ARRAY_NAME "MAPFILE" +#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */ /* The value specifying how frequently `mapfile' calls the callback. */ #define DEFAULT_QUANTUM 5000 @@ -98,18 +102,20 @@ extern int errno; #define MAPF_CHOP 0x02 static int -run_callback(callback, current_index) +run_callback (callback, curindex, curline) const char *callback; - unsigned int current_index; + unsigned int curindex; + const char *curline; { unsigned int execlen; - char *execstr; + char *execstr, *qline; int flags; - execlen = strlen (callback) + 10; - /* 1 for space between %s and %d, + qline = sh_single_quote (curline); + execlen = strlen (callback) + strlen (qline) + 10; + /* 1 for each space between %s and %d, another 1 for the last nul char for C string. */ - execlen += 2; + execlen += 3; execstr = xmalloc (execlen); flags = SEVAL_NOHIST; @@ -117,8 +123,9 @@ run_callback(callback, current_index) if (interactive) flags |= SEVAL_INTERACT; #endif - snprintf (execstr, execlen, "%s %d", callback, current_index); - return parse_and_execute(execstr, NULL, flags); + snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline); + free (qline); + return parse_and_execute (execstr, NULL, flags); } static void @@ -202,7 +209,7 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n /* Has a callback been registered and if so is it time to call it? */ if (callback && line_count && (line_count % callback_quantum) == 0) { - run_callback (callback, array_index); + run_callback (callback, array_index, line); /* Reset the buffer for bash own stream. */ if (unbuffered_read == 0) diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c index cdd45e4..cdfdfb1 100644 --- a/builtins/mkbuiltins.c +++ b/builtins/mkbuiltins.c @@ -1,7 +1,7 @@ /* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from a single source file called builtins.def. */ -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. +/* Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -1127,7 +1127,7 @@ char *structfile_header[] = { }; char *structfile_footer[] = { - " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0 }", + " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0, (char *)0x0 }", "};", "", "struct builtin *shell_builtins = static_shell_builtins;", @@ -1380,7 +1380,7 @@ write_documentation (stream, documentation, indentation, flags) { register int i, j; register char *line; - int string_array, texinfo, base_indent, last_cpp, filename_p; + int string_array, texinfo, base_indent, filename_p; if (stream == 0) return; @@ -1407,7 +1407,7 @@ write_documentation (stream, documentation, indentation, flags) 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++) + for (i = 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. */ @@ -1415,11 +1415,8 @@ write_documentation (stream, documentation, indentation, flags) { 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 && single_longdoc_strings == 0) diff --git a/builtins/printf.def b/builtins/printf.def index 277566f..7892cb5 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-2009 Free Software Foundation, Inc. +Copyright (C) 1997-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -40,6 +40,8 @@ and printf(3), printf interprets: %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input + %(fmt)T output the date-time string resulting from using FMT as a format + string for strftime(3) Exit Status: Returns success unless an invalid option is given or a write or assignment @@ -72,9 +74,12 @@ $END # include #endif +#include "posixtime.h" #include "../bashansi.h" #include "../bashintl.h" +#define NEED_STRFTIME_DECL + #include "../shell.h" #include "shmbutil.h" #include "stdc.h" @@ -167,6 +172,8 @@ extern int errno; #define SKIP1 "#'-+ 0" #define LENMODS "hjlLtz" +extern time_t shell_start_time; + #if !HAVE_ASPRINTF extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); #endif @@ -177,7 +184,7 @@ extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__( static void printf_erange __P((char *)); static int printstr __P((char *, char *, int, int, int)); -static int tescape __P((char *, char *, int *)); +static int tescape __P((char *, char *, int *, int *)); static char *bexpand __P((char *, int, int *, int *)); static char *vbadd __P((char *, int)); static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); @@ -224,6 +231,10 @@ printf_builtin (list) int ch, fieldwidth, precision; int have_fieldwidth, have_precision; char convch, thisch, nextch, *format, *modstart, *fmt, *start; +#if defined (HANDLE_MULTIBYTE) + char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/ + int mbind, mblen; +#endif conversion_error = 0; retval = EXECUTION_SUCCESS; @@ -301,8 +312,17 @@ printf_builtin (list) fmt++; /* A NULL third argument to tescape means to bypass the special processing for arguments to %b. */ - fmt += tescape (fmt, &nextch, (int *)NULL); +#if defined (HANDLE_MULTIBYTE) + /* Accommodate possible use of \u or \U, which can result in + multibyte characters */ + memset (mbch, '\0', sizeof (mbch)); + fmt += tescape (fmt, mbch, &mblen, (int *)NULL); + for (mbind = 0; mbind < mblen; mbind++) + PC (mbch[mbind]); +#else + fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL); PC (nextch); +#endif fmt--; /* for loop will increment it for us again */ continue; } @@ -401,6 +421,70 @@ printf_builtin (list) break; } + case '(': + { + char *timefmt, timebuf[128], *t; + int n; + intmax_t arg; + time_t secs; + struct tm *tm; + + modstart[1] = nextch; /* restore char after left paren */ + timefmt = xmalloc (strlen (fmt) + 3); + fmt++; /* skip over left paren */ + for (t = timefmt, n = 1; *fmt; ) + { + if (*fmt == '(') + n++; + else if (*fmt == ')') + n--; + if (n == 0) + break; + *t++ = *fmt++; + } + *t = '\0'; + if (*++fmt != 'T') + { + builtin_warning (_("`%c': invalid time format specification"), *fmt); + fmt = start; + free (timefmt); + PC (*fmt); + continue; + } + if (timefmt[0] == '\0') + { + timefmt[0] = '%'; + timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */ + timefmt[2] = '\0'; + } + /* argument is seconds since the epoch with special -1 and -2 */ + arg = getintmax (); + if (arg == -1) + secs = NOW; /* roughly date +%s */ + else if (arg == -2) + secs = shell_start_time; /* roughly $SECONDS */ + else + secs = arg; + tm = localtime (&secs); + n = strftime (timebuf, sizeof (timebuf), timefmt, tm); + free (timefmt); + if (n == 0) + timebuf[0] = '\0'; + else + timebuf[sizeof(timebuf) - 1] = '\0'; + /* convert to %s format that preserves fieldwidth and precision */ + modstart[0] = 's'; + modstart[1] = '\0'; + n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */ + if (n < 0) + { + sh_wrerror (); + clearerr (stdout); + PRETURN (EXECUTION_FAILURE); + } + break; + } + case 'n': { char *var; @@ -699,15 +783,18 @@ printstr (fmt, string, len, fieldwidth, precision) do the \c short-circuiting, and \c is treated as an unrecognized escape sequence; we also bypass the other processing specific to %b arguments. */ static int -tescape (estart, cp, sawc) +tescape (estart, cp, lenp, sawc) char *estart; char *cp; - int *sawc; + int *lenp, *sawc; { register char *p; int temp, c, evalue; + unsigned long uvalue; p = estart; + if (lenp) + *lenp = 1; switch (c = *p++) { @@ -743,14 +830,10 @@ tescape (estart, cp, sawc) *cp = evalue & 0xFF; break; - /* And, as another extension, we allow \xNNN, where each N is a + /* And, as another extension, we allow \xNN, where each N is a hex digit. */ case 'x': -#if 0 - for (evalue = 0; ISXDIGIT ((unsigned char)*p); p++) -#else for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) -#endif evalue = (evalue * 16) + HEXVALUE (*p); if (p == estart + 1) { @@ -761,6 +844,30 @@ tescape (estart, cp, sawc) *cp = evalue & 0xFF; break; +#if defined (HANDLE_MULTIBYTE) + case 'u': + case 'U': + temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ + for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) + uvalue = (uvalue * 16) + HEXVALUE (*p); + if (p == estart + 1) + { + builtin_error (_("missing unicode digit for \\%c"), c); + *cp = '\\'; + return 0; + } + if (uvalue <= UCHAR_MAX) + *cp = uvalue; + else + { + temp = u32cconv (uvalue, cp); + cp[temp] = '\0'; + if (lenp) + *lenp = temp; + } + break; +#endif + case '\\': /* \\ -> \ */ *cp = c; break; @@ -799,12 +906,12 @@ bexpand (string, len, sawc, lenp) { int temp; char *ret, *r, *s, c; +#if defined (HANDLE_MULTIBYTE) + char mbch[25]; + int mbind, mblen; +#endif -#if 0 - if (string == 0 || *string == '\0') -#else if (string == 0 || len == 0) -#endif { if (sawc) *sawc = 0; @@ -823,7 +930,12 @@ bexpand (string, len, sawc, lenp) continue; } temp = 0; - s += tescape (s, &c, &temp); +#if defined (HANDLE_MULTIBYTE) + memset (mbch, '\0', sizeof (mbch)); + s += tescape (s, mbch, &mblen, &temp); +#else + s += tescape (s, &c, (int *)NULL, &temp); +#endif if (temp) { if (sawc) @@ -831,7 +943,12 @@ bexpand (string, len, sawc, lenp) break; } +#if defined (HANDLE_MULTIBYTE) + for (mbind = 0; mbind < mblen; mbind++) + *r++ = mbch[mbind]; +#else *r++ = c; +#endif } *r = '\0'; diff --git a/builtins/read.def b/builtins/read.def index 20860be..c4a668a 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -793,11 +793,16 @@ assign_vars: } else var = bind_read_variable (list->word->word, input_string); - stupidly_hack_special_variables (list->word->word); - FREE (tofree); if (var) - VUNSETATTR (var, att_invisible); + { + stupidly_hack_special_variables (list->word->word); + VUNSETATTR (var, att_invisible); + } + else + retval = EXECUTION_FAILURE; + + FREE (tofree); xfree (orig_input_string); return (retval); @@ -807,14 +812,17 @@ static SHELL_VAR * bind_read_variable (name, value) char *name, *value; { + SHELL_VAR *v; #if defined (ARRAY_VARS) if (valid_array_reference (name) == 0) - return (bind_variable (name, value, 0)); + v = bind_variable (name, value, 0); else - return (assign_array_element (name, value, 0)); + v = assign_array_element (name, value, 0); #else /* !ARRAY_VARS */ - return bind_variable (name, value, 0); + v = bind_variable (name, value, 0); #endif /* !ARRAY_VARS */ + return (v == 0 ? v + : ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v)); } #if defined (HANDLE_MULTIBYTE) diff --git a/builtins/set.def b/builtins/set.def index 5e550cb..6e69eb6 100644 --- a/builtins/set.def +++ b/builtins/set.def @@ -59,7 +59,7 @@ extern int no_line_editing; $BUILTIN set $FUNCTION set_builtin -$SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...] +$SHORT_DOC set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...] Set or unset values of shell options and positional parameters. Change the value of shell attributes and positional parameters, or @@ -138,6 +138,9 @@ Options: -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. + If there are no remaining arguments, the positional parameters + are unset. - Assign any remaining arguments to the positional parameters. The -x and -v options are turned off. diff --git a/builtins/setattr.def b/builtins/setattr.def index 8b4cdf7..b3ca317 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -82,7 +82,7 @@ export_builtin (list) $BUILTIN readonly $FUNCTION readonly_builtin -$SHORT_DOC readonly [-af] [name[=value] ...] or readonly -p +$SHORT_DOC readonly [-aAf] [name[=value] ...] or readonly -p Mark shell variables as unchangeable. Mark each NAME as read-only; the values of these NAMEs may not be @@ -433,11 +433,11 @@ show_var_attributes (var, pattr, nodefs) printf ("%s\n", var->name); else if (function_p (var)) printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL)); - else if (invisible_p (var)) + else if (invisible_p (var) || var_isset (var) == 0) printf ("%s\n", var->name); else { - x = sh_double_quote (var_isset (var) ? value_cell (var) : ""); + x = sh_double_quote (value_cell (var)); printf ("%s=%s\n", var->name, x); free (x); } diff --git a/builtins/shopt.def b/builtins/shopt.def index 68c7245..27685aa 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-2009 Free Software Foundation, Inc. +Copyright (C) 1994-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -84,6 +84,7 @@ extern int gnu_error_format; extern int check_jobs_at_exit; extern int autocd; extern int glob_star; +extern int lastpipe_opt; #if defined (EXTENDED_GLOB) extern int extended_glob; @@ -124,6 +125,7 @@ static int shopt_login_shell; static int shopt_compat31; static int shopt_compat32; static int shopt_compat40; +static int shopt_compat41; typedef int shopt_set_func_t __P((char *, int)); @@ -146,6 +148,7 @@ static struct { { "compat31", &shopt_compat31, set_compatibility_level }, { "compat32", &shopt_compat32, set_compatibility_level }, { "compat40", &shopt_compat40, set_compatibility_level }, + { "compat41", &shopt_compat41, set_compatibility_level }, #if defined (READLINE) { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL }, #endif @@ -175,6 +178,7 @@ static struct { #endif { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL }, { "interactive_comments", &interactive_comments, set_shellopts_after_change }, + { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL }, #if defined (HISTORY) { "lithist", &literal_history, (shopt_set_func_t *)NULL }, #endif diff --git a/builtins/source.def b/builtins/source.def index 72627db..71908b8 100644 --- a/builtins/source.def +++ b/builtins/source.def @@ -80,6 +80,8 @@ extern int errno; #endif /* !errno */ extern int posixly_correct; +extern int last_command_exit_value; +extern int executing_command_builtin; static void maybe_pop_dollar_vars __P((void)); @@ -151,6 +153,11 @@ source_builtin (list) if (source_searches_cwd == 0) { builtin_error (_("%s: file not found"), list->word->word); + if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) + { + last_command_exit_value = 1; + jump_to_top_level (EXITPROG); + } return (EXECUTION_FAILURE); } else diff --git a/builtins/test.def b/builtins/test.def index 4adff93..1ebc818 100644 --- a/builtins/test.def +++ b/builtins/test.def @@ -1,7 +1,7 @@ This file is test.def, from which is created test.c. It implements the builtin "test" in Bash. -Copyright (C) 1987-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -28,7 +28,10 @@ Evaluate conditional expression. Exits with a status of 0 (true) or 1 (false) depending on the evaluation of EXPR. Expressions may be unary or binary. Unary expressions are often used to examine the status of a file. There -are string operators as well, and numeric comparison operators. +are string operators and numeric comparison operators as well. + +The behavior of test depends on the number of arguments. Read the +bash manual page for the complete specification. File operators: @@ -80,6 +83,7 @@ String operators: Other operators: -o OPTION True if the shell option OPTION is enabled. + -v VAR True if the shell variable VAR is set ! EXPR True if expr is false. EXPR1 -a EXPR2 True if both expr1 AND expr2 are true. EXPR1 -o EXPR2 True if either expr1 OR expr2 is true. diff --git a/builtins/trap.def b/builtins/trap.def index a8da71d..2119f5b 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -35,7 +35,11 @@ value. If ARG is the null string each SIGNAL_SPEC is ignored by the shell and by the commands it invokes. If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If -a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. +a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If +a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a +script run by the . or source builtins finishes executing. A SIGNAL_SPEC +of ERR means to execute ARG each time a command's failure would cause the +shell to exit when the -e option is enabled. If no arguments are supplied, trap prints the list of commands associated with each signal. @@ -93,7 +97,7 @@ static int display_traps __P((WORD_LIST *)); #define REVERT 1 /* Revert to this signals original value. */ #define IGNORE 2 /* Ignore this signal. */ -extern int posixly_correct; +extern int posixly_correct, subshell_environment; int trap_builtin (list) @@ -103,6 +107,7 @@ trap_builtin (list) list_signal_names = display = 0; result = EXECUTION_SUCCESS; + reset_internal_getopt (); while ((opt = internal_getopt (list, "lp")) != -1) { @@ -126,7 +131,11 @@ trap_builtin (list) if (list_signal_names) return (sh_chkwrite (display_signal_list ((WORD_LIST *)NULL, 1))); else if (display || list == 0) - return (sh_chkwrite (display_traps (list))); + { + initialize_terminating_signals (); + get_all_original_signals (); + return (sh_chkwrite (display_traps (list))); + } else { char *first_arg; @@ -163,6 +172,16 @@ trap_builtin (list) operation = REVERT; } + /* If we're in a command substitution, we haven't freed the trap strings + (though we reset the signal handlers). If we're setting a trap to + handle a signal here, free the rest of the trap strings since they + don't apply any more. */ + if (subshell_environment & SUBSHELL_RESETTRAP) + { + free_trap_strings (); + subshell_environment &= ~SUBSHELL_RESETTRAP; + } + while (list) { sig = decode_signal (list->word->word, opt); @@ -188,6 +207,8 @@ trap_builtin (list) switch (sig) { case SIGINT: + /* XXX - should we do this if original disposition + was SIG_IGN? */ if (interactive) set_signal_handler (SIGINT, sigint_sighandler); else @@ -229,10 +250,13 @@ showtrap (i) char *t, *p, *sn; p = trap_list[i]; - if (p == (char *)DEFAULT_SIG) + if (p == (char *)DEFAULT_SIG && signal_is_hard_ignored (i) == 0) return; + else if (signal_is_hard_ignored (i)) + t = (char *)NULL; + else + t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p); - t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p); sn = signal_name (i); /* Make sure that signals whose names are unknown (for whatever reason) are printed as signal numbers. */ diff --git a/builtins/ulimit.def b/builtins/ulimit.def index 7c1e256..03cbe8a 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-2009 Free Software Foundation, Inc. +Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -118,6 +118,10 @@ extern int errno; # undef HAVE_RESOURCE #endif +#if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H) +# include +#endif + #if !defined (RLIMTYPE) # define RLIMTYPE long # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10) -- cgit v1.1