diff options
author | Peter Drahoš <drahosp@gmail.com> | 2010-12-14 15:45:15 +0100 |
---|---|---|
committer | Peter Drahoš <drahosp@gmail.com> | 2010-12-14 15:45:15 +0100 |
commit | 8c966e95c726a4620c9ea483d424c454ca759c76 (patch) | |
tree | bbe846cbf85dfbceee8af4ff08f698f061a2850c | |
parent | 00d544daf5be733cd3fecb9fe65d8723c92d704d (diff) | |
download | lua-8c966e95c726a4620c9ea483d424c454ca759c76.tar.gz |
Finalized relative module loading.
-rw-r--r-- | src/loadlib.c | 115 | ||||
-rw-r--r-- | src/luaconf.h | 51 |
2 files changed, 87 insertions, 79 deletions
diff --git a/src/loadlib.c b/src/loadlib.c index 5add868..60b7aa2 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -39,77 +39,88 @@ #define ERRLIB 1 #define ERRFUNC 2 -#define setprogdir(L) ((void)0) - - static void ll_unloadlib (void *lib); static void *ll_load (lua_State *L, const char *path); static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); +static void setprogdir (lua_State *L); - - -#if defined(LUA_DL_DLOPEN) /* -** {======================================================================== -** This is an implementation of loadlib based on the dlfcn interface. -** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, -** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least -** as an emulation layer on top of native functions. -** ========================================================================= +** {========================================================================= +** This determines the location of the executable for relative module loading +** ========================================================================== */ - -#include <dlfcn.h> -#include <sys/stat.h> - -#undef setprogdir +#if defined(_WIN32) || defined(__CYGWIN__) + #include <windows.h> + #define PATH_MAX MAX_PATH +#endif static void setprogdir (lua_State *L) { - char buff[PATH_MAX + 1]; + char progdir[PATH_MAX + 1]; char *lb; - int nsize; - -#if defined(__linux__) - nsize = readlink("/proc/self/exe", buff, PATH_MAX - 1); - if (nsize > 0) buff[nsize] = 0; + int nsize = sizeof(progdir)/sizeof(char); + int n; +#if defined(_WIN32) + n = GetModuleFileNameA(NULL, progdir, nsize); +#elif defined(__CYGWIN__) + char win_buff[PATH_MAX + 1]; + GetModuleFileNameA(NULL, win_buff, nsize); + cygwin_conv_to_posix_path(win_buff, progdir); + n = strlen(progdir); +#elif defined(__linux__) + n = readlink("/proc/self/exe", progdir, nsize); + if (n > 0) progdir[n] = 0; #elif defined(__FreeBSD__) - int len; - len = readlink("/proc/curproc/file", buff, PATH_MAX - 1); - if (nsize > 0) buff[nsize] = 0; + n = readlink("/proc/curproc/file", progdir, nsize); + if (n > 0) progdir[n] = 0; #else - // Rely on 'lsof' ... sadly this is the best we can do as fallback for most UNIX systems (OSX too) - // lsof will list open files, this includes the executable listed as 1st file + // FALLBACK + // Use 'lsof' ... should work on most UNIX systems (incl. OSX) + // lsof will list open files, this captures the 1st file listed (usually the executable) int pid; FILE* fd; char cmd[80]; pid = getpid(); - // Get first open file, lsof marks files as REG - sprintf(cmd, "lsof -p %d | awk '{if ($5==\"REG\") { print $9 ; exit}}'", pid); + sprintf(cmd, "lsof -p %d | awk '{if ($5==\"REG\") { print $9 ; exit}}' 2> /dev/null", pid); fd = popen(cmd, "r"); - nsize = fread(buff, 1, PATH_MAX - 1, fd); + n = fread(progdir, 1, nsize, fd); // remove newline - if (nsize > 1) buff[nsize - 1] = '\0'; + if (n > 1) progdir[--n] = '\0'; #endif - - if (nsize == 0 || (lb = strrchr(buff, '/')) == NULL) + if (n == 0 || n == nsize || (lb = strrchr(progdir, (int)LUA_DIRSEP[0])) == NULL) luaL_error(L, "unable to get process executable path"); else { *lb = '\0'; - // Add _PATH global - lua_pushstring(L, buff); - lua_setglobal(L, "_PATH"); - - luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); - lua_remove(L, -2); /* remove original string */ + // Set progdir global + lua_pushstring(L, progdir); + lua_setglobal(L, "_PROGDIR"); + + // Replace the relative path placeholder + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, progdir); + lua_remove(L, -2); } } +/* }====================================================== */ + +#if defined(LUA_DL_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include <dlfcn.h> +#include <sys/stat.h> + static void ll_unloadlib (void *lib) { dlclose(lib); } - static void *ll_load (lua_State *L, const char *path) { void *lib = dlopen(path, RTLD_NOW); if (lib == NULL) lua_pushstring(L, dlerror()); @@ -136,28 +147,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { #include <windows.h> - -#undef setprogdir - -static void setprogdir (lua_State *L) { - char buff[MAX_PATH + 1]; - char *lb; - DWORD nsize = sizeof(buff)/sizeof(char); - DWORD n = GetModuleFileNameA(NULL, buff, nsize); - if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) - luaL_error(L, "unable to get ModuleFileName"); - else { - *lb = '\0'; - // Add _PATH global - lua_pushstring(L, buff); - lua_setglobal(L, "_PATH"); - - luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); - lua_remove(L, -2); /* remove original string */ - } -} - - static void pusherror (lua_State *L) { int error = GetLastError(); char buffer[128]; diff --git a/src/luaconf.h b/src/luaconf.h index cfe746d..d913b1b 100644 --- a/src/luaconf.h +++ b/src/luaconf.h @@ -79,26 +79,43 @@ ** CHANGE them if your machine has a non-conventional directory ** hierarchy or if you want to install your libraries in ** non-conventional directories. -*/ -#if defined(_WIN32) -/* -** In Windows, any exclamation mark ('!') in the path is replaced by the +** Any exclamation mark ('!') in the path is replaced by the ** path of the directory of the executable file of the current process. */ +#if defined(_WIN32) #define LUADIST_LDIR "!\\..\\share\\lua\\lmod\\" #define LUADIST_CDIR "!\\..\\share\\lua\\cmod\\" #define LUA_LDIR "!\\lua\\" #define LUA_CDIR "!\\" -#define LUA_PATH_DEFAULT \ - ".\\?.lua;" LUADIST_LDIR"?.lua;" LUADIST_LDIR"?\\init.lua;" \ - LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" -#define LUA_CPATH_DEFAULT \ - ".\\?.dll;" LUADIST_CDIR"?.dll;" LUADIST_CDIR"loadall.dll;" \ - LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" +#define LUA_PATH_DEFAULT ".\\?.lua;" \ + LUADIST_LDIR"?.lua;" LUADIST_LDIR"?\\init.lua;" \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" + +#define LUA_CPATH_DEFAULT ".\\?.dll;" \ + LUADIST_CDIR"?.dll;" LUADIST_CDIR"loadall.dll;" \ + LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#elif defined(__CYGWIN__) + +#define LUADIST_LDIR "!/../share/lua/lmod/" +#define LUADIST_CDIR "!/../share/lua/cmod/" + +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" + +#define LUA_PATH_DEFAULT "./?.lua;" \ + LUADIST_LDIR"?.lua;" LUADIST_LDIR"?/init.lua;" \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" + +#define LUA_CPATH_DEFAULT "./?.dll;" \ + LUADIST_CDIR"?.dll;" LUADIST_CDIR"loadall.dll;" \ + LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" #else #define LUADIST_LDIR "!/../share/lua/lmod/" @@ -107,13 +124,15 @@ #define LUA_ROOT "/usr/local/" #define LUA_LDIR LUA_ROOT "share/lua/5.1/" #define LUA_CDIR LUA_ROOT "lib/lua/5.1/" -#define LUA_PATH_DEFAULT \ - "./?.lua;" LUADIST_LDIR"?.lua;" LUADIST_LDIR"?/init.lua;" \ + +#define LUA_PATH_DEFAULT "./?.lua;" \ + LUADIST_LDIR"?.lua;" LUADIST_LDIR"?/init.lua;" \ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" -#define LUA_CPATH_DEFAULT \ - "./?.so;" LUADIST_CDIR"?.so;" LUADIST_CDIR"loadall.so;" \ - LUA_CDIR"?.so;" LUA_CDIR"loadall.so" + +#define LUA_CPATH_DEFAULT "./?.so;" \ + LUADIST_CDIR"?.so;" LUADIST_CDIR"loadall.so;" \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so" #endif |