From 367b87d26db90015bdee12e3efea49f9d0c0a7ea Mon Sep 17 00:00:00 2001 From: Paul Querna Date: Tue, 13 Jul 2010 01:33:51 -0700 Subject: [PATCH] Add support for the module structure to process.dlopen. --- src/node.cc | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/node.cc b/src/node.cc index 04534de3bd..6b697d3f3e 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1357,19 +1357,55 @@ Handle DLOpen(const v8::Arguments& args) { return ThrowException(exception); } + String::Utf8Value symbol(args[0]->ToString()); + char *symstr = NULL; + { + char *sym = *symbol; + char *p = strrchr(sym, '/'); + if (p != NULL) { + sym = p+1; + } + + p = strrchr(sym, '.'); + if (p != NULL) { + *p = NULL; + } + + size_t slen = strlen(sym); + symstr = static_cast(calloc(1, slen + sizeof("_module") + 1)); + memcpy(symstr, sym, slen); + memcpy(symstr+slen, "_module", sizeof("_module") + 1); + } + // Get the init() function from the dynamically shared object. - void *init_handle = dlsym(handle, "init"); + node_module_struct *mod = static_cast(dlsym(handle, symstr)); + free(symstr); // Error out if not found. - if (init_handle == NULL) { - dlclose(handle); + if (mod == NULL) { + /* Start Compatibility hack: Remove once everyone is using NODE_MODULE macro */ + node_module_struct compat_mod; + mod = &compat_mod; + mod->version = NODE_MODULE_VERSION; + + void *init_handle = dlsym(handle, "init"); + if (init_handle == NULL) { + dlclose(handle); + Local exception = + Exception::Error(String::New("No module symbol found in module.")); + return ThrowException(exception); + } + mod->register_func = (extInit)(init_handle); + /* End Compatibility hack */ + } + + if (mod->version != NODE_MODULE_VERSION) { Local exception = - Exception::Error(String::New("No 'init' symbol found in module.")); + Exception::Error(String::New("Module version mismatch, refusing to load.")); return ThrowException(exception); } - extInit init = (extInit)(init_handle); // Cast // Execute the C++ module - init(target); + mod->register_func(target); // Tell coverity that 'handle' should not be freed when we return. // coverity[leaked_storage]