149 lines
4.0 KiB
Modula-2
149 lines
4.0 KiB
Modula-2
This file is source.def, from which is created source.c.
|
|
It implements the builtins "." and "source" in Bash.
|
|
|
|
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
|
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
$PRODUCES source.c
|
|
|
|
$BUILTIN source
|
|
$FUNCTION source_builtin
|
|
$SHORT_DOC source filename
|
|
Read and execute commands from FILENAME and return. The pathnames
|
|
in $PATH are used to find the directory containing FILENAME.
|
|
$END
|
|
$BUILTIN .
|
|
$DOCNAME dot
|
|
$FUNCTION source_builtin
|
|
$SHORT_DOC . [filename]
|
|
Read and execute commands from FILENAME and return. The pathnames
|
|
in $PATH are used to find the directory containing FILENAME.
|
|
$END
|
|
/* source.c - Implements the `.' and `source' builtins. */
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/file.h>
|
|
#include <errno.h>
|
|
#include "../shell.h"
|
|
#include "../posixstat.h"
|
|
#include "../filecntl.h"
|
|
|
|
extern int errno;
|
|
|
|
/* 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. */
|
|
source_builtin (list)
|
|
WORD_LIST *list;
|
|
{
|
|
extern int return_catch_flag, return_catch_value;
|
|
extern jmp_buf return_catch;
|
|
int result, return_val;
|
|
|
|
/* Assume the best. */
|
|
result = EXECUTION_SUCCESS;
|
|
|
|
if (list)
|
|
{
|
|
extern char *find_path_file ();
|
|
char *string, *filename, *tempfile;
|
|
struct stat finfo;
|
|
int fd, tt;
|
|
|
|
tempfile = find_path_file (list->word->word);
|
|
|
|
if (!tempfile)
|
|
tempfile = savestring (list->word->word);
|
|
|
|
filename = (char *)alloca (1 + strlen (tempfile));
|
|
strcpy (filename, tempfile);
|
|
free (tempfile);
|
|
|
|
if (stat (filename, &finfo) == -1 ||
|
|
(fd = open (filename, O_RDONLY)) == -1)
|
|
goto file_error_exit;
|
|
|
|
string = (char *)xmalloc (1 + finfo.st_size);
|
|
tt = read (fd, string, finfo.st_size);
|
|
string[finfo.st_size] = '\0';
|
|
|
|
/* Close the open file, preserving the state of errno. */
|
|
{ int temp = errno; close (fd); errno = temp; }
|
|
|
|
if (tt != finfo.st_size)
|
|
{
|
|
free (string);
|
|
|
|
file_error_exit:
|
|
file_error (filename);
|
|
#if defined (ALLOW_RIGID_POSIX_COMPLIANCE)
|
|
/* POSIX shells exit if non-interactive and file error. */
|
|
if (getenv ("POSIX_PENDANTIC"))
|
|
{
|
|
extern int interactive_shell;
|
|
|
|
if (!interactive_shell)
|
|
longjmp (top_level, EXITPROG);
|
|
}
|
|
#endif /* ALLOW_RIGID_POSIX_COMPLIANCE */
|
|
return (EXECUTION_FAILURE);
|
|
}
|
|
|
|
if (tt > 80)
|
|
tt = 80;
|
|
|
|
if (check_binary_file (string, tt))
|
|
{
|
|
free (string);
|
|
builtin_error ("%s: cannot execute binary file", filename);
|
|
return (EX_BINARY_FILE);
|
|
}
|
|
|
|
begin_unwind_frame ("File Sourcing");
|
|
|
|
if (list->next)
|
|
{
|
|
extern void pop_dollar_vars (), push_dollar_vars ();
|
|
|
|
push_dollar_vars ();
|
|
add_unwind_protect ((Function *)pop_dollar_vars, (char *)NULL);
|
|
remember_args (list->next, 1);
|
|
}
|
|
|
|
unwind_protect_int (return_catch_flag);
|
|
unwind_protect_jmp_buf (return_catch);
|
|
|
|
return_catch_flag++;
|
|
return_val = setjmp (return_catch);
|
|
|
|
if (return_val)
|
|
parse_and_execute_cleanup ();
|
|
else
|
|
result = parse_and_execute (string, filename);
|
|
|
|
run_unwind_frame ("File Sourcing");
|
|
|
|
/* If RETURN_VAL is non-zero, then we return the value given
|
|
to return_builtin (), since that is how we got here. */
|
|
if (return_val)
|
|
result = return_catch_value;
|
|
}
|
|
return (result);
|
|
}
|