diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-03-17 10:04:58 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-03-17 10:04:58 -0300 |
commit | b0c40e240585b67902bece4569ee683296e475f4 (patch) | |
tree | d7af01079027eefcfe885d6e285afc1c8947b560 | |
parent | 4734e2de0524cc1896fb8605b9c81c195383eb25 (diff) | |
download | lua-b0c40e240585b67902bece4569ee683296e475f4.tar.gz lua-b0c40e240585b67902bece4569ee683296e475f4.tar.bz2 lua-b0c40e240585b67902bece4569ee683296e475f4.zip |
first version of `loadlib'
-rw-r--r-- | loadlib.c | 173 | ||||
-rw-r--r-- | lualib.h | 5 |
2 files changed, 177 insertions, 1 deletions
diff --git a/loadlib.c b/loadlib.c new file mode 100644 index 00000000..69b1339e --- /dev/null +++ b/loadlib.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | ** $Id$ | ||
3 | ** Bare-bones dynamic library loader for Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | * | ||
6 | * This Lua library exports a single function, called loadlib, which is | ||
7 | * called from Lua as loadlib(lib,init), where lib is the full name of the | ||
8 | * library to be loaded (including the complete path) and init is the name | ||
9 | * of a function to be called after the library is loaded. Typically, this | ||
10 | * function will register other functions, thus making the complete library | ||
11 | * available to Lua. The init function is *not* automatically called by | ||
12 | * loadlib. Instead, loadlib returns the init function as a Lua function | ||
13 | * that the client can call when it thinks is appropriate. In the case of | ||
14 | * errors, loadlib returns nil and two strings describing the error. | ||
15 | * The first string is supplied by the operating system; it should be | ||
16 | * informative and useful for error messages. The second string is "open", | ||
17 | * "init", or "absent" to identify the error and is meant to be used for | ||
18 | * making decisions without having to look into the first string (whose | ||
19 | * format is system-dependent). | ||
20 | * | ||
21 | * This bare-bones loadlib function is supposed to be used as a foundation | ||
22 | * for more sophisticated dynamic library loaders, possibly still called | ||
23 | * loadlib and probably written in Lua, that will be smart enough to try to | ||
24 | * find the library in different directories and also perhaps guess the name | ||
25 | * of the init function. | ||
26 | * | ||
27 | * This module contains an implementation of loadlib for Unix systems that | ||
28 | * have dlfcn, an implementation for Windows, and a stub for other systems. | ||
29 | * See the list at the end of this file for some links to available | ||
30 | * implementations of dlfcn and interfaces to other native dynamic loaders | ||
31 | * on top of which loadlib could be implemented. | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | #include "lua.h" | ||
36 | #include "lauxlib.h" | ||
37 | #include "lualib.h" | ||
38 | |||
39 | #ifndef USE_LOADLIB | ||
40 | #define USE_LOADLIB 1 | ||
41 | #endif | ||
42 | |||
43 | #ifndef USE_DLOPEN | ||
44 | #define USE_DLOPEN 0 | ||
45 | #endif | ||
46 | |||
47 | #if USE_LOADLIB | ||
48 | |||
49 | #if defined(linux) || defined(sun) || defined(sgi) || defined(BSD) || USE_DLOPEN | ||
50 | #define LOADLIB | ||
51 | /* | ||
52 | * This is an implementation of loadlib based on the dlfcn interface. | ||
53 | * The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, | ||
54 | * NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least | ||
55 | * as an emulation layer on top of native functions. | ||
56 | */ | ||
57 | |||
58 | #include <dlfcn.h> | ||
59 | |||
60 | static int loadlib(lua_State *L) | ||
61 | { | ||
62 | const char *path=luaL_checkstring(L,1); | ||
63 | const char *init=luaL_checkstring(L,2); | ||
64 | void *lib=dlopen(path,RTLD_NOW); | ||
65 | if (lib!=NULL) | ||
66 | { | ||
67 | lua_CFunction f=(lua_CFunction) dlsym(lib,init); | ||
68 | if (f!=NULL) | ||
69 | { | ||
70 | lua_pushlightuserdata(L,lib); | ||
71 | lua_pushcclosure(L,f,1); | ||
72 | return 1; | ||
73 | } | ||
74 | } | ||
75 | lua_pushnil(L); | ||
76 | lua_pushstring(L,dlerror()); | ||
77 | lua_pushstring(L,(lib!=NULL) ? "init" : "open"); | ||
78 | if (lib!=NULL) dlclose(lib); | ||
79 | return 3; | ||
80 | } | ||
81 | |||
82 | #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) | ||
83 | #define LOADLIB | ||
84 | /* | ||
85 | * This is an implementation of loadlib for Windows using native functions. | ||
86 | */ | ||
87 | |||
88 | #include <windows.h> | ||
89 | |||
90 | static void pusherror(lua_State *L) | ||
91 | { | ||
92 | int error=GetLastError(); | ||
93 | char buffer[128]; | ||
94 | if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, | ||
95 | 0, error, 0, buffer, sizeof(buffer), 0)) | ||
96 | lua_pushstring(L,buffer); | ||
97 | else | ||
98 | lua_pushfstring("system error %d\n",error); | ||
99 | } | ||
100 | |||
101 | static int loadlib(lua_State *L) | ||
102 | { | ||
103 | const char *path=luaL_checkstring(L,1); | ||
104 | const char *init=luaL_checkstring(L,2); | ||
105 | HINSTANCE lib=LoadLibrary(path); | ||
106 | if (lib!=NULL) | ||
107 | { | ||
108 | lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init); | ||
109 | if (f!=NULL) | ||
110 | { | ||
111 | lua_pushlightuserdata(L,lib); | ||
112 | lua_pushcclosure(L,f,1); | ||
113 | return 1; | ||
114 | } | ||
115 | } | ||
116 | lua_pushnil(L); | ||
117 | pusherror(L); | ||
118 | lua_pushstring(L,(lib!=NULL) ? "init" : "open"); | ||
119 | if (lib!=NULL) FreeLibrary(lib); | ||
120 | return 3; | ||
121 | } | ||
122 | |||
123 | #else | ||
124 | /* | ||
125 | * write an implementation for your system here and send it to us, together | ||
126 | * with preprocessing symbols that identify your system. | ||
127 | */ | ||
128 | #endif | ||
129 | #endif | ||
130 | |||
131 | #ifndef LOADLIB | ||
132 | /* Fallback for other systems */ | ||
133 | |||
134 | static int loadlib(lua_State *L) | ||
135 | { | ||
136 | lua_pushnil(L); | ||
137 | lua_pushliteral(L,"`loadlib' not supported"); | ||
138 | lua_pushliteral(L,"absent"); | ||
139 | return 3; | ||
140 | } | ||
141 | #endif | ||
142 | |||
143 | LUALIB_API int luaopen_loadlib (lua_State *L) | ||
144 | { | ||
145 | lua_register(L,"loadlib",loadlib); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Here are some links por to available implementations of dlfcn and | ||
151 | * interfaces to other native dynamic loaders on top of which loadlib could | ||
152 | * be implemented. Please send contributions and corrections to us. | ||
153 | * | ||
154 | * AIX | ||
155 | * Starting with AIX 4.2, dlfcn is included in the base OS. | ||
156 | * There is also an emulation package available. | ||
157 | * http://www.faqs.org/faqs/aix-faq/part4/section-21.html | ||
158 | * | ||
159 | * HPUX | ||
160 | * HPUX 11 has dlfcn. For HPUX 10 use shl_*. | ||
161 | * http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html | ||
162 | * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html | ||
163 | * | ||
164 | * Macintosh, Windows | ||
165 | * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html | ||
166 | * | ||
167 | * Mac OS X/Darwin | ||
168 | * http://www.opendarwin.org/projects/dlcompat/ | ||
169 | * | ||
170 | * GLIB has wrapper code for BeOS, OS2, Unix and Windows | ||
171 | * http://cvs.gnome.org/lxr/source/glib/gmodule/ | ||
172 | * | ||
173 | */ | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lualib.h,v 1.25 2002/07/09 18:49:13 roberto Exp roberto $ | 2 | ** $Id: lualib.h,v 1.26 2003/03/11 12:24:34 roberto Exp roberto $ |
3 | ** Lua standard libraries | 3 | ** Lua standard libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -36,6 +36,9 @@ LUALIB_API int luaopen_math (lua_State *L); | |||
36 | LUALIB_API int luaopen_debug (lua_State *L); | 36 | LUALIB_API int luaopen_debug (lua_State *L); |
37 | 37 | ||
38 | 38 | ||
39 | LUALIB_API int luaopen_loadlib (lua_State *L); | ||
40 | |||
41 | |||
39 | /* to help testing the libraries */ | 42 | /* to help testing the libraries */ |
40 | #ifndef lua_assert | 43 | #ifndef lua_assert |
41 | #define lua_assert(c) /* empty */ | 44 | #define lua_assert(c) /* empty */ |