diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-07 14:27:20 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-07 14:27:20 -0300 |
| commit | 3bec76abe350ef610996b850a1b9c9bbdd46ee6b (patch) | |
| tree | 8327be802e309b7e866ab8c2bef1f84a9a4bbfd7 | |
| parent | 5cb6037d49cbbde936505a705e37d4962c91b28a (diff) | |
| download | lua-3bec76abe350ef610996b850a1b9c9bbdd46ee6b.tar.gz lua-3bec76abe350ef610996b850a1b9c9bbdd46ee6b.tar.bz2 lua-3bec76abe350ef610996b850a1b9c9bbdd46ee6b.zip | |
first version of loadlib for Mac OS X (not tested yet!!)
| -rw-r--r-- | loadlib.c | 88 |
1 files changed, 66 insertions, 22 deletions
| @@ -1,29 +1,28 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.5 2003/05/14 21:01:53 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.6 2004/04/30 20:13:38 roberto Exp roberto $ |
| 3 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | * | 5 | * |
| 6 | * This Lua library exports a single function, called loadlib, which is | 6 | * This Lua library exports a single function, called loadlib, which |
| 7 | * called from Lua as loadlib(lib,init), where lib is the full name of the | 7 | * is called from Lua as loadlib(lib,init), where lib is the full |
| 8 | * library to be loaded (including the complete path) and init is the name | 8 | * name of the library to be loaded (including the complete path) and |
| 9 | * of a function to be called after the library is loaded. Typically, this | 9 | * init is the name of a function to be called after the library is |
| 10 | * function will register other functions, thus making the complete library | 10 | * loaded. Typically, this function will register other functions, thus |
| 11 | * available to Lua. The init function is *not* automatically called by | 11 | * making the complete library available to Lua. The init function is |
| 12 | * loadlib. Instead, loadlib returns the init function as a Lua function | 12 | * *not* automatically called by loadlib. Instead, loadlib returns the |
| 13 | * that the client can call when it thinks is appropriate. In the case of | 13 | * init function as a Lua function that the client can call when it |
| 14 | * errors, loadlib returns nil and two strings describing the error. | 14 | * thinks is appropriate. In the case of errors, loadlib returns nil and |
| 15 | * The first string is supplied by the operating system; it should be | 15 | * two strings describing the error. The first string is supplied by |
| 16 | * informative and useful for error messages. The second string is "open", | 16 | * the operating system; it should be informative and useful for error |
| 17 | * "init", or "absent" to identify the error and is meant to be used for | 17 | * messages. The second string is "open", "init", or "absent" to identify |
| 18 | * making decisions without having to look into the first string (whose | 18 | * the error and is meant to be used for making decisions without having |
| 19 | * format is system-dependent). | 19 | * to look into the first string (whose format is system-dependent). |
| 20 | * | 20 | * This module contains an implementation of loadlib for Unix systems |
| 21 | * This module contains an implementation of loadlib for Unix systems that | 21 | * that have dlfcn, an implementation for Darwin (Mac OS X), an |
| 22 | * have dlfcn, an implementation for Windows, and a stub for other systems. | 22 | * implementation for Windows, and a stub for other systems. See |
| 23 | * See the list at the end of this file for some links to available | 23 | * the list at the end of this file for some links to available |
| 24 | * implementations of dlfcn and interfaces to other native dynamic loaders | 24 | * implementations of dlfcn and interfaces to other native dynamic |
| 25 | * on top of which loadlib could be implemented. | 25 | * loaders on top of which loadlib could be implemented. |
| 26 | * | ||
| 27 | */ | 26 | */ |
| 28 | 27 | ||
| 29 | #define loadlib_c | 28 | #define loadlib_c |
| @@ -130,6 +129,51 @@ static int loadlib(lua_State *L) | |||
| 130 | 129 | ||
| 131 | #endif | 130 | #endif |
| 132 | 131 | ||
| 132 | /* Native Mac OS X / Darwin Implementation */ | ||
| 133 | #ifdef USE_DYLD | ||
| 134 | #define LOADLIB | ||
| 135 | |||
| 136 | #include <mach-o/dyld.h> | ||
| 137 | |||
| 138 | static int loadlib (lua_State *L) { | ||
| 139 | const char * err_str; | ||
| 140 | const char * err_file; | ||
| 141 | NSLinkEditErrors err; | ||
| 142 | int err_num; | ||
| 143 | const char *path=luaL_checkstring(L,1); | ||
| 144 | const char *init=luaL_checkstring(L,2); | ||
| 145 | const struct mach_header *lib; | ||
| 146 | /* this would be a rare case, but prevents crashing if it happens */ | ||
| 147 | if(!_dyld_present()) { | ||
| 148 | lua_pushnil(L); | ||
| 149 | lua_pushstring(L,"dyld not present."); | ||
| 150 | lua_pushstring(L,"absent"); | ||
| 151 | return 3; | ||
| 152 | } | ||
| 153 | |||
| 154 | lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); | ||
| 155 | if(lib != NULL) { | ||
| 156 | NSSymbol init_sym = NSLookupSymbolInImage(lib, init, | ||
| 157 | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | | ||
| 158 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | ||
| 159 | if(init_sym != NULL) { | ||
| 160 | lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); | ||
| 161 | lua_pushlightuserdata(L,(void *)lib); | ||
| 162 | lua_pushcclosure(L,f,1); | ||
| 163 | return 1; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | /* else an error ocurred */ | ||
| 167 | NSLinkEditError(&err, &err_num, &err_file, &err_str); | ||
| 168 | lua_pushnil(L); | ||
| 169 | lua_pushstring(L, err_str); | ||
| 170 | lua_pushstring(L, (lib != NULL) ? "init" : "open"); | ||
| 171 | /* Can't unload image */ | ||
| 172 | return 3; | ||
| 173 | } | ||
| 174 | |||
| 175 | #endif | ||
| 176 | |||
| 133 | 177 | ||
| 134 | 178 | ||
| 135 | #ifndef LOADLIB | 179 | #ifndef LOADLIB |
