aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-10-18 15:07:31 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-10-18 15:07:31 -0300
commit3e1a1f28362d53104a6ef09fadd902e91657f8ce (patch)
treea81941b3417bc771e0616f43e5823a68b785d966
parentb32e9a46d24f949803bcfd11d637436fb4ccb076 (diff)
downloadlua-3e1a1f28362d53104a6ef09fadd902e91657f8ce.tar.gz
lua-3e1a1f28362d53104a6ef09fadd902e91657f8ce.tar.bz2
lua-3e1a1f28362d53104a6ef09fadd902e91657f8ce.zip
better configuration for loadlib + tested Mac OS X version
-rw-r--r--loadlib.c118
1 files changed, 66 insertions, 52 deletions
diff --git a/loadlib.c b/loadlib.c
index 70e63ee4..ebfa4d51 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: loadlib.c,v 1.6 2004/04/30 20:13:38 roberto Exp roberto $ 2** $Id: loadlib.c,v 1.7 2004/10/07 17:27:20 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*
@@ -33,11 +33,10 @@
33#include "lualib.h" 33#include "lualib.h"
34 34
35 35
36#undef LOADLIB 36static void registerlib (lua_State *L, const void *lib);
37 37
38 38
39#ifdef USE_DLOPEN 39#if defined(USE_DLOPEN)
40#define LOADLIB
41/* 40/*
42* This is an implementation of loadlib based on the dlfcn interface. 41* This is an implementation of loadlib based on the dlfcn interface.
43* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, 42* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
@@ -47,6 +46,8 @@
47 46
48#include <dlfcn.h> 47#include <dlfcn.h>
49 48
49#define freelib dlclose
50
50static int loadlib(lua_State *L) 51static int loadlib(lua_State *L)
51{ 52{
52 const char *path=luaL_checkstring(L,1); 53 const char *path=luaL_checkstring(L,1);
@@ -57,8 +58,8 @@ static int loadlib(lua_State *L)
57 lua_CFunction f=(lua_CFunction) dlsym(lib,init); 58 lua_CFunction f=(lua_CFunction) dlsym(lib,init);
58 if (f!=NULL) 59 if (f!=NULL)
59 { 60 {
60 lua_pushlightuserdata(L,lib); 61 registerlib(L, lib);
61 lua_pushcclosure(L,f,1); 62 lua_pushcfunction(L,f);
62 return 1; 63 return 1;
63 } 64 }
64 } 65 }
@@ -70,30 +71,17 @@ static int loadlib(lua_State *L)
70 return 3; 71 return 3;
71} 72}
72 73
73#endif
74
75
76
77/*
78** In Windows, default is to use dll; otherwise, default is not to use dll
79*/
80#ifndef USE_DLL
81#ifdef _WIN32
82#define USE_DLL 1
83#else
84#define USE_DLL 0
85#endif
86#endif
87 74
88 75
89#if USE_DLL 76#elif defined(USE_DLL)
90#define LOADLIB
91/* 77/*
92* This is an implementation of loadlib for Windows using native functions. 78* This is an implementation of loadlib for Windows using native functions.
93*/ 79*/
94 80
95#include <windows.h> 81#include <windows.h>
96 82
83#define freelib(lib) FreeLibrary((HINSTANCE)lib)
84
97static void pusherror(lua_State *L) 85static void pusherror(lua_State *L)
98{ 86{
99 int error=GetLastError(); 87 int error=GetLastError();
@@ -115,8 +103,8 @@ static int loadlib(lua_State *L)
115 lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init); 103 lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init);
116 if (f!=NULL) 104 if (f!=NULL)
117 { 105 {
118 lua_pushlightuserdata(L,lib); 106 registerlib(L, lib);
119 lua_pushcclosure(L,f,1); 107 lua_pushcfunction(L,f);
120 return 1; 108 return 1;
121 } 109 }
122 } 110 }
@@ -127,19 +115,28 @@ static int loadlib(lua_State *L)
127 return 3; 115 return 3;
128} 116}
129 117
130#endif 118
131 119
132/* Native Mac OS X / Darwin Implementation */ 120/* Native Mac OS X / Darwin Implementation */
133#ifdef USE_DYLD 121#elif defined(USE_DYLD)
134#define LOADLIB
135 122
136#include <mach-o/dyld.h> 123#include <mach-o/dyld.h>
137 124
125
126/* Mach cannot unload images (?) */
127#define freelib(lib) ((void)lib)
128
129static void pusherror (lua_State *L)
130{
131 const char *err_str;
132 const char *err_file;
133 NSLinkEditErrors err;
134 int err_num;
135 NSLinkEditError(&err, &err_num, &err_file, &err_str);
136 lua_pushstring(L, err_str);
137}
138
138static int loadlib (lua_State *L) { 139static 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); 140 const char *path=luaL_checkstring(L,1);
144 const char *init=luaL_checkstring(L,2); 141 const char *init=luaL_checkstring(L,2);
145 const struct mach_header *lib; 142 const struct mach_header *lib;
@@ -150,7 +147,6 @@ static int loadlib (lua_State *L) {
150 lua_pushstring(L,"absent"); 147 lua_pushstring(L,"absent");
151 return 3; 148 return 3;
152 } 149 }
153
154 lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); 150 lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
155 if(lib != NULL) { 151 if(lib != NULL) {
156 NSSymbol init_sym = NSLookupSymbolInImage(lib, init, 152 NSSymbol init_sym = NSLookupSymbolInImage(lib, init,
@@ -158,49 +154,70 @@ static int loadlib (lua_State *L) {
158 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); 154 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
159 if(init_sym != NULL) { 155 if(init_sym != NULL) {
160 lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); 156 lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym);
161 lua_pushlightuserdata(L,(void *)lib); 157 registerlib(L, lib);
162 lua_pushcclosure(L,f,1); 158 lua_pushcfunction(L,f);
163 return 1; 159 return 1;
164 } 160 }
165 } 161 }
166 /* else an error ocurred */ 162 /* else an error ocurred */
167 NSLinkEditError(&err, &err_num, &err_file, &err_str);
168 lua_pushnil(L); 163 lua_pushnil(L);
169 lua_pushstring(L, err_str); 164 pusherror(L);
170 lua_pushstring(L, (lib != NULL) ? "init" : "open"); 165 lua_pushstring(L, (lib != NULL) ? "init" : "open");
171 /* Can't unload image */ 166 /* Can't unload image */
172 return 3; 167 return 3;
173} 168}
174 169
175#endif
176
177 170
178 171
179#ifndef LOADLIB 172#else
180/* Fallback for other systems */ 173/* Fallback for other systems */
181 174
182/*
183** Those systems support dlopen, so they should have defined USE_DLOPEN.
184** The default (no)implementation gives them a special error message.
185*/
186#if defined(linux) || defined(sun) || defined(sgi) || defined(BSD) || defined(_WIN32)
187#define LOADLIB "`loadlib' not installed (check your Lua configuration)"
188#else
189#define LOADLIB "`loadlib' not supported"
190#endif
191 175
176#define freelib(lib) ((void)lib)
192 177
193static int loadlib(lua_State *L) 178static int loadlib(lua_State *L)
194{ 179{
180 registerlib(L, NULL); /* to avoid warnings */
195 lua_pushnil(L); 181 lua_pushnil(L);
196 lua_pushliteral(L,LOADLIB); 182 lua_pushliteral(L,"`loadlib' not supported");
197 lua_pushliteral(L,"absent"); 183 lua_pushliteral(L,"absent");
198 return 3; 184 return 3;
199} 185}
186
200#endif 187#endif
201 188
189
190/*
191** common code for all implementations: put a library into the registry
192** so that, when Lua closes its state, the library's __gc metamethod
193** will be called to unload the library.
194*/
195static void registerlib (lua_State *L, const void *lib)
196{
197 const void **plib = (const void **)lua_newuserdata(L, sizeof(const void *));
198 *plib = lib;
199 luaL_getmetatable(L, "_LOADLIB");
200 lua_setmetatable(L, -2);
201 lua_pushboolean(L, 1);
202 lua_settable(L, LUA_REGISTRYINDEX); /* registry[lib] = true */
203}
204
205/*
206** __gc tag method: calls library's `freelib' function with the lib
207** handle
208*/
209static int gctm (lua_State *L)
210{
211 void *lib = *(void **)luaL_checkudata(L, 1, "_LOADLIB");
212 freelib(lib);
213 return 0;
214}
215
202LUALIB_API int luaopen_loadlib (lua_State *L) 216LUALIB_API int luaopen_loadlib (lua_State *L)
203{ 217{
218 luaL_newmetatable(L, "_LOADLIB");
219 lua_pushcfunction(L, gctm);
220 lua_setfield(L, -2, "__gc");
204 lua_register(L,"loadlib",loadlib); 221 lua_register(L,"loadlib",loadlib);
205 return 0; 222 return 0;
206} 223}
@@ -223,9 +240,6 @@ LUALIB_API int luaopen_loadlib (lua_State *L)
223* Macintosh, Windows 240* Macintosh, Windows
224* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html 241* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
225* 242*
226* Mac OS X/Darwin
227* http://www.opendarwin.org/projects/dlcompat/
228*
229* GLIB has wrapper code for BeOS, OS2, Unix and Windows 243* GLIB has wrapper code for BeOS, OS2, Unix and Windows
230* http://cvs.gnome.org/lxr/source/glib/gmodule/ 244* http://cvs.gnome.org/lxr/source/glib/gmodule/
231* 245*