- initial import of revision 374 from cnc
[apt.git] / lua / lib / loadlib.c
1 /*
2 ** $Id: loadlib.c,v 1.4 2003/04/07 20:11:53 roberto Exp $
3 ** 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 module contains  an implementation of loadlib for  Unix systems that
22 * have dlfcn, an implementation for Windows,  and a stub for other systems.
23 * See  the list  at  the end  of  this  file for  some  links to  available
24 * implementations of dlfcn  and interfaces to other  native dynamic loaders
25 * on top of which loadlib could be implemented.
26 *
27 */
28
29 #include "lua.h"
30 #include "lauxlib.h"
31 #include "lualib.h"
32
33
34 #undef LOADLIB
35
36
37 #ifdef USE_DLOPEN
38 #define LOADLIB
39 /*
40 * This is an implementation of loadlib based on the dlfcn interface.
41 * The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
42 * NetBSD, AIX 4.2, HPUX 11, and  probably most other Unix flavors, at least
43 * as an emulation layer on top of native functions.
44 */
45
46 #include <dlfcn.h>
47
48 static int loadlib(lua_State *L)
49 {
50  const char *path=luaL_checkstring(L,1);
51  const char *init=luaL_checkstring(L,2);
52  void *lib=dlopen(path,RTLD_NOW);
53  if (lib!=NULL)
54  {
55   lua_CFunction f=(lua_CFunction) dlsym(lib,init);
56   if (f!=NULL)
57   {
58    lua_pushlightuserdata(L,lib);
59    lua_pushcclosure(L,f,1);
60    return 1;
61   }
62  }
63  /* else return appropriate error messages */
64  lua_pushnil(L);
65  lua_pushstring(L,dlerror());
66  lua_pushstring(L,(lib!=NULL) ? "init" : "open");
67  if (lib!=NULL) dlclose(lib);
68  return 3;
69 }
70
71 #endif
72
73
74
75 /*
76 ** In Windows, default is to use dll; otherwise, default is not to use dll
77 */
78 #ifndef USE_DLL
79 #ifdef _WIN32
80 #define USE_DLL 1
81 #else
82 #define USE_DLL 0
83 #endif
84 #endif
85
86
87 #if USE_DLL
88 #define LOADLIB
89 /*
90 * This is an implementation of loadlib for Windows using native functions.
91 */
92
93 #include <windows.h>
94
95 static void pusherror(lua_State *L)
96 {
97  int error=GetLastError();
98  char buffer[128];
99  if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
100         0, error, 0, buffer, sizeof(buffer), 0))
101   lua_pushstring(L,buffer);
102  else
103   lua_pushfstring(L,"system error %d\n",error);
104 }
105
106 static int loadlib(lua_State *L)
107 {
108  const char *path=luaL_checkstring(L,1);
109  const char *init=luaL_checkstring(L,2);
110  HINSTANCE lib=LoadLibrary(path);
111  if (lib!=NULL)
112  {
113   lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init);
114   if (f!=NULL)
115   {
116    lua_pushlightuserdata(L,lib);
117    lua_pushcclosure(L,f,1);
118    return 1;
119   }
120  }
121  lua_pushnil(L);
122  pusherror(L);
123  lua_pushstring(L,(lib!=NULL) ? "init" : "open");
124  if (lib!=NULL) FreeLibrary(lib);
125  return 3;
126 }
127
128 #endif
129
130
131
132 #ifndef LOADLIB
133 /* Fallback for other systems */
134
135 /*
136 ** Those systems support dlopen, so they should have defined USE_DLOPEN.
137 ** The default (no)implementation gives them a special error message.
138 */
139 #ifdef linux
140 #define LOADLIB
141 #endif
142
143 #ifdef sun
144 #define LOADLIB
145 #endif
146
147 #ifdef sgi
148 #define LOADLIB
149 #endif
150
151 #ifdef BSD
152 #define LOADLIB
153 #endif
154
155 #ifdef _WIN32
156 #define LOADLIB
157 #endif
158
159 #ifdef LOADLIB
160 #undef LOADLIB
161 #define LOADLIB "`loadlib' not installed (check your Lua configuration)"
162 #else
163 #define LOADLIB "`loadlib' not supported"
164 #endif
165
166 static int loadlib(lua_State *L)
167 {
168  lua_pushnil(L);
169  lua_pushliteral(L,LOADLIB);
170  lua_pushliteral(L,"absent");
171  return 3;
172 }
173 #endif
174
175 LUALIB_API int luaopen_loadlib (lua_State *L)
176 {
177  lua_register(L,"loadlib",loadlib);
178  return 0;
179 }
180
181 /*
182 * Here are some links to available implementations of dlfcn and
183 * interfaces to other native dynamic loaders on top of which loadlib
184 * could be implemented. Please send contributions and corrections to us.
185 *
186 * AIX
187 * Starting with AIX 4.2, dlfcn is included in the base OS.
188 * There is also an emulation package available.
189 * http://www.faqs.org/faqs/aix-faq/part4/section-21.html
190 *
191 * HPUX 
192 * HPUX 11 has dlfcn. For HPUX 10 use shl_*.
193 * http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html
194 * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
195 *
196 * Macintosh, Windows
197 * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
198 *
199 * Mac OS X/Darwin
200 * http://www.opendarwin.org/projects/dlcompat/
201 *
202 * GLIB has wrapper code for BeOS, OS2, Unix and Windows
203 * http://cvs.gnome.org/lxr/source/glib/gmodule/
204 *
205 */