diff options
Diffstat (limited to 'builtins/common.c')
-rw-r--r-- | builtins/common.c | 160 |
1 files changed, 121 insertions, 39 deletions
diff --git a/builtins/common.c b/builtins/common.c index 7b9613e..f02e99c 100644 --- a/builtins/common.c +++ b/builtins/common.c @@ -1,20 +1,22 @@ -/* Copyright (C) 1987-2005 Free Software Foundation, Inc. +/* common.c - utility functions for all builtins */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. - Bash is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2, or (at your option) any later - version. + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - Bash is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with Bash; see the file COPYING. If not, write to the Free Software - Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + You should have received a copy of the GNU General Public License + along with Bash. If not, see <http://www.gnu.org/licenses/>. +*/ #include <config.h> @@ -42,6 +44,8 @@ #include "../bashansi.h" #include "../bashintl.h" +#define NEED_FPURGE_DECL + #include "../shell.h" #include "maxpath.h" #include "../flags.h" @@ -69,7 +73,7 @@ extern int last_command_exit_value; extern int running_trap; extern int posixly_correct; extern char *this_command_name, *shell_name; -extern char *bash_getcwd_errstr; +extern const char * const bash_getcwd_errstr; /* Used by some builtins and the mainline code. */ sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL; @@ -84,6 +88,22 @@ sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL; /* This is a lot like report_error (), but it is for shell builtins instead of shell control structures, and it won't ever exit the shell. */ + +static void +builtin_error_prolog () +{ + char *name; + + name = get_name_for_error (); + fprintf (stderr, "%s: ", name); + + if (interactive_shell == 0) + fprintf (stderr, _("line %d: "), executing_line_number ()); + + if (this_command_name && *this_command_name) + fprintf (stderr, "%s: ", this_command_name); +} + void #if defined (PREFER_STDARG) builtin_error (const char *format, ...) @@ -94,16 +114,29 @@ builtin_error (format, va_alist) #endif { va_list args; - char *name; - name = get_name_for_error (); - fprintf (stderr, "%s: ", name); + builtin_error_prolog (); - if (interactive_shell == 0) - fprintf (stderr, "line %d: ", executing_line_number ()); + SH_VA_START (args, format); - if (this_command_name && *this_command_name) - fprintf (stderr, "%s: ", this_command_name); + vfprintf (stderr, format, args); + va_end (args); + fprintf (stderr, "\n"); +} + +void +#if defined (PREFER_STDARG) +builtin_warning (const char *format, ...) +#else +builtin_warning (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + builtin_error_prolog (); + fprintf (stderr, _("warning: ")); SH_VA_START (args, format); @@ -117,7 +150,7 @@ void builtin_usage () { if (this_command_name && *this_command_name) - fprintf (stderr, "%s: usage: ", this_command_name); + fprintf (stderr, _("%s: usage: "), this_command_name); fprintf (stderr, "%s\n", current_builtin->short_doc); fflush (stderr); } @@ -131,6 +164,7 @@ no_args (list) if (list) { builtin_error (_("too many arguments")); + top_level_cleanup (); jump_to_top_level (DISCARD); } } @@ -198,7 +232,15 @@ void sh_invalidnum (s) char *s; { - builtin_error (_("%s: invalid number"), s); + char *msg; + + if (*s == '0' && isdigit (s[1])) + msg = _("invalid octal number"); + else if (*s == '0' && s[1] == 'x') + msg = _("invalid hex number"); + else + msg = _("invalid number"); + builtin_error ("%s: %s", s, msg); } void @@ -273,9 +315,37 @@ sh_notbuiltin (s) void sh_wrerror () { +#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE) + if (errno != EPIPE) +#endif /* DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS && EPIPE */ builtin_error (_("write error: %s"), strerror (errno)); } +void +sh_ttyerror (set) + int set; +{ + if (set) + builtin_error (_("error setting terminal attributes: %s"), strerror (errno)); + else + builtin_error (_("error getting terminal attributes: %s"), strerror (errno)); +} + +int +sh_chkwrite (s) + int s; +{ + fflush (stdout); + if (ferror (stdout)) + { + sh_wrerror (); + fpurge (stdout); + clearerr (stdout); + return (EXECUTION_FAILURE); + } + return (s); +} + /* **************************************************************** */ /* */ /* Shell positional parameter manipulation */ @@ -371,36 +441,44 @@ set_dollar_vars_changed () /* Read a numeric arg for this_command_name, the name of the shell builtin that wants it. LIST is the word list that the arg is to come from. Accept only the numeric argument; report an error if other arguments - follow. If FATAL is true, call throw_to_top_level, which exits the - shell; if not, call jump_to_top_level (DISCARD), which aborts the - current command. */ -intmax_t -get_numeric_arg (list, fatal) + follow. If FATAL is 1, call throw_to_top_level, which exits the + shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the + current command; if FATAL is 0, return an indication of an invalid + number by setting *NUMOK == 0 and return -1. */ +int +get_numeric_arg (list, fatal, count) WORD_LIST *list; int fatal; + intmax_t *count; { - intmax_t count = 1; + char *arg; + + if (count) + *count = 1; if (list && list->word && ISOPTION (list->word->word, '-')) list = list->next; if (list) { - register char *arg; - arg = list->word->word; - if (arg == 0 || (legal_number (arg, &count) == 0)) + if (arg == 0 || (legal_number (arg, count) == 0)) { - sh_neednumarg (list->word->word); - if (fatal) + sh_neednumarg (list->word->word ? list->word->word : "`'"); + if (fatal == 0) + return 0; + else if (fatal == 1) /* fatal == 1; abort */ throw_to_top_level (); - else - jump_to_top_level (DISCARD); + else /* fatal == 2; discard current command */ + { + top_level_cleanup (); + jump_to_top_level (DISCARD); + } } no_args (list->next); } - return (count); + return (1); } /* Get an eight-bit status value from LIST */ @@ -475,7 +553,11 @@ get_working_directory (for_whom) if (the_current_working_directory == 0) { +#if defined (GETCWD_BROKEN) + the_current_working_directory = getcwd (0, PATH_MAX); +#else the_current_working_directory = getcwd (0, 0); +#endif if (the_current_working_directory == 0) { fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"), @@ -530,7 +612,7 @@ get_job_by_name (name, flags) match = STREQN (p->command, name, cl); } else if (flags & JM_SUBSTRING) - match = strindex (p->command, name) != (char *)0; + match = strcasestr (p->command, name) != (char *)0; else match = STREQN (p->command, name, wl); @@ -639,7 +721,7 @@ display_signal_list (list, forcecols) { printf ("%2d) %s", i, name); - if (++column < 4) + if (++column < 5) printf ("\t"); else { |