The new import builtin works just like the source builtin but it searches only the directories in BASH_IMPORT_PATH, allowing programmers to create reusable libraries without their scripts needing to be placed in the same locations as normal executable commands or other sourceable scripts.
Signed-off-by: Matheus Afonso Martins Moreira <math...@matheusmoreira.com> --- AUTHORS | 1 + MANIFEST | 1 + Makefile.in | 4 +- builtins/Makefile.in | 6 ++- builtins/import.def | 99 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 builtins/import.def diff --git a/AUTHORS b/AUTHORS index 9ad0ba28..ec4098c4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -121,6 +121,7 @@ builtins/getopts.def Brian Fox, Chet Ramey builtins/hash.def Brian Fox, Chet Ramey builtins/hashcom.h Brian Fox, Chet Ramey builtins/help.def Brian Fox, Chet Ramey +builtins/import.def Matheus Afonso Martins Moreira builtins/let.def Chet Ramey, Brian Fox builtins/history.def Brian Fox, Chet Ramey builtins/jobs.def Brian Fox, Chet Ramey diff --git a/MANIFEST b/MANIFEST index a45b3cfc..75754375 100644 --- a/MANIFEST +++ b/MANIFEST @@ -180,6 +180,7 @@ builtins/getopt.h f builtins/getopts.def f builtins/hash.def f builtins/help.def f +builtins/import.def f builtins/let.def f builtins/history.def f builtins/jobs.def f diff --git a/Makefile.in b/Makefile.in index 0b4df73a..83da6d32 100644 --- a/Makefile.in +++ b/Makefile.in @@ -510,7 +510,8 @@ BUILTIN_DEFS = $(DEFSRC)/alias.def $(DEFSRC)/bind.def $(DEFSRC)/break.def \ $(DEFSRC)/echo.def $(DEFSRC)/enable.def $(DEFSRC)/eval.def \ $(DEFSRC)/exec.def $(DEFSRC)/exit.def $(DEFSRC)/fc.def \ $(DEFSRC)/fg_bg.def $(DEFSRC)/hash.def $(DEFSRC)/help.def \ - $(DEFSRC)/history.def $(DEFSRC)/jobs.def $(DEFSRC)/kill.def \ + $(DEFSRC)/history.def $(DEFSRC)/import.def \ + $(DEFSRC)/jobs.def $(DEFSRC)/kill.def \ $(DEFSRC)/let.def $(DEFSRC)/read.def $(DEFSRC)/return.def \ $(DEFSRC)/set.def $(DEFSRC)/setattr.def $(DEFSRC)/shift.def \ $(DEFSRC)/source.def $(DEFSRC)/suspend.def $(DEFSRC)/test.def \ @@ -1757,6 +1758,7 @@ builtins/getopts.o: $(DEFSRC)/getopts.def builtins/hash.o: $(DEFSRC)/hash.def builtins/help.o: $(DEFSRC)/help.def builtins/history.o: $(DEFSRC)/history.def +builtins/import.o: $(DEFSRC)/import.def builtins/inlib.o: $(DEFSRC)/inlib.def builtins/jobs.o: $(DEFSRC)/jobs.def builtins/kill.o: $(DEFSRC)/kill.def diff --git a/builtins/Makefile.in b/builtins/Makefile.in index 642878c6..e19105e1 100644 --- a/builtins/Makefile.in +++ b/builtins/Makefile.in @@ -137,7 +137,8 @@ DEFSRC = $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \ $(srcdir)/enable.def $(srcdir)/eval.def $(srcdir)/getopts.def \ $(srcdir)/exec.def $(srcdir)/exit.def $(srcdir)/fc.def \ $(srcdir)/fg_bg.def $(srcdir)/hash.def $(srcdir)/help.def \ - $(srcdir)/history.def $(srcdir)/jobs.def $(srcdir)/kill.def \ + $(srcdir)/history.def $(srcdir)/import.def \ + $(srcdir)/jobs.def $(srcdir)/kill.def \ $(srcdir)/let.def $(srcdir)/read.def $(srcdir)/return.def \ $(srcdir)/set.def $(srcdir)/setattr.def $(srcdir)/shift.def \ $(srcdir)/source.def $(srcdir)/suspend.def $(srcdir)/test.def \ @@ -153,7 +154,7 @@ OFILES = builtins.o \ alias.o bind.o break.o builtin.o caller.o cd.o colon.o command.o \ common.o declare.o echo.o enable.o eval.o evalfile.o \ evalstring.o exec.o exit.o fc.o fg_bg.o hash.o help.o history.o \ - jobs.o kill.o let.o mapfile.o \ + import.o jobs.o kill.o let.o mapfile.o \ pushd.o read.o return.o set.o setattr.o shift.o source.o \ suspend.o test.o times.o trap.o type.o ulimit.o umask.o \ wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o @@ -298,6 +299,7 @@ fg_bg.o: fg_bg.def hash.o: hash.def help.o: help.def history.o: history.def +import.o: import.def jobs.o: jobs.def kill.o: kill.def let.o: let.def diff --git a/builtins/import.def b/builtins/import.def new file mode 100644 index 00000000..4c1bb66a --- /dev/null +++ b/builtins/import.def @@ -0,0 +1,99 @@ +This file is import.def, from which is created import.c. +It implements the builtin "import" in Bash. + +Copyright (C) 1987-2024 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 import.c + +$BUILTIN import +$FUNCTION import_builtin +$SHORT_DOC import FILENAME [arguments] +Execute commands from a file in the current shell. + +Read and execute commands from FILENAME in the current shell. +The entries in $BASH_IMPORT_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 "../execute_cmd.h" +#include "../flags.h" +#include "../findcmd.h" +#include "common.h" +#include "bashgetopt.h" +#include "../trap.h" + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* Find, read and execute commands from the file passed as argument. */ +int +import_builtin (list) + WORD_LIST *list; +{ + char *filename; + + 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 + + if (absolute_pathname (list->word->word)) + filename = savestring (list->word->word); + else + filename = find_user_import (list->word->word); + + return execute_file_contents (list, filename, "import"); +} -- 2.44.0