gateway: simplify stopping the cleanup timer
[olsrd.git] / lib / tas / src / lua / loadlib.c
1
2 /*
3 ** $Id: loadlib.c,v 1.4 2003/04/07 20:11:53 roberto Exp $
4 ** Dynamic library loader for Lua
5 ** See Copyright Notice in lua.h
6 *
7 * This  Lua library  exports a  single function,  called loadlib,  which is
8 * called from Lua  as loadlib(lib,init), where lib is the  full name of the
9 * library to be  loaded (including the complete path) and  init is the name
10 * of a function  to be called after the library  is loaded. Typically, this
11 * function will register other functions,  thus making the complete library
12 * available  to Lua.  The init  function is  *not* automatically  called by
13 * loadlib. Instead,  loadlib returns  the init function  as a  Lua function
14 * that the client  can call when it  thinks is appropriate. In  the case of
15 * errors,  loadlib  returns  nil  and two  strings  describing  the  error.
16 * The  first string  is  supplied by  the operating  system;  it should  be
17 * informative and useful  for error messages. The second  string is "open",
18 * "init", or  "absent" to identify  the error and is  meant to be  used for
19 * making  decisions without  having to  look into  the first  string (whose
20 * format is system-dependent).
21 *
22 * This module contains  an implementation of loadlib for  Unix systems that
23 * have dlfcn, an implementation for Windows,  and a stub for other systems.
24 * See  the list  at  the end  of  this  file for  some  links to  available
25 * implementations of dlfcn  and interfaces to other  native dynamic loaders
26 * on top of which loadlib could be implemented.
27 *
28 */
29
30 #include "lua.h"
31 #include "lauxlib.h"
32 #include "lualib.h"
33
34
35 #undef LOADLIB
36
37
38 #ifdef USE_DLOPEN
39 #define LOADLIB
40
41 /*
42 * This is an implementation of loadlib based on the dlfcn interface.
43 * The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
44 * NetBSD, AIX 4.2, HPUX 11, and  probably most other Unix flavors, at least
45 * as an emulation layer on top of native functions.
46 */
47
48 #include <dlfcn.h>
49
50 static int
51 loadlib(lua_State * L)
52 {
53   const char *path = luaL_checkstring(L, 1);
54   const char *init = luaL_checkstring(L, 2);
55   void *lib = dlopen(path, RTLD_NOW);
56   if (lib != NULL) {
57     lua_CFunction f = (lua_CFunction) dlsym(lib, init);
58     if (f != NULL) {
59       lua_pushlightuserdata(L, lib);
60       lua_pushcclosure(L, f, 1);
61       return 1;
62     }
63   }
64   /* else return appropriate error messages */
65   lua_pushnil(L);
66   lua_pushstring(L, dlerror());
67   lua_pushstring(L, (lib != NULL) ? "init" : "open");
68   if (lib != NULL)
69     dlclose(lib);
70   return 3;
71 }
72
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
88
89 #if USE_DLL
90 #define LOADLIB
91
92 /*
93 * This is an implementation of loadlib for Windows using native functions.
94 */
95
96 #include <windows.h>
97
98 static void
99 pusherror(lua_State * L)
100 {
101   int error = GetLastError();
102   char buffer[128];
103   if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 0, error, 0, buffer, sizeof(buffer), 0))
104     lua_pushstring(L, buffer);
105   else
106     lua_pushfstring(L, "system error %d\n", error);
107 }
108
109 static int
110 loadlib(lua_State * L)
111 {
112   const char *path = luaL_checkstring(L, 1);
113   const char *init = luaL_checkstring(L, 2);
114   HINSTANCE lib = LoadLibrary(path);
115   if (lib != NULL) {
116     lua_CFunction f = (lua_CFunction) GetProcAddress(lib, init);
117     if (f != NULL) {
118       lua_pushlightuserdata(L, lib);
119       lua_pushcclosure(L, f, 1);
120       return 1;
121     }
122   }
123   lua_pushnil(L);
124   pusherror(L);
125   lua_pushstring(L, (lib != NULL) ? "init" : "open");
126   if (lib != NULL)
127     FreeLibrary(lib);
128   return 3;
129 }
130
131 #endif
132
133
134
135 #ifndef LOADLIB
136
137 /* Fallback for other systems */
138
139 /*
140 ** Those systems support dlopen, so they should have defined USE_DLOPEN.
141 ** The default (no)implementation gives them a special error message.
142 */
143 #ifdef __linux__
144 #define LOADLIB
145 #endif
146
147 #ifdef sun
148 #define LOADLIB
149 #endif
150
151 #ifdef sgi
152 #define LOADLIB
153 #endif
154
155 #ifdef BSD
156 #define LOADLIB
157 #endif
158
159 #ifdef _WIN32
160 #define LOADLIB
161 #endif
162
163 #ifdef LOADLIB
164 #undef LOADLIB
165 #define LOADLIB "`loadlib' not installed (check your Lua configuration)"
166 #else
167 #define LOADLIB "`loadlib' not supported"
168 #endif
169
170 static int
171 loadlib(lua_State * L)
172 {
173   lua_pushnil(L);
174   lua_pushliteral(L, LOADLIB);
175   lua_pushliteral(L, "absent");
176   return 3;
177 }
178 #endif
179
180 LUALIB_API int
181 luaopen_loadlib(lua_State * L)
182 {
183   lua_register(L, "loadlib", loadlib);
184   return 0;
185 }
186
187 /*
188 * Here are some links to available implementations of dlfcn and
189 * interfaces to other native dynamic loaders on top of which loadlib
190 * could be implemented. Please send contributions and corrections to us.
191 *
192 * AIX
193 * Starting with AIX 4.2, dlfcn is included in the base OS.
194 * There is also an emulation package available.
195 * http://www.faqs.org/faqs/aix-faq/part4/section-21.html
196 *
197 * HPUX
198 * HPUX 11 has dlfcn. For HPUX 10 use shl_*.
199 * http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html
200 * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
201 *
202 * Macintosh, Windows
203 * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
204 *
205 * Mac OS X/Darwin
206 * http://www.opendarwin.org/projects/dlcompat/
207 *
208 * GLIB has wrapper code for BeOS, OS2, Unix and Windows
209 * http://cvs.gnome.org/lxr/source/glib/gmodule/
210 *
211 */