1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-02 22:11:54 +02:00

zsh-workers/8770

This commit is contained in:
Tanaka Akira 1999-11-24 16:20:58 +00:00
parent f853592fa0
commit f8b0dee880
30 changed files with 338 additions and 336 deletions

View file

@ -1390,20 +1390,20 @@ item(tt(zmodload) tt(-ua) [ tt(-i) ] var(builtin) ...)(
Equivalent to tt(-ab) and tt(-ub).
)
item(tt(zmodload -e) [ var(string) ... ])(
The tt(-e) option without arguments lists all modules loaded or linked
into the shell. With arguments only the return status is set to zero
if all var(string)s given as arguments are names of modules loaded or
linked in and to one if at least on var(string) is not the name of a
module loaded or linked. This can be used to test for the availability
The tt(-e) option without arguments lists all loaded modules loaded.
With arguments only the return status is set to zero
if all var(string)s given as arguments are names of loaded modules
and to one if at least on var(string) is not the name of a
loaded module. This can be used to test for the availability
of things implemented by modules.
)
enditem()
In a shell without dynamic loading only the tt(-e) option is
supported and the tt(-i) option is ignored. In such a shell the return
status of tt(zmodload) without arguments or options is one whereas in
a shell with dynamic loading the return status without arguments or
options is always zero. This can be used to test if the shell supports
dynamic loading of modules or not.
Note that tt(zsh) makes no difference between modules that were linked
into the shell and modules that are loaded dynamically. In both cases
this builtin command has to be used to make available the builtins and
other things defined by modules (unless the module is autoloaded on
these definitions). This is even true for systems that don't support
dynamic loading of modules.
)
enditem()

View file

@ -151,9 +151,7 @@ The third one, named `cleanup_foo' for module `foo' is called when the
user tries to unload a module and should de-register the builtins
etc. The last function, `finish_foo' is called when the module is
actually unloaded and should finalize all the data initialized in the
`setup'-function. Since the last two functions are only executed when
the module is used as an dynamically loaded module you can surround
it with `#ifdef MODULE' and `#endif'.
`setup'-function.
In short, the `cleanup'-function should undo what the `boot'-function
did, and the `finish'-function should undo what the `setup'-function
did.

View file

@ -637,8 +637,6 @@ boot_rlimits(Module m)
return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
}
#ifdef MODULE
/**/
int
cleanup_rlimits(Module m)
@ -653,5 +651,3 @@ finish_rlimits(Module m)
{
return 0;
}
#endif

View file

@ -200,8 +200,6 @@ boot_sched(Module m)
return 0;
}
#ifdef MODULE
/**/
int
cleanup_sched(Module m)
@ -224,5 +222,3 @@ finish_sched(Module m)
{
return 0;
}
#endif

View file

@ -136,8 +136,6 @@ boot_cap(Module m)
return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
}
#ifdef MODULE
/**/
int
cleanup_cap(Module m)
@ -152,5 +150,3 @@ finish_cap(Module m)
{
return 0;
}
#endif

View file

@ -110,8 +110,6 @@ boot_clone(Module m)
return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
}
#ifdef MODULE
/**/
int
cleanup_clone(Module m)
@ -126,5 +124,3 @@ finish_clone(Module m)
{
return 0;
}
#endif

View file

@ -212,8 +212,6 @@ boot_example(Module m)
!addwrapper(m, wrapper));
}
#ifdef MODULE
/**/
int
cleanup_example(Module m)
@ -234,5 +232,3 @@ finish_example(Module m)
fflush(stdout);
return 0;
}
#endif

View file

@ -523,8 +523,6 @@ boot_files(Module m)
return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
}
#ifdef MODULE
/**/
int
cleanup_files(Module m)
@ -539,5 +537,3 @@ finish_files(Module m)
{
return 0;
}
#endif

View file

@ -346,8 +346,6 @@ boot_mapfile(Module m)
return 0;
}
#ifdef MODULE
/**/
int
cleanup_mapfile(Module m)
@ -370,5 +368,3 @@ finish_mapfile(Module m)
{
return 0;
}
#endif

View file

@ -462,8 +462,6 @@ boot_mathfunc(Module m)
return !addmathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab));
}
#ifdef MODULE
/**/
int
cleanup_mathfunc(Module m)
@ -478,5 +476,3 @@ finish_mathfunc(Module m)
{
return 0;
}
#endif

View file

