mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-03 10:20:49 +02:00
commit bash-20101001 snapshot
This commit is contained in:
+32
-1
@@ -9751,7 +9751,7 @@ lib/readline/complete.c
|
||||
|
||||
lib/readline/bind.c
|
||||
- new bindable variable: completion-display-width, controls the
|
||||
number of columns used when displaying completionsm with new
|
||||
number of columns used when displaying completions with new
|
||||
sv_compwidth function to call when value is set or unset
|
||||
|
||||
lib/readline/doc/{readline.3,rltech.texi}
|
||||
@@ -10415,3 +10415,34 @@ doc/{bash.1,bashref.texi},lib/readline/doc/{readline.3,rluser.texi}
|
||||
configure.in
|
||||
- remove AM_PATH_LISPDIR call since we don't use that bash debugger
|
||||
any more. Suggested by Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
10/6
|
||||
----
|
||||
findcmd.c
|
||||
- change executable_file to set errno to EISDIR if the passed name
|
||||
is a directory
|
||||
|
||||
builtins/exec.def
|
||||
- change exec_builtin to report appropriate error message if the
|
||||
file argument is a directory. Noted by Eric Blake <eblake@redhat.com>
|
||||
in a message to austin-group
|
||||
|
||||
builtins/source.def
|
||||
- change source_builtin to make sure the shell exits if the file is
|
||||
not found when in a non-interactive shell running in posix mode
|
||||
and source_searches_cwd == 0 (as posix mode makes it by default).
|
||||
Pointed out in http://thread.gmane.org/gmane.comp.shells.dash/291/focus=392
|
||||
by Jilles Tjoelker <jilles@stack.nl>
|
||||
|
||||
execute_cmd.c
|
||||
- set executing_command_builtin in execute_builtin if the builtin is
|
||||
command_builtin. Unwind-protected in execute_function_or_builtin
|
||||
(like executing_builtin variable). Available for rest of shell
|
||||
|
||||
builtins/{source.def,evalfile.c}
|
||||
- make sure that non-interactive posix mode shells exit if the file
|
||||
argument to `.' is not found only if they are not being executed
|
||||
by the command builtin (executing_command_builtin == 0). This is
|
||||
how `command' can cancel effects of special builtin exit properties
|
||||
in the case of `dot file not found'
|
||||
|
||||
|
||||
+32
-1
@@ -9751,7 +9751,7 @@ lib/readline/complete.c
|
||||
|
||||
lib/readline/bind.c
|
||||
- new bindable variable: completion-display-width, controls the
|
||||
number of columns used when displaying completionsm with new
|
||||
number of columns used when displaying completions with new
|
||||
sv_compwidth function to call when value is set or unset
|
||||
|
||||
lib/readline/doc/{readline.3,rltech.texi}
|
||||
@@ -10406,4 +10406,35 @@ lib/readline/bind.c
|
||||
- new bindable readline variable, "menu-complete-display-prefix",
|
||||
controls setting of _rl_menu_complete_prefix_first
|
||||
|
||||
doc/{bash.1,bashref.texi},lib/readline/doc/{readline.3,rluser.texi}
|
||||
- added description of menu-complete-display-prefix bindable
|
||||
readline variable
|
||||
|
||||
9/17
|
||||
----
|
||||
configure.in
|
||||
- remove AM_PATH_LISPDIR call since we don't use that bash debugger
|
||||
any more. Suggested by Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
10/6
|
||||
----
|
||||
findcmd.c
|
||||
- change executable_file to set errno to EISDIR if the passed name
|
||||
is a directory
|
||||
|
||||
builtins/exec.def
|
||||
- change exec_builtin to report appropriate error message if the
|
||||
file argument is a directory. Noted by Eric Blake <eblake@redhat.com>
|
||||
in a message to austin-group
|
||||
|
||||
builtins/source.def
|
||||
- change source_builtin to make sure the shell exits if the file is
|
||||
not found when in a non-interactive shell running in posix mode
|
||||
and source_searches_cwd == 0 (as posix mode makes it by default).
|
||||
Pointed out in http://thread.gmane.org/gmane.comp.shells.dash/291/focus=392
|
||||
by Jilles Tjoelker <jilles@stack.nl>
|
||||
|
||||
execute_cmd.c
|
||||
- set executing_command_builtin in execute_builtin if the builtin is
|
||||
command_builtin. Unwind-protected in execute_function_or_builtin
|
||||
(like executing_builtin variable). Available for rest of shell
|
||||
|
||||
+2
-2
@@ -1400,12 +1400,12 @@ bash_default_completion (text, start, end, qc, compflags)
|
||||
|
||||
/* If the word starts in `~', and there is no slash in the word, then
|
||||
try completing this word as a username. */
|
||||
if (matches ==0 && *text == '~' && mbschr (text, '/') == 0)
|
||||
if (matches == 0 && *text == '~' && mbschr (text, '/') == 0)
|
||||
matches = rl_completion_matches (text, rl_username_completion_function);
|
||||
|
||||
/* Another one. Why not? If the word starts in '@', then look through
|
||||
the world of known hostnames for completion first. */
|
||||
if (!matches && perform_hostname_completion && *text == '@')
|
||||
if (matches == 0 && perform_hostname_completion && *text == '@')
|
||||
matches = rl_completion_matches (text, hostname_completion_function);
|
||||
|
||||
/* And last, (but not least) if this word is in a command position, then
|
||||
|
||||
+1
-4
@@ -529,11 +529,8 @@ initialize_readline ()
|
||||
enable_hostname_completion (perform_hostname_completion);
|
||||
|
||||
/* characters that need to be quoted when appearing in filenames. */
|
||||
#if 0
|
||||
rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{"; /*}*/
|
||||
#else
|
||||
rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
|
||||
#endif
|
||||
|
||||
rl_filename_quoting_function = bash_quote_filename;
|
||||
rl_filename_dequoting_function = bash_dequote_filename;
|
||||
rl_char_is_quoted_p = char_is_quoted;
|
||||
|
||||
+2
-1
@@ -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;
|
||||
@@ -342,7 +343,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);
|
||||
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
/* evalfile.c - read and evaluate commands from a file or file descriptor */
|
||||
|
||||
/* Copyright (C) 1996-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 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.
|
||||
|
||||
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>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include "filecntl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../jobs.h"
|
||||
#include "../builtins.h"
|
||||
#include "../flags.h"
|
||||
#include "../input.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../trap.h"
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
|
||||
#include <typemax.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Flags for _evalfile() */
|
||||
#define FEVAL_ENOENTOK 0x001
|
||||
#define FEVAL_BUILTIN 0x002
|
||||
#define FEVAL_UNWINDPROT 0x004
|
||||
#define FEVAL_NONINT 0x008
|
||||
#define FEVAL_LONGJMP 0x010
|
||||
#define FEVAL_HISTORY 0x020
|
||||
#define FEVAL_CHECKBINARY 0x040
|
||||
#define FEVAL_REGFILE 0x080
|
||||
#define FEVAL_NOPUSHARGS 0x100
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int indirection_level, subshell_environment;
|
||||
extern int return_catch_flag, return_catch_value;
|
||||
extern int last_command_exit_value;
|
||||
|
||||
/* How many `levels' of sourced files we have. */
|
||||
int sourcelevel = 0;
|
||||
|
||||
static int
|
||||
_evalfile (filename, flags)
|
||||
const char *filename;
|
||||
int flags;
|
||||
{
|
||||
volatile int old_interactive;
|
||||
procenv_t old_return_catch;
|
||||
int return_val, fd, result, pflags, i, nnull;
|
||||
ssize_t nr; /* return value from read(2) */
|
||||
char *string;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
sh_vmsg_func_t *errfunc;
|
||||
#if defined (ARRAY_VARS)
|
||||
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;
|
||||
ARRAY *bash_argv_a, *bash_argc_a;
|
||||
# endif
|
||||
char *t, tt[2];
|
||||
#endif
|
||||
|
||||
USE_VAR(pflags);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
|
||||
# if defined (DEBUGGER)
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
fd = open (filename, O_RDONLY);
|
||||
|
||||
if (fd < 0 || (fstat (fd, &finfo) == -1))
|
||||
{
|
||||
file_error_and_exit:
|
||||
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
|
||||
file_error (filename);
|
||||
|
||||
if (flags & FEVAL_LONGJMP)
|
||||
{
|
||||
last_command_exit_value = 1;
|
||||
jump_to_top_level (EXITPROG);
|
||||
}
|
||||
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
|
||||
: ((errno == ENOENT) ? 0 : -1));
|
||||
}
|
||||
|
||||
errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
|
||||
|
||||
if (S_ISDIR (finfo.st_mode))
|
||||
{
|
||||
(*errfunc) (_("%s: is a directory"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
|
||||
{
|
||||
(*errfunc) (_("%s: not a regular file"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
|
||||
file_size = (size_t)finfo.st_size;
|
||||
/* Check for overflow with large files. */
|
||||
if (file_size != finfo.st_size || file_size + 1 < file_size)
|
||||
{
|
||||
(*errfunc) (_("%s: file is too large"), filename);
|
||||
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);
|
||||
nr = read (fd, string, file_size);
|
||||
if (nr >= 0)
|
||||
string[nr] = '\0';
|
||||
}
|
||||
else
|
||||
nr = zmapfd (fd, &string, 0);
|
||||
|
||||
return_val = errno;
|
||||
close (fd);
|
||||
errno = return_val;
|
||||
|
||||
if (nr < 0) /* XXX was != file_size, not < 0 */
|
||||
{
|
||||
free (string);
|
||||
goto file_error_and_exit;
|
||||
}
|
||||
|
||||
if (nr == 0)
|
||||
{
|
||||
free (string);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
|
||||
}
|
||||
|
||||
if ((flags & FEVAL_CHECKBINARY) &&
|
||||
check_binary_file (string, (nr > 80) ? 80 : nr))
|
||||
{
|
||||
free (string);
|
||||
(*errfunc) (_("%s: cannot execute binary file"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
|
||||
}
|
||||
|
||||
i = strlen (string);
|
||||
if (i < nr)
|
||||
{
|
||||
for (nnull = i = 0; i < nr; i++)
|
||||
if (string[i] == '\0')
|
||||
{
|
||||
memmove (string+i, string+i+1, nr - i);
|
||||
nr--;
|
||||
/* Even if the `check binary' flag is not set, we want to avoid
|
||||
sourcing files with more than 256 null characters -- that
|
||||
probably indicates a binary file. */
|
||||
if ((flags & FEVAL_BUILTIN) && ++nnull > 256)
|
||||
{
|
||||
free (string);
|
||||
(*errfunc) (_("%s: cannot execute binary file"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
{
|
||||
begin_unwind_frame ("_evalfile");
|
||||
|
||||
unwind_protect_int (return_catch_flag);
|
||||
unwind_protect_jmp_buf (return_catch);
|
||||
if (flags & FEVAL_NONINT)
|
||||
unwind_protect_int (interactive);
|
||||
unwind_protect_int (sourcelevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
COPY_PROCENV (return_catch, old_return_catch);
|
||||
if (flags & FEVAL_NONINT)
|
||||
old_interactive = interactive;
|
||||
}
|
||||
|
||||
if (flags & FEVAL_NONINT)
|
||||
interactive = 0;
|
||||
|
||||
return_catch_flag++;
|
||||
sourcelevel++;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
array_push (bash_source_a, (char *)filename);
|
||||
t = itos (executing_line_number ());
|
||||
array_push (bash_lineno_a, t);
|
||||
free (t);
|
||||
array_push (funcname_a, "source"); /* not exactly right */
|
||||
# if defined (DEBUGGER)
|
||||
/* Have to figure out a better way to do this when `source' is supplied
|
||||
arguments */
|
||||
if ((flags & FEVAL_NOPUSHARGS) == 0)
|
||||
{
|
||||
array_push (bash_argv_a, (char *)filename);
|
||||
tt[0] = '1'; tt[1] = '\0';
|
||||
array_push (bash_argc_a, tt);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* set the flags to be passed to parse_and_execute */
|
||||
pflags = SEVAL_RESETLINE;
|
||||
pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
|
||||
|
||||
if (flags & FEVAL_BUILTIN)
|
||||
result = EXECUTION_SUCCESS;
|
||||
|
||||
return_val = setjmp (return_catch);
|
||||
|
||||
/* If `return' was seen outside of a function, but in the script, then
|
||||
force parse_and_execute () to clean up. */
|
||||
if (return_val)
|
||||
{
|
||||
parse_and_execute_cleanup ();
|
||||
result = return_catch_value;
|
||||
}
|
||||
else
|
||||
result = parse_and_execute (string, filename, pflags);
|
||||
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
run_unwind_frame ("_evalfile");
|
||||
else
|
||||
{
|
||||
if (flags & FEVAL_NONINT)
|
||||
interactive = old_interactive;
|
||||
return_catch_flag--;
|
||||
sourcelevel--;
|
||||
COPY_PROCENV (old_return_catch, return_catch);
|
||||
}
|
||||
|
||||
#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);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
array_pop (bash_argc_a);
|
||||
array_pop (bash_argv_a);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return ((flags & FEVAL_BUILTIN) ? result : 1);
|
||||
}
|
||||
|
||||
int
|
||||
maybe_execute_file (fname, force_noninteractive)
|
||||
const char *fname;
|
||||
int force_noninteractive;
|
||||
{
|
||||
char *filename;
|
||||
int result, flags;
|
||||
|
||||
filename = bash_tilde_expand (fname, 0);
|
||||
flags = FEVAL_ENOENTOK;
|
||||
if (force_noninteractive)
|
||||
flags |= FEVAL_NONINT;
|
||||
result = _evalfile (filename, flags);
|
||||
free (filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined (HISTORY)
|
||||
int
|
||||
fc_execute_file (filename)
|
||||
const char *filename;
|
||||
{
|
||||
int flags;
|
||||
|
||||
/* We want these commands to show up in the history list if
|
||||
remember_on_history is set. */
|
||||
flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
|
||||
return (_evalfile (filename, flags));
|
||||
}
|
||||
#endif /* HISTORY */
|
||||
|
||||
int
|
||||
source_file (filename, sflags)
|
||||
const char *filename;
|
||||
int sflags;
|
||||
{
|
||||
int flags, rval;
|
||||
|
||||
flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
|
||||
if (sflags)
|
||||
flags |= FEVAL_NOPUSHARGS;
|
||||
/* POSIX shells exit if non-interactive and file error. */
|
||||
if (posixly_correct && interactive_shell == 0)
|
||||
flags |= FEVAL_LONGJMP;
|
||||
rval = _evalfile (filename, flags);
|
||||
|
||||
run_return_trap ();
|
||||
return rval;
|
||||
}
|
||||
+14
-2
@@ -148,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;
|
||||
}
|
||||
|
||||
|
||||
+11
-3
@@ -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.
|
||||
|
||||
@@ -148,8 +148,16 @@ 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]))
|
||||
{
|
||||
builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno));
|
||||
exit_value = EX_NOEXEC;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_notfound (args[0]);
|
||||
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
|
||||
}
|
||||
goto failed_exec;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -788,6 +788,7 @@ tescape (estart, cp, lenp, sawc)
|
||||
{
|
||||
register char *p;
|
||||
int temp, c, evalue;
|
||||
unsigned long uvalue;
|
||||
|
||||
p = estart;
|
||||
if (lenp)
|
||||
@@ -845,19 +846,19 @@ tescape (estart, cp, lenp, sawc)
|
||||
case 'u':
|
||||
case 'U':
|
||||
temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */
|
||||
for (evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
|
||||
evalue = (evalue * 16) + HEXVALUE (*p);
|
||||
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 (evalue <= UCHAR_MAX)
|
||||
*cp = evalue;
|
||||
if (uvalue <= UCHAR_MAX)
|
||||
*cp = uvalue;
|
||||
else
|
||||
{
|
||||
temp = u32cconv (evalue, cp);
|
||||
temp = u32cconv (uvalue, cp);
|
||||
cp[temp] = '\0';
|
||||
if (lenp)
|
||||
*lenp = temp;
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
This file is source.def, from which is created source.c.
|
||||
It implements the builtins "." and "source" in Bash.
|
||||
|
||||
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 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES source.c
|
||||
|
||||
$BUILTIN source
|
||||
$FUNCTION source_builtin
|
||||
$SHORT_DOC source filename [arguments]
|
||||
Execute commands from a file in the current shell.
|
||||
|
||||
Read and execute commands from FILENAME in the current shell. The
|
||||
entries in $PATH are used to find the directory containing FILENAME.
|
||||
If any ARGUMENTS are supplied, they become the positional parameters
|
||||
when FILENAME is executed.
|
||||
|
||||
Exit Status:
|
||||
Returns the status of the last command executed in FILENAME; fails if
|
||||
FILENAME cannot be read.
|
||||
$END
|
||||
|
||||
$BUILTIN .
|
||||
$DOCNAME dot
|
||||
$FUNCTION source_builtin
|
||||
$SHORT_DOC . filename [arguments]
|
||||
Execute commands from a file in the current shell.
|
||||
|
||||
Read and execute commands from FILENAME in the current shell. The
|
||||
entries in $PATH are used to find the directory containing FILENAME.
|
||||
If any ARGUMENTS are supplied, they become the positional parameters
|
||||
when FILENAME is executed.
|
||||
|
||||
Exit Status:
|
||||
Returns the status of the last command executed in FILENAME; fails if
|
||||
FILENAME cannot be read.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include "filecntl.h"
|
||||
#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../flags.h"
|
||||
#include "../findcmd.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "../trap.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int last_command_exit_value;
|
||||
|
||||
static void maybe_pop_dollar_vars __P((void));
|
||||
|
||||
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
|
||||
int source_uses_path = 1;
|
||||
|
||||
/* If non-zero, `.' looks in the current directory if the filename argument
|
||||
is not found in the $PATH. */
|
||||
int source_searches_cwd = 1;
|
||||
|
||||
/* If this . script is supplied arguments, we save the dollar vars and
|
||||
replace them with the script arguments for the duration of the script's
|
||||
execution. If the script does not change the dollar vars, we restore
|
||||
what we saved. If the dollar vars are changed in the script, and we are
|
||||
not executing a shell function, we leave the new values alone and free
|
||||
the saved values. */
|
||||
static void
|
||||
maybe_pop_dollar_vars ()
|
||||
{
|
||||
if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
|
||||
dispose_saved_dollar_vars ();
|
||||
else
|
||||
pop_dollar_vars ();
|
||||
if (debugging_mode)
|
||||
pop_args (); /* restore BASH_ARGC and BASH_ARGV */
|
||||
set_dollar_vars_unchanged ();
|
||||
}
|
||||
|
||||
/* Read and execute commands from the file passed as argument. Guess what.
|
||||
This cannot be done in a subshell, since things like variable assignments
|
||||
take place in there. So, I open the file, place it into a large string,
|
||||
close the file, and then execute the string. */
|
||||
int
|
||||
source_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int result;
|
||||
char *filename, *debug_trap;
|
||||
|
||||
if (no_options (list))
|
||||
return (EX_USAGE);
|
||||
list = loptend;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_error (_("filename argument required"));
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted && strchr (list->word->word, '/'))
|
||||
{
|
||||
sh_restricted (list->word->word);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
filename = (char *)NULL;
|
||||
/* XXX -- should this be absolute_pathname? */
|
||||
if (posixly_correct && strchr (list->word->word, '/'))
|
||||
filename = savestring (list->word->word);
|
||||
else if (absolute_pathname (list->word->word))
|
||||
filename = savestring (list->word->word);
|
||||
else if (source_uses_path)
|
||||
filename = find_path_file (list->word->word);
|
||||
if (filename == 0)
|
||||
{
|
||||
if (source_searches_cwd == 0)
|
||||
{
|
||||
builtin_error (_("%s: file not found"), list->word->word);
|
||||
if (posixly_correct && interactive_shell == 0)
|
||||
{
|
||||
last_command_exit_value = 1;
|
||||
jump_to_top_level (EXITPROG);
|
||||
}
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
filename = savestring (list->word->word);
|
||||
}
|
||||
|
||||
begin_unwind_frame ("source");
|
||||
add_unwind_protect ((Function *)xfree, filename);
|
||||
|
||||
if (list->next)
|
||||
{
|
||||
push_dollar_vars ();
|
||||
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
|
||||
remember_args (list->next, 1);
|
||||
if (debugging_mode)
|
||||
push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */
|
||||
}
|
||||
set_dollar_vars_unchanged ();
|
||||
|
||||
/* Don't inherit the DEBUG trap unless function_trace_mode (overloaded)
|
||||
is set. XXX - should sourced files inherit the RETURN trap? Functions
|
||||
don't. */
|
||||
debug_trap = TRAP_STRING (DEBUG_TRAP);
|
||||
if (debug_trap && function_trace_mode == 0)
|
||||
{
|
||||
debug_trap = savestring (debug_trap);
|
||||
add_unwind_protect (xfree, debug_trap);
|
||||
add_unwind_protect (set_debug_trap, debug_trap);
|
||||
restore_default_signal (DEBUG_TRAP);
|
||||
}
|
||||
|
||||
result = source_file (filename, (list && list->next));
|
||||
|
||||
run_unwind_frame ("source");
|
||||
|
||||
return (result);
|
||||
}
|
||||
+11
-1
@@ -256,6 +256,8 @@ SHELL_VAR *this_shell_function;
|
||||
/* If non-zero, matches in case and [[ ... ]] are case-insensitive */
|
||||
int match_ignore_case = 0;
|
||||
|
||||
int executing_command_builtin = 0;
|
||||
|
||||
struct stat SB; /* used for debugging */
|
||||
|
||||
static int special_builtin_failed;
|
||||
@@ -3889,7 +3891,10 @@ run_builtin:
|
||||
if (builtin || func)
|
||||
{
|
||||
if (builtin)
|
||||
unwind_protect_int (executing_builtin); /* modified in execute_builtin */
|
||||
{
|
||||
unwind_protect_int (executing_builtin); /* modified in execute_builtin */
|
||||
unwind_protect_int (executing_command_builtin); /* ditto */
|
||||
}
|
||||
if (already_forked)
|
||||
{
|
||||
/* reset_terminating_signals (); */ /* XXX */
|
||||
@@ -4076,6 +4081,7 @@ execute_builtin (builtin, words, flags, subshell)
|
||||
}
|
||||
|
||||
executing_builtin++;
|
||||
executing_command_builtin |= builtin == command_builtin;
|
||||
result = ((*builtin) (words->next));
|
||||
|
||||
/* This shouldn't happen, but in case `return' comes back instead of
|
||||
@@ -4928,7 +4934,11 @@ shell_execve (command, args, env)
|
||||
if (i != ENOEXEC)
|
||||
{
|
||||
if (file_isdir (command))
|
||||
#if defined (EISDIR)
|
||||
internal_error (_("%s: %s"), command, strerror (EISDIR));
|
||||
#else
|
||||
internal_error (_("%s: is a directory"), command);
|
||||
#endif
|
||||
else if (executable_file (command) == 0)
|
||||
{
|
||||
errno = i;
|
||||
|
||||
+12
-2
@@ -256,6 +256,8 @@ SHELL_VAR *this_shell_function;
|
||||
/* If non-zero, matches in case and [[ ... ]] are case-insensitive */
|
||||
int match_ignore_case = 0;
|
||||
|
||||
int executing_command_builtin = 0;
|
||||
|
||||
struct stat SB; /* used for debugging */
|
||||
|
||||
static int special_builtin_failed;
|
||||
@@ -735,7 +737,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
execute_simple_command (command->value.Simple, pipe_in, pipe_out,
|
||||
asynchronous, fds_to_close);
|
||||
line_number = save_line_number;
|
||||
itrace("execute_simple_command (%s) returns %d", command->value.Simple->words->word->word, exec_result);
|
||||
|
||||
/* The temporary environment should be used for only the simple
|
||||
command immediately following its definition. */
|
||||
dispose_used_env_vars ();
|
||||
@@ -3889,7 +3891,10 @@ run_builtin:
|
||||
if (builtin || func)
|
||||
{
|
||||
if (builtin)
|
||||
unwind_protect_int (executing_builtin); /* modified in execute_builtin */
|
||||
{
|
||||
unwind_protect_int (executing_builtin); /* modified in execute_builtin */
|
||||
unwind_protect_int (executing_command_builtin); /* ditto */
|
||||
}
|
||||
if (already_forked)
|
||||
{
|
||||
/* reset_terminating_signals (); */ /* XXX */
|
||||
@@ -4076,6 +4081,7 @@ execute_builtin (builtin, words, flags, subshell)
|
||||
}
|
||||
|
||||
executing_builtin++;
|
||||
executing_command_builtin = builtin == command_builtin;
|
||||
result = ((*builtin) (words->next));
|
||||
|
||||
/* This shouldn't happen, but in case `return' comes back instead of
|
||||
@@ -4928,7 +4934,11 @@ shell_execve (command, args, env)
|
||||
if (i != ENOEXEC)
|
||||
{
|
||||
if (file_isdir (command))
|
||||
#if defined (EISDIR)
|
||||
internal_error (_("%s: %s"), command, strerror (EISDIR));
|
||||
#else
|
||||
internal_error (_("%s: is a directory"), command);
|
||||
#endif
|
||||
else if (executable_file (command) == 0)
|
||||
{
|
||||
errno = i;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include "bashansi.h"
|
||||
|
||||
@@ -43,6 +44,10 @@
|
||||
#include "hashcmd.h"
|
||||
#include "findcmd.h" /* matching prototypes and declarations */
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
extern int posixly_correct;
|
||||
|
||||
/* Static functions defined and used in this file. */
|
||||
@@ -172,6 +177,10 @@ executable_file (file)
|
||||
int s;
|
||||
|
||||
s = file_status (file);
|
||||
#if defined EISDIR
|
||||
if (s & FS_DIRECTORY)
|
||||
errno = EISDIR; /* let's see if we can improve error messages */
|
||||
#endif
|
||||
return ((s & FS_EXECABLE) && ((s & FS_DIRECTORY) == 0));
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -49,11 +49,9 @@ ansicstr (string, len, flags, sawc, rlen)
|
||||
char *string;
|
||||
int len, flags, *sawc, *rlen;
|
||||
{
|
||||
int c, temp, v;
|
||||
int c, temp;
|
||||
char *ret, *r, *s;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/
|
||||
#endif
|
||||
unsigned long v;
|
||||
|
||||
if (string == 0 || *string == '\0')
|
||||
return ((char *)NULL);
|
||||
@@ -153,7 +151,6 @@ ansicstr (string, len, flags, sawc, rlen)
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (mbch, '\0', sizeof (mbch));
|
||||
temp = u32cconv (v, r);
|
||||
r += temp;
|
||||
continue;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/* strtrans.c - Translate and untranslate strings with ANSI-C escape sequences. */
|
||||
|
||||
/* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2000-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user