@ -901,18 +901,12 @@ getpmmodule(HashTable ht, char *name)
pm->old = NULL;
pm->level = 0;
for (node = firstnode(bltinmodules); node; incnode(node))
if (!strcmp(name, (char *) getdata(node))) {
type = "builtin";
break;
}
#ifdef DYNAMIC
if (!type) {
Module m;
for (node = firstnode(modules); node; incnode(node)) {
m = (Module) getdata(node);
if (m->handle && !(m->flags & MOD_UNLOAD) &&
if (m->u.handle && !(m->flags & MOD_UNLOAD) &&
!strcmp(name, m->nam)) {
type = "loaded";
break;
@ -937,7 +931,6 @@ getpmmodule(HashTable ht, char *name)
if (modpmfound)
type = "autoloaded";
}
#endif
if (type)
pm->u.str = dupstring(type);
else {
@ -972,16 +965,10 @@ scanpmmodules(HashTable ht, ScanFunc func, int flags)
pm.level = 0;
pm.u.str = dupstring("builtin");
for (node = firstnode(bltinmodules); node; incnode(node)) {
pm.nam = (char *) getdata(node);
addlinknode(done, pm.nam);
func((HashNode) &pm, flags);
}
#ifdef DYNAMIC
pm.u.str = dupstring("loaded");
for (node = firstnode(modules); node; incnode(node)) {
m = (Module) getdata(node);
if (m->handle && !(m->flags & MOD_UNLOAD)) {
if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
pm.nam = m->nam;
addlinknode(done, pm.nam);
func((HashNode) &pm, flags);
@ -1012,7 +999,6 @@ scanpmmodules(HashTable ht, ScanFunc func, int flags)
func((HashNode) &pm, flags);
}
}
#endif
}
/* Functions for the dirstack special parameter. */
@ -1919,8 +1905,6 @@ boot_parameter(Module m)
return 0;
}
#ifdef MODULE
/**/
int
cleanup_parameter(Module m)
@ -1949,5 +1933,3 @@ finish_parameter(Module m)
{
return 0;
}
#endif

View file

@ -602,8 +602,6 @@ boot_stat(Module m)
return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
}
#ifdef MODULE
/**/
int
cleanup_stat(Module m)
@ -618,5 +616,3 @@ finish_stat(Module m)
{
return 0;
}
#endif

View file

@ -3213,8 +3213,6 @@ boot_zftp(Module m)
return !ret;
}
#ifdef MODULE
/**/
int
cleanup_zftp(Module m)
@ -3249,5 +3247,3 @@ finish_zftp(Module m)
{
return 0;
}
#endif

View file

@ -3764,8 +3764,6 @@ boot_compctl(Module m)
return (addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) != 1);
}
#ifdef MODULE
/**/
int
cleanup_compctl(Module m)
@ -3789,5 +3787,3 @@ finish_compctl(Module m)
compctlreadptr = fallback_compctlread;
return 0;
}
#endif

View file

@ -1389,8 +1389,6 @@ boot_complete(Module m)
return 0;
}
#ifdef MODULE
/**/
int
cleanup_complete(Module m)
@ -1414,7 +1412,8 @@ cleanup_complete(Module m)
int
finish_complete(Module m)
{
freearray(compwords);
if (compwords)
freearray(compwords);
zsfree(compprefix);
zsfree(compsuffix);
zsfree(compiprefix);
@ -1446,5 +1445,3 @@ finish_complete(Module m)
return 0;
}
#endif

View file

@ -935,8 +935,6 @@ boot_complist(Module m)
return 0;
}
#ifdef MODULE
/**/
int
cleanup_complist(Module m)
@ -957,5 +955,3 @@ finish_complist(Module m)
{
return 0;
}
#endif

View file

@ -2837,8 +2837,6 @@ boot_computil(Module m)
return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
}
#ifdef MODULE
/**/
int
cleanup_computil(Module m)
@ -2865,5 +2863,3 @@ finish_computil(Module m)
return 0;
}
#endif

View file

@ -98,8 +98,6 @@ boot_deltochar(Module m)
return -1;
}
#ifdef MODULE
/**/
int
cleanup_deltochar(Module m)
@ -115,5 +113,3 @@ finish_deltochar(Module m)
{
return 0;
}
#endif

View file

@ -611,9 +611,6 @@ static struct isrch_spot {
static int max_spot = 0;
/**/
#ifdef MODULE
/**/
void
free_isrch_spots(void)
@ -621,9 +618,6 @@ free_isrch_spots(void)
zfree(isrch_spots, max_spot * sizeof(*isrch_spots));
}
/**/
#endif /* MODULE */
/**/
static void
set_isrch_spot(int num, int hl, int pos, int cs, int len, int dir, int nomatch)

View file

@ -1000,8 +1000,6 @@ init_keymaps(void)
lastnamed = refthingy(t_undefinedkey);
}
#ifdef MODULE
/* cleanup entry point (for unloading the zle module) */
/**/
@ -1013,8 +1011,6 @@ cleanup_keymaps(void)
zfree(keybuf, keybufsz);
}
#endif /* MODULE */
/* Create the default keymaps. For efficiency reasons, this function *
* assigns directly to the km->first array. It knows that there are no *
* prefix bindings in the way, and that it is using a simple keymap. */

View file

@ -1043,8 +1043,6 @@ boot_zle(Module m)
return 0;
}
#ifdef MODULE
/**/
int
cleanup_zle(Module m)
@ -1093,5 +1091,3 @@ finish_zle(Module m)
return 0;
}
#endif /* MODULE */

View file

@ -286,8 +286,6 @@ addzlefunction(char *name, ZleIntFunc ifunc, int flags)
return w;
}
#ifdef DYNAMIC
/* Delete an internal widget provided by a module. Don't try to delete *
* a widget from the fixed table -- it would be bad. (Thanks, Egon.) */
@ -309,8 +307,6 @@ deletezlefunction(Widget w)
}
}
#endif /* DYNAMIC */
/***************/
/* zle builtin */
/***************/
@ -550,18 +546,10 @@ bin_zle_complete(char *name, char **args, char *ops, char func)
Thingy t;
Widget w, cw;
#ifdef DYNAMIC
if (!require_module(name, "complete", 0, 0)) {
zerrnam(name, "can't load complete module", NULL, 0);
return 1;
}
#else
if (!module_linked("complete")) {
zerrnam(name, "complete module not available", NULL, 0);
return 1;
}
#endif
t = rthingy((args[1][0] == '.') ? args[1] : dyncat(".", args[1]));
cw = t->widget;
unrefthingy(t);

View file

@ -230,8 +230,6 @@ boot_zleparameter(Module m)
return 0;
}
#ifdef MODULE
/**/
int
cleanup_zleparameter(Module m)
@ -255,5 +253,3 @@ finish_zleparameter(Module m)
{
return 0;
}
#endif

View file

@ -123,12 +123,7 @@ static struct builtin builtins[] =
BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsw", NULL),
BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsw", "ca"),
BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
#ifdef DYNAMIC
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ILabcfdipue", NULL),
#else
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ei", NULL),
#endif
};
/****************************************/
@ -229,14 +224,11 @@ execbuiltin(LinkList args, Builtin bn)
arg = (char *) ugetnode(args);
#ifdef DYNAMIC
if (!bn->handlerfunc) {
zwarnnam(name, "autoload failed", NULL, 0);
deletebuiltin(bn->nam);
return 1;
}
#endif
/* get some information about the command */
flags = bn->flags;
optstr = bn->optstr;
@ -3209,6 +3201,8 @@ zexit(int val, int from_signal)
if (in_exit++ && from_signal) {
LASTALLOC_RETURN;
}
exit_modules();
if (isset(MONITOR)) {
/* send SIGHUP to any jobs left running */
killrunjobs(from_signal);

View file

@ -1504,13 +1504,12 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
}
if (!(hn->flags & BINF_PREFIX)) {
is_builtin = 1;
#ifdef DYNAMIC
/* autoload the builtin if necessary */
if (!((Builtin) hn)->handlerfunc) {
load_module(((Builtin) hn)->optstr);
hn = builtintab->getnode(builtintab, cmdarg);
}
#endif
assign = (hn->flags & BINF_MAGICEQUALS);
break;
}
@ -1619,13 +1618,12 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
}
if (!(hn->flags & BINF_PREFIX)) {
is_builtin = 1;
#ifdef DYNAMIC
/* autoload the builtin if necessary */
if (!((Builtin) hn)->handlerfunc) {
load_module(((Builtin) hn)->optstr);
hn = builtintab->getnode(builtintab, cmdarg);
}
#endif
break;
}
cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
@ -3072,11 +3070,11 @@ runshfunc(List list, FuncWrap wrap, char *name)
wrap->module->wrapper++;
cont = wrap->handler(list, wrap->next, name);
wrap->module->wrapper--;
#ifdef DYNAMIC
if (!wrap->module->wrapper &&
(wrap->module->flags & MOD_UNLOAD))
unload_module(wrap->module, NULL);
#endif
unload_module(wrap->module, NULL, 0);
if (!cont)
return;
wrap = wrap->next;

View file

@ -599,11 +599,9 @@ setupvals(void)
mailpath = mkarray(NULL);
watch = mkarray(NULL);
psvar = mkarray(NULL);
#ifdef DYNAMIC
module_path = mkarray(ztrdup(MODULE_DIR));
modules = newlinklist();
#endif
bltinmodules = newlinklist();
linkedmodules = newlinklist();
/* Set default prompts */
if(unset(INTERACTIVE)) {
@ -940,9 +938,10 @@ sourcehome(char *s)
void
init_bltinmods(void)
{
static struct module mod = { NULL, 0, NULL, NULL };
#include "bltinmods.list"
mod.nam = NULL;
load_module("zsh");
}
/**/
@ -969,13 +968,13 @@ noop_function_int(int nothing)
/**/
ZleVoidFn trashzleptr = noop_function;
/**/
ZleVoidFn gotwordptr;
ZleVoidFn gotwordptr = noop_function;
/**/
ZleVoidFn refreshptr;
ZleVoidFn refreshptr = noop_function;
/**/
ZleVoidIntFn spaceinlineptr;
ZleVoidIntFn spaceinlineptr = noop_function_int;
/**/
ZleReadFn zlereadptr;
ZleReadFn zlereadptr = autoload_zleread;
#else /* !LINKED_XMOD_zle */
@ -989,11 +988,10 @@ ZleReadFn zlereadptr = autoload_zleread;
ZleReadFn zlereadptr = fallback_zleread;
# endif /* !UNLINKED_XMOD_zle */
/**/
# ifdef UNLINKED_XMOD_zle
#endif /* !LINKED_XMOD_zle */
/**/
static unsigned char *
unsigned char *
autoload_zleread(char *lp, char *rp, int ha)
{
zlereadptr = fallback_zleread;
@ -1001,9 +999,6 @@ autoload_zleread(char *lp, char *rp, int ha)
return zleread(lp, rp, ha);
}
/**/
# endif /* UNLINKED_XMOD_zle */
/**/
unsigned char *
fallback_zleread(char *lp, char *rp, int ha)
@ -1017,8 +1012,6 @@ fallback_zleread(char *lp, char *rp, int ha)
return (unsigned char *)shingetline();
}
#endif /* !LINKED_XMOD_zle */
/* compctl entry point pointers. Similar to the ZLE ones. */
/**/

View file

@ -4,6 +4,7 @@
#
# Written by Andrew Main
#
srcdir=${srcdir-`echo $0|sed 's%/[^/][^/]*$%%'`}
test "x$srcdir" = "x$0" && srcdir=.
test "x$srcdir" = "x" && srcdir=.
@ -18,40 +19,32 @@ trap "rm -f $1; exit 1" 1 2 15
exec > $1
echo "#ifdef DYNAMIC"
for x_mod in $x_mods; do
case $bin_mods in
*" $x_mod "*) ;;
*) echo "/* non-linked-in known module \`$x_mod' */"
eval "loc=\$loc_$x_mod"
unset moddeps autobins autoinfixconds autoprefixconds autoparams
unset automathfuncs
. $srcdir/../$loc/${x_mod}.mdd
for bin in $autobins; do
echo " add_autobin(\"$bin\", \"$x_mod\");"
done
for cond in $autoinfixconds; do
echo " add_autocond(\"$cond\", 1, \"$x_mod\");"
done
for cond in $autoprefixconds; do
echo " add_autocond(\"$cond\", 0, \"$x_mod\");"
done
for param in $autoparams; do
echo " add_autoparam(\"$param\", \"$x_mod\");"
done
for mfunc in $automathfuncs; do
echo " add_automath(\"$mfunc\", \"$x_mod\");"
done
for dep in $moddeps; do
case $bin_mods in
*" $dep "*)
echo " /* depends on \`$dep' */" ;;
*) echo " add_dep(\"$x_mod\", \"$dep\");" ;;
esac
done ;;
esac
echo "/* non-linked-in known module \`$x_mod' */"
eval "loc=\$loc_$x_mod"
unset moddeps autobins autoinfixconds autoprefixconds autoparams
unset automathfuncs
. $srcdir/../$loc/${x_mod}.mdd
for bin in $autobins; do
echo " add_autobin(\"$bin\", \"$x_mod\");"
done
for cond in $autoinfixconds; do
echo " add_autocond(\"$cond\", 1, \"$x_mod\");"
done
for cond in $autoprefixconds; do
echo " add_autocond(\"$cond\", 0, \"$x_mod\");"
done
for param in $autoparams; do
echo " add_autoparam(\"$param\", \"$x_mod\");"
done
for mfunc in $automathfuncs; do
echo " add_automath(\"$mfunc\", \"$x_mod\");"
done
for dep in $moddeps; do
echo " add_dep(\"$x_mod\", \"$dep\");"
done
done
echo "#endif /* DYNAMIC */"
echo
done_mods=" "
for bin_mod in $bin_mods; do
@ -68,6 +61,15 @@ for bin_mod in $bin_mods; do
exit 1 ;;
esac
done
echo " register_module(mod.nam = \"$bin_mod\"); setup_$bin_mod(&mod); boot_$bin_mod(&mod);"
echo " {"
echo " extern int setup_${bin_mod} _((Module));"
echo " extern int boot_${bin_mod} _((Module));"
echo " extern int cleanup_${bin_mod} _((Module));"
echo " extern int finish_${bin_mod} _((Module));"
echo
echo " register_module(\"$bin_mod\","
echo " setup_${bin_mod}, boot_${bin_mod},"
echo " cleanup_${bin_mod}, finish_${bin_mod});"
echo " }"
done_mods="$done_mods$bin_mod "
done

View file

@ -30,10 +30,10 @@
#include "zsh.mdh"
#include "module.pro"
/* List of builtin modules. */
/* List of linked-in modules. */
/**/
LinkList bltinmodules;
LinkList linkedmodules;
/* The `zsh' module contains all the base code that can't actually be built *
@ -54,30 +54,55 @@ boot_zsh(Module m)
return 0;
}
/**/
int
cleanup_zsh(Module m)
{
return 0;
}
/**/
int
finish_zsh(Module m)
{
return 0;
}
/* This registers a builtin module. */
/**/
void
register_module(char *n)
register_module(char *n, Module_func setup, Module_func boot,
Module_func cleanup, Module_func finish)
{
Linkedmod m;
PERMALLOC {
addlinknode(bltinmodules, n);
m = (Linkedmod) zalloc(sizeof(*m));
m->name = ztrdup(n);
m->setup = setup;
m->boot = boot;
m->cleanup = cleanup;
m->finish = finish;
addlinknode(linkedmodules, m);
} LASTALLOC;
}
/* Check if a module is linked in. */
/**/
int
module_linked(char *name)
Linkedmod
module_linked(char const *name)
{
LinkNode node;
for (node = firstnode(bltinmodules); node; incnode(node))
if (!strcmp((char *) getdata(node), name))
return 1;
for (node = firstnode(linkedmodules); node; incnode(node))
if (!strcmp(((Linkedmod) getdata(node))->name, name))
return (Linkedmod) getdata(node);
return 0;
return NULL;
}
/* addbuiltin() can be used to add a new builtin. It returns zero on *
@ -157,9 +182,6 @@ addwrapper(Module m, FuncWrap w)
return 0;
}
/**/
#ifdef DYNAMIC
/* $module_path ($MODULE_PATH) */
/**/
@ -254,6 +276,9 @@ deletewrapper(Module m, FuncWrap w)
return 1;
}
/**/
#ifdef DYNAMIC
/**/
#ifdef AIXDYNAMIC
@ -271,8 +296,8 @@ load_and_bind(const char *fn)
int err = loadbind(0, (void *) addbuiltin, ret);
for (node = firstnode(modules); !err && node; incnode(node)) {
Module m = (Module) getdata(node);
if (m->handle)
err |= loadbind(0, m->handle, ret);
if (m->u.handle)
err |= loadbind(0, m->u.handle, ret);
}
if (err) {
@ -361,8 +386,6 @@ hpux_dlsym(void *handle, char *name)
# define RTLD_GLOBAL 0
#endif
typedef int (*Module_func) _((Module));
/**/
static void *
try_load_module(char const *name)
@ -414,6 +437,19 @@ do_load_module(char const *name)
return ret;
}
/**/
#else /* !DYNAMIC */
/**/
static void *
do_load_module(char const *name)
{
return NULL;
}
/**/
#endif /* !DYNAMIC */
/**/
static LinkNode
find_module(const char *name)
@ -429,35 +465,38 @@ find_module(const char *name)
return NULL;
}
/**/
#ifdef DYNAMIC
/**/
#ifdef AIXDYNAMIC
/**/
static int
setup_module(Module m)
dyn_setup_module(Module m)
{
return ((int (*)_((int,Module))) m->handle)(0, m);
return ((int (*)_((int,Module))) m->u.handle)(0, m);
}
/**/
static int
init_module(Module m)
dyn_boot_module(Module m)
{
return ((int (*)_((int,Module))) m->handle)(1, m);
return ((int (*)_((int,Module))) m->u.handle)(1, m);
}
/**/
static int
cleanup_module(Module m)
dyn_cleanup_module(Module m)
{
return ((int (*)_((int,Module))) m->handle)(2, m);
return ((int (*)_((int,Module))) m->u.handle)(2, m);
}
/**/
static int
finish_module(Module m)
dyn_finish_module(Module m)
{
return ((int (*)_((int,Module))) m->handle)(3, m);
return ((int (*)_((int,Module))) m->u.handle)(3, m);
}
/**/
@ -480,19 +519,19 @@ module_func(Module m, char *name, char *name_s)
if ((t = strrchr(s, '.')))
*t = '\0';
#ifdef DYNAMIC_NAME_CLASH_OK
fn = (Module_func) dlsym(m->handle, name);
fn = (Module_func) dlsym(m->u.handle, name);
#else /* !DYNAMIC_NAME_CLASH_OK */
if (strlen(s) + 6 > PATH_MAX)
return NULL;
sprintf(buf, name_s, s);
fn = (Module_func) dlsym(m->handle, buf);
fn = (Module_func) dlsym(m->u.handle, buf);
#endif /* !DYNAMIC_NAME_CLASH_OK */
return fn;
}
/**/
static int
setup_module(Module m)
dyn_setup_module(Module m)
{
Module_func fn = module_func(m, STR_SETUP, STR_SETUP_S);
@ -504,7 +543,7 @@ setup_module(Module m)
/**/
static int
init_module(Module m)
dyn_boot_module(Module m)
{
Module_func fn = module_func(m, STR_BOOT, STR_BOOT_S);
@ -516,7 +555,7 @@ init_module(Module m)
/**/
static int
cleanup_module(Module m)
dyn_cleanup_module(Module m)
{
Module_func fn = module_func(m, STR_CLEANUP, STR_CLEANUP_S);
@ -531,7 +570,7 @@ cleanup_module(Module m)
/**/
static int
finish_module(Module m)
dyn_finish_module(Module m)
{
Module_func fn = module_func(m, STR_FINISH, STR_FINISH_S);
int r;
@ -542,42 +581,115 @@ finish_module(Module m)
zwarnnam(m->nam, "no finish function", NULL, 0);
r = 1;
}
dlclose(m->handle);
dlclose(m->u.handle);
return r;
}
/**/
#endif /* !AIXDYNAMIC */
/**/
static int
setup_module(Module m)
{
return ((m->flags & MOD_LINKED) ?
(m->u.linked->setup)(m) : dyn_setup_module(m));
}
/**/
static int
boot_module(Module m)
{
return ((m->flags & MOD_LINKED) ?
(m->u.linked->boot)(m) : dyn_boot_module(m));
}
/**/
static int
cleanup_module(Module m)
{
return ((m->flags & MOD_LINKED) ?
(m->u.linked->cleanup)(m) : dyn_cleanup_module(m));
}
/**/
static int
finish_module(Module m)
{
return ((m->flags & MOD_LINKED) ?
(m->u.linked->finish)(m) : dyn_finish_module(m));
}
/**/
#else /* !DYNAMIC */
/**/
static int
setup_module(Module m)
{
return ((m->flags & MOD_LINKED) ? (m->u.linked->setup)(m) : 1);
}
/**/
static int
boot_module(Module m)
{
return ((m->flags & MOD_LINKED) ? (m->u.linked->boot)(m) : 1);
}
/**/
static int
cleanup_module(Module m)
{
return ((m->flags & MOD_LINKED) ? (m->u.linked->cleanup)(m) : 1);
}
/**/
static int
finish_module(Module m)
{
return ((m->flags & MOD_LINKED) ? (m->u.linked->finish)(m) : 1);
}
/**/
#endif /* !DYNAMIC */
/**/
int
load_module(char const *name)
{
Module m;
void *handle;
void *handle = NULL;
Linkedmod linked;
LinkNode node, n;
if (module_linked(name))
return 1;
int set;
if (!(node = find_module(name))) {
if (!(handle = do_load_module(name)))
return NULL;
if (!(linked = module_linked(name)) &&
!(handle = do_load_module(name)))
return 0;
m = zcalloc(sizeof(*m));
m->nam = ztrdup(name);
m->handle = handle;
m->flags |= MOD_SETUP;
if (handle) {
m->u.handle = handle;
m->flags |= MOD_SETUP;
} else {
m->u.linked = linked;
m->flags |= MOD_SETUP | MOD_LINKED;
}
PERMALLOC {
node = addlinknode(modules, m);
} LASTALLOC;
if (setup_module(m) || init_module(m)) {
finish_module(m);
if ((set = setup_module(m)) || boot_module(m)) {
if (!set)
finish_module(m);
remnode(modules, node);
zsfree(m->nam);
zfree(m, sizeof(*m));
m->flags &= ~MOD_SETUP;
return NULL;
return 0;
}
m->flags |= MOD_INIT_S | MOD_INIT_B;
m->flags &= ~MOD_SETUP;
return 1;
}
@ -586,7 +698,7 @@ load_module(char const *name)
return 1;
if (m->flags & MOD_UNLOAD)
m->flags &= ~MOD_UNLOAD;
else if (m->handle)
else if ((m->flags & MOD_LINKED) ? m->u.linked : m->u.handle)
return 1;
if (m->flags & MOD_BUSY) {
zerr("circular dependencies for module %s", name, 0);
@ -600,24 +712,39 @@ load_module(char const *name)
return 0;
}
m->flags &= ~MOD_BUSY;
if (!m->handle) {
if (!(m->handle = do_load_module(name)))
if (!m->u.handle) {
handle = NULL;
if (!(linked = module_linked(name)) &&
!(handle = do_load_module(name)))
return 0;
m->flags |= MOD_SETUP;
if (handle) {
m->u.handle = handle;
m->flags |= MOD_SETUP;
} else {
m->u.linked = linked;
m->flags |= MOD_SETUP | MOD_LINKED;
}
if (setup_module(m)) {
finish_module(m->handle);
m->handle = NULL;
if (handle)
m->u.handle = NULL;
else
m->u.linked = NULL;
m->flags &= ~MOD_SETUP;
return 0;
}
m->flags |= MOD_INIT_S;
}
m->flags |= MOD_SETUP;
if (init_module(m)) {
finish_module(m->handle);
m->handle = NULL;
if (boot_module(m)) {
finish_module(m);
if (m->flags & MOD_LINKED)
m->u.linked = NULL;
else
m->u.handle = NULL;
m->flags &= ~MOD_SETUP;
return 0;
}
m->flags |= MOD_INIT_B;
m->flags &= ~MOD_SETUP;
return 1;
}
@ -638,12 +765,12 @@ require_module(char *nam, char *module, int res, int test)
LinkNode node;
/* First see if the module is linked in. */
for (node = firstnode(bltinmodules); node; incnode(node)) {
for (node = firstnode(linkedmodules); node; incnode(node)) {
if (!strcmp((char *) getdata(node), nam))
return 1;
}
node = find_module(module);
if (node && (m = ((Module) getdata(node)))->handle &&
if (node && (m = ((Module) getdata(node)))->u.handle &&
!(m->flags & MOD_UNLOAD)) {
if (test) {
zwarnnam(nam, "module %s already loaded.", module, 0);
@ -710,6 +837,47 @@ autoloadscan(HashNode hn, int printflags)
putchar('\n');
}
/* Cleanup and finish all modules. */
/**/
void
exit_modules(void)
{
Module m;
char *name;
LinkNode node, next, mn, dn;
int del, used;
while (nonempty(modules)) {
for (node = firstnode(modules); (next = node); node = next) {
incnode(next);
del = used = 0;
name = ((Module) getdata(node))->nam;
for (mn = firstnode(modules); !used && mn; incnode(mn)) {
m = (Module) getdata(mn);
if (m->deps && m->u.handle)
for (dn = firstnode(m->deps); dn; incnode(dn))
if (!strcmp((char *) getdata(dn), name)) {
if (m->flags & MOD_UNLOAD)
del = 1;
else {
used = 1;
break;
}
}
}
if (!used) {
m = (Module) getdata(node);
if (del)
m->wrapper++;
unload_module(m, NULL, 1);
if (del)
m->wrapper--;
}
}
}
}
/**/
int
bin_zmodload(char *nam, char **args, char *ops, int func)
@ -761,13 +929,9 @@ bin_zmodload_exist(char *nam, char **args, char *ops)
Module m;
if (!*args) {
for (node = firstnode(bltinmodules); node; incnode(node)) {
nicezputs((char *) getdata(node), stdout);
putchar('\n');
}
for (node = firstnode(modules); node; incnode(node)) {
m = (Module) getdata(node);
if (m->handle && !(m->flags & MOD_UNLOAD)) {
if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
nicezputs(m->nam, stdout);
putchar('\n');
}
@ -778,13 +942,10 @@ bin_zmodload_exist(char *nam, char **args, char *ops)
for (; !ret && *args; args++) {
f = 0;
for (node = firstnode(bltinmodules);
!f && node; incnode(node))
f = !strcmp(*args, (char *) getdata(node));
for (node = firstnode(modules);
!f && node; incnode(node)) {
m = (Module) getdata(node);
if (m->handle && !(m->flags & MOD_UNLOAD))
if (m->u.handle && !(m->flags & MOD_UNLOAD))
f = !strcmp(*args, m->nam);
}
ret = !f;
@ -825,7 +986,7 @@ bin_zmodload_dep(char *nam, char **args, char *ops)
m->deps = NULL;
}
}
if (!m->deps && !m->handle) {
if (!m->deps && !m->u.handle) {
remnode(modules, node);
zsfree(m->nam);
zfree(m, sizeof(*m));
@ -1111,9 +1272,13 @@ bin_zmodload_param(char *nam, char **args, char *ops)
/**/
int
unload_module(Module m, LinkNode node)
unload_module(Module m, LinkNode node, int force)
{
if (m->handle && !(m->flags & MOD_UNLOAD) && cleanup_module(m))
if ((m->flags & MOD_INIT_S) &&
!(m->flags & MOD_UNLOAD) &&
((m->flags & MOD_LINKED) ?
(m->u.linked && m->u.linked->cleanup(m)) :
(m->u.handle && cleanup_module(m))))
return 1;
else {
int del = (m->flags & MOD_UNLOAD);
@ -1123,9 +1288,19 @@ unload_module(Module m, LinkNode node)
return 0;
}
m->flags &= ~MOD_UNLOAD;
if (m->handle)
finish_module(m);
m->handle = NULL;
if (m->flags & MOD_INIT_B) {
if (m->flags & MOD_LINKED) {
if (m->u.linked) {
m->u.linked->finish(m);
m->u.linked = NULL;
}
} else {
if (m->u.handle) {
finish_module(m);
m->u.handle = NULL;
}
}
}
if (del && m->deps) {
/* The module was unloaded delayed, unload all modules *
* on which it depended. */
@ -1145,7 +1320,9 @@ unload_module(Module m, LinkNode node)
for (an = firstnode(modules); du && an; incnode(an)) {
am = (Module) getdata(an);
if (am != m && am->handle && am->deps) {
if (am != m && am->deps &&
((am->flags & MOD_LINKED) ?
am->u.linked : am->u.handle)) {
LinkNode sn;
for (sn = firstnode(am->deps); du && sn;
@ -1156,11 +1333,11 @@ unload_module(Module m, LinkNode node)
}
}
if (du)
unload_module(dm, NULL);
unload_module(dm, NULL, 0);
}
}
}
if(!m->deps) {
if(!m->deps || force) {
if (!node) {
for (node = firstnode(modules); node; incnode(node))
if (m == (Module) getdata(node))
@ -1193,7 +1370,7 @@ bin_zmodload_load(char *nam, char **args, char *ops)
for (mn = firstnode(modules); mn; incnode(mn)) {
m = (Module) getdata(mn);
if (m->deps && m->handle)
if (m->deps && m->u.handle)
for (dn = firstnode(m->deps); dn; incnode(dn))
if (!strcmp((char *) getdata(dn), *args)) {
if (m->flags & MOD_UNLOAD)
@ -1208,7 +1385,7 @@ bin_zmodload_load(char *nam, char **args, char *ops)
m = (Module) getdata(node);
if (del)
m->wrapper++;
if (unload_module(m, node))
if (unload_module(m, node, 0))
ret = 1;
if (del)
m->wrapper--;
@ -1223,7 +1400,7 @@ bin_zmodload_load(char *nam, char **args, char *ops)
/* list modules */
for (node = firstnode(modules); node; incnode(node)) {
m = (Module) getdata(node);
if (m->handle && !(m->flags & MOD_UNLOAD)) {
if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
if(ops['L']) {
printf("zmodload ");
if(m->nam[0] == '-')
@ -1245,46 +1422,6 @@ bin_zmodload_load(char *nam, char **args, char *ops)
}
}
/**/
#else /* DYNAMIC */
/* This is the version for shells without dynamic linking. */
/**/
int
bin_zmodload(char *nam, char **args, char *ops, int func)
{
/* We understand only the -e option (and ignore -i). */
if (ops['e'] || *args) {
LinkNode node;
if (!*args) {
for (node = firstnode(bltinmodules); node; incnode(node)) {
nicezputs((char *) getdata(node), stdout);
putchar('\n');
}
} else {
for (; *args; args++) {
for (node = firstnode(bltinmodules); node; incnode(node))
if (!strcmp(*args, (char *) getdata(node)))
break;
if (!node) {
if (!ops['e'])
zerrnam(nam, "cannot load module: `%s'", *args, 0);
return 1;
}
}
}
return 0;
}
/* Otherwise we return 1 -- different from the dynamic version. */
return 1;
}
/**/
#endif /* DYNAMIC */
/* The list of module-defined conditions. */
/**/
@ -1299,9 +1436,7 @@ Conddef
getconddef(int inf, char *name, int autol)
{
Conddef p;
#ifdef DYNAMIC
int f = 1;
#endif
do {
for (p = condtab; p; p = p->next) {
@ -1309,7 +1444,6 @@ getconddef(int inf, char *name, int autol)
!strcmp(name, p->name))
break;
}
#ifdef DYNAMIC
if (autol && p && p->module) {
/* This is a definition for an autoloaded condition, load the *
* module if we haven't tried that already. */
@ -1322,7 +1456,6 @@ getconddef(int inf, char *name, int autol)
return NULL;
}
} else
#endif
break;
} while (!p);
return p;
@ -1341,11 +1474,9 @@ addconddef(Conddef c)
if (p) {
if (!p->module || (p->flags & CONDF_ADDED))
return 1;
#ifdef DYNAMIC
/* There is an autoload definition. */
deleteconddef(p);
#endif
}
c->next = condtab;
condtab = c;
@ -1616,9 +1747,6 @@ deleteparamdefs(char const *nam, Paramdef d, int size)
return 1;
}
/**/
#ifdef DYNAMIC
/* This adds a definition for autoloading a module for a condition. */
/**/
@ -1709,9 +1837,6 @@ add_autoparam(char *nam, char *module)
pm->flags |= PM_AUTOLOAD;
}
/**/
#endif
/* List of math functions. */
/**/
@ -1725,7 +1850,6 @@ getmathfunc(char *name, int autol)
for (p = mathfuncs; p; q = p, p = p->next)
if (!strcmp(name, p->name)) {
#ifdef DYNAMIC
if (autol && p->module) {
char *n = dupstring(p->module);
@ -1741,7 +1865,6 @@ getmathfunc(char *name, int autol)
return getmathfunc(name, 0);
}
#endif
return p;
}
@ -1790,8 +1913,6 @@ addmathfuncs(char const *nam, MathFunc f, int size)
return hadf ? hads : 1;
}
#ifdef DYNAMIC
/**/
int
add_automathfunc(char *nam, char *module)
@ -1859,5 +1980,3 @@ deletemathfuncs(char const *nam, MathFunc f, int size)
}
return hadf ? hads : 1;
}
#endif /* DYNAMIC */

View file

@ -203,10 +203,8 @@ IPDEF8("WATCH", &watch, "watch", 0),
IPDEF8("PATH", &path, "path", PM_RESTRICTED),
IPDEF8("PSVAR", &psvar, "psvar", 0),
#ifdef DYNAMIC
/* MODULE_PATH is not imported for security reasons */
IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED),
#endif
#define IPDEF9F(A,B,C,D) {NULL,A,D|PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT,BR((void *)B),SFN(arrvarsetfn),GFN(arrvargetfn),stdunsetfn,0,NULL,C,NULL,0}
#define IPDEF9(A,B,C) IPDEF9F(A,B,C,0)
@ -234,9 +232,7 @@ IPDEF9("manpath", &manpath, "MANPATH"),
IPDEF9("psvar", &psvar, "PSVAR"),
IPDEF9("watch", &watch, "WATCH"),
#ifdef DYNAMIC
IPDEF9F("module_path", &module_path, "MODULE_PATH", PM_RESTRICTED),
#endif
IPDEF9F("path", &path, "PATH", PM_RESTRICTED),
{NULL, NULL}
@ -254,10 +250,6 @@ static Param argvparam;
/**/
HashTable paramtab, realparamtab;
#ifndef DYNAMIC
#define getparamnode gethashnode2
#endif /* DYNAMIC */
/**/
HashTable
newparamtable(int size, char const *name)
@ -280,8 +272,6 @@ newparamtable(int size, char const *name)
return ht;
}
/**/
#ifdef DYNAMIC
/**/
static HashNode
getparamnode(HashTable ht, char *nam)
@ -302,8 +292,6 @@ getparamnode(HashTable ht, char *nam)
}
return hn;
}
/**/
#endif /* DYNAMIC */
/* Copy a parameter hash table */

View file

@ -300,6 +300,7 @@ typedef struct funcwrap *FuncWrap;
typedef struct builtin *Builtin;
typedef struct nameddir *Nameddir;
typedef struct module *Module;
typedef struct linkedmod *Linkedmod;
typedef struct patprog *Patprog;
typedef struct process *Process;
@ -917,7 +918,10 @@ struct builtin {
struct module {
char *nam;
int flags;
void *handle;
union {
void *handle;
Linkedmod linked;
} u;
LinkList deps;
int wrapper;
};
@ -925,6 +929,19 @@ struct module {
#define MOD_BUSY (1<<0)
#define MOD_UNLOAD (1<<1)
#define MOD_SETUP (1<<2)
#define MOD_LINKED (1<<3)
#define MOD_INIT_S (1<<4)
#define MOD_INIT_B (1<<5)
typedef int (*Module_func) _((Module));
struct linkedmod {
char *name;
Module_func setup;
Module_func boot;
Module_func cleanup;
Module_func finish;
};
/* C-function hooks */