loadlib.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. /*
  2. ** $Id: loadlib.c,v 1.120 2014/11/02 19:19:04 roberto Exp roberto $
  3. ** Dynamic library loader for Lua
  4. ** See Copyright Notice in lua.h
  5. **
  6. ** This module contains an implementation of loadlib for Unix systems
  7. ** that have dlfcn, an implementation for Windows, and a stub for other
  8. ** systems.
  9. */
  10. #define loadlib_c
  11. #define LUA_LIB
  12. #include "lprefix.h"
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "lua.h"
  16. #include "lauxlib.h"
  17. #include "lualib.h"
  18. /*
  19. ** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
  20. ** variables that Lua check to set its paths.
  21. */
  22. #if !defined(LUA_PATH_VAR)
  23. #define LUA_PATH_VAR "LUA_PATH"
  24. #endif
  25. #if !defined(LUA_CPATH_VAR)
  26. #define LUA_CPATH_VAR "LUA_CPATH"
  27. #endif
  28. #define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
  29. #define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
  30. #define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
  31. /*
  32. ** LUA_PATH_SEP is the character that separates templates in a path.
  33. ** LUA_PATH_MARK is the string that marks the substitution points in a
  34. ** template.
  35. ** LUA_EXEC_DIR in a Windows path is replaced by the executable's
  36. ** directory.
  37. ** LUA_IGMARK is a mark to ignore all before it when building the
  38. ** luaopen_ function name.
  39. */
  40. #if !defined (LUA_PATH_SEP)
  41. #define LUA_PATH_SEP ";"
  42. #endif
  43. #if !defined (LUA_PATH_MARK)
  44. #define LUA_PATH_MARK "?"
  45. #endif
  46. #if !defined (LUA_EXEC_DIR)
  47. #define LUA_EXEC_DIR "!"
  48. #endif
  49. #if !defined (LUA_IGMARK)
  50. #define LUA_IGMARK "-"
  51. #endif
  52. /*
  53. ** LUA_CSUBSEP is the character that replaces dots in submodule names
  54. ** when searching for a C loader.
  55. ** LUA_LSUBSEP is the character that replaces dots in submodule names
  56. ** when searching for a Lua loader.
  57. */
  58. #if !defined(LUA_CSUBSEP)
  59. #define LUA_CSUBSEP LUA_DIRSEP
  60. #endif
  61. #if !defined(LUA_LSUBSEP)
  62. #define LUA_LSUBSEP LUA_DIRSEP
  63. #endif
  64. /* prefix for open functions in C libraries */
  65. #define LUA_POF "luaopen_"
  66. /* separator for open functions in C libraries */
  67. #define LUA_OFSEP "_"
  68. /* table (in the registry) that keeps handles for all loaded C libraries */
  69. #define CLIBS "_CLIBS"
  70. #define LIB_FAIL "open"
  71. #define setprogdir(L) ((void)0)
  72. /*
  73. ** system-dependent functions
  74. */
  75. /*
  76. ** unload library 'lib'
  77. */
  78. static void lsys_unloadlib (void *lib);
  79. /*
  80. ** load C library in file 'path'. If 'seeglb', load with all names in
  81. ** the library global.
  82. ** Returns the library; in case of error, returns NULL plus an
  83. ** error string in the stack.
  84. */
  85. static void *lsys_load (lua_State *L, const char *path, int seeglb);
  86. /*
  87. ** Try to find a function named 'sym' in library 'lib'.
  88. ** Returns the function; in case of error, returns NULL plus an
  89. ** error string in the stack.
  90. */
  91. static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
  92. #if defined(LUA_USE_DLOPEN) /* { */
  93. /*
  94. ** {========================================================================
  95. ** This is an implementation of loadlib based on the dlfcn interface.
  96. ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
  97. ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
  98. ** as an emulation layer on top of native functions.
  99. ** =========================================================================
  100. */
  101. #include <dlfcn.h>
  102. static void lsys_unloadlib (void *lib) {
  103. dlclose(lib);
  104. }
  105. static void *lsys_load (lua_State *L, const char *path, int seeglb) {
  106. void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
  107. if (lib == NULL) lua_pushstring(L, dlerror());
  108. return lib;
  109. }
  110. static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
  111. lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
  112. if (f == NULL) lua_pushstring(L, dlerror());
  113. return f;
  114. }
  115. /* }====================================================== */
  116. #elif defined(LUA_DL_DLL) /* }{ */
  117. /*
  118. ** {======================================================================
  119. ** This is an implementation of loadlib for Windows using native functions.
  120. ** =======================================================================
  121. */
  122. #include <windows.h>
  123. #undef setprogdir
  124. /*
  125. ** optional flags for LoadLibraryEx
  126. */
  127. #if !defined(LUA_LLE_FLAGS)
  128. #define LUA_LLE_FLAGS 0
  129. #endif
  130. static void setprogdir (lua_State *L) {
  131. char buff[MAX_PATH + 1];
  132. char *lb;
  133. DWORD nsize = sizeof(buff)/sizeof(char);
  134. DWORD n = GetModuleFileNameA(NULL, buff, nsize);
  135. if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
  136. luaL_error(L, "unable to get ModuleFileName");
  137. else {
  138. *lb = '\0';
  139. luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
  140. lua_remove(L, -2); /* remove original string */
  141. }
  142. }
  143. static void pusherror (lua_State *L) {
  144. int error = GetLastError();
  145. char buffer[128];
  146. if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  147. NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
  148. lua_pushstring(L, buffer);
  149. else
  150. lua_pushfstring(L, "system error %d\n", error);
  151. }
  152. static void lsys_unloadlib (void *lib) {
  153. FreeLibrary((HMODULE)lib);
  154. }
  155. static void *lsys_load (lua_State *L, const char *path, int seeglb) {
  156. HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
  157. (void)(seeglb); /* not used: symbols are 'global' by default */
  158. if (lib == NULL) pusherror(L);
  159. return lib;
  160. }
  161. static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
  162. lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
  163. if (f == NULL) pusherror(L);
  164. return f;
  165. }
  166. /* }====================================================== */
  167. #else /* }{ */
  168. /*
  169. ** {======================================================
  170. ** Fallback for other systems
  171. ** =======================================================
  172. */
  173. #undef LIB_FAIL
  174. #define LIB_FAIL "absent"
  175. #define DLMSG "dynamic libraries not enabled; check your Lua installation"
  176. static void lsys_unloadlib (void *lib) {
  177. (void)(lib); /* not used */
  178. }
  179. static void *lsys_load (lua_State *L, const char *path, int seeglb) {
  180. (void)(path); (void)(seeglb); /* not used */
  181. lua_pushliteral(L, DLMSG);
  182. return NULL;
  183. }
  184. static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
  185. (void)(lib); (void)(sym); /* not used */
  186. lua_pushliteral(L, DLMSG);
  187. return NULL;
  188. }
  189. /* }====================================================== */
  190. #endif /* } */
  191. /*
  192. ** return registry.CLIBS[path]
  193. */
  194. static void *checkclib (lua_State *L, const char *path) {
  195. void *plib;
  196. lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
  197. lua_getfield(L, -1, path);
  198. plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
  199. lua_pop(L, 2); /* pop CLIBS table and 'plib' */
  200. return plib;
  201. }
  202. /*
  203. ** registry.CLIBS[path] = plib -- for queries
  204. ** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
  205. */
  206. static void addtoclib (lua_State *L, const char *path, void *plib) {
  207. lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
  208. lua_pushlightuserdata(L, plib);
  209. lua_pushvalue(L, -1);
  210. lua_setfield(L, -3, path); /* CLIBS[path] = plib */
  211. lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
  212. lua_pop(L, 1); /* pop CLIBS table */
  213. }
  214. /*
  215. ** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
  216. ** handles in list CLIBS
  217. */
  218. static int gctm (lua_State *L) {
  219. lua_Integer n = luaL_len(L, 1);
  220. for (; n >= 1; n--) { /* for each handle, in reverse order */
  221. lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
  222. lsys_unloadlib(lua_touserdata(L, -1));
  223. lua_pop(L, 1); /* pop handle */
  224. }
  225. return 0;
  226. }
  227. /* error codes for 'lookforfunc' */
  228. #define ERRLIB 1
  229. #define ERRFUNC 2
  230. /*
  231. ** Look for a C function named 'sym' in a dynamically loaded library
  232. ** 'path'.
  233. ** First, check whether the library is already loaded; if not, try
  234. ** to load it.
  235. ** Then, if 'sym' is '*', return true (as library has been loaded).
  236. ** Otherwise, look for symbol 'sym' in the library and push a
  237. ** C function with that symbol.
  238. ** Return 0 and 'true' or a function in the stack; in case of
  239. ** errors, return an error code and an error message in the stack.
  240. */
  241. static int lookforfunc (lua_State *L, const char *path, const char *sym) {
  242. void *reg = checkclib(L, path); /* check loaded C libraries */
  243. if (reg == NULL) { /* must load library? */
  244. reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */
  245. if (reg == NULL) return ERRLIB; /* unable to load library */
  246. addtoclib(L, path, reg);
  247. }
  248. if (*sym == '*') { /* loading only library (no function)? */
  249. lua_pushboolean(L, 1); /* return 'true' */
  250. return 0; /* no errors */
  251. }
  252. else {
  253. lua_CFunction f = lsys_sym(L, reg, sym);
  254. if (f == NULL)
  255. return ERRFUNC; /* unable to find function */
  256. lua_pushcfunction(L, f); /* else create new function */
  257. return 0; /* no errors */
  258. }
  259. }
  260. static int ll_loadlib (lua_State *L) {
  261. const char *path = luaL_checkstring(L, 1);
  262. const char *init = luaL_checkstring(L, 2);
  263. int stat = lookforfunc(L, path, init);
  264. if (stat == 0) /* no errors? */
  265. return 1; /* return the loaded function */
  266. else { /* error; error message is on stack top */
  267. lua_pushnil(L);
  268. lua_insert(L, -2);
  269. lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
  270. return 3; /* return nil, error message, and where */
  271. }
  272. }
  273. /*
  274. ** {======================================================
  275. ** 'require' function
  276. ** =======================================================
  277. */
  278. static int readable (const char *filename) {
  279. FILE *f = fopen(filename, "r"); /* try to open file */
  280. if (f == NULL) return 0; /* open failed */
  281. fclose(f);
  282. return 1;
  283. }
  284. static const char *pushnexttemplate (lua_State *L, const char *path) {
  285. const char *l;
  286. while (*path == *LUA_PATH_SEP) path++; /* skip separators */
  287. if (*path == '\0') return NULL; /* no more templates */
  288. l = strchr(path, *LUA_PATH_SEP); /* find next separator */
  289. if (l == NULL) l = path + strlen(path);
  290. lua_pushlstring(L, path, l - path); /* template */
  291. return l;
  292. }
  293. static const char *searchpath (lua_State *L, const char *name,
  294. const char *path,
  295. const char *sep,
  296. const char *dirsep) {
  297. luaL_Buffer msg; /* to build error message */
  298. luaL_buffinit(L, &msg);
  299. if (*sep != '\0') /* non-empty separator? */
  300. name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
  301. while ((path = pushnexttemplate(L, path)) != NULL) {
  302. const char *filename = luaL_gsub(L, lua_tostring(L, -1),
  303. LUA_PATH_MARK, name);
  304. lua_remove(L, -2); /* remove path template */
  305. if (readable(filename)) /* does file exist and is readable? */
  306. return filename; /* return that file name */
  307. lua_pushfstring(L, "\n\tno file '%s'", filename);
  308. lua_remove(L, -2); /* remove file name */
  309. luaL_addvalue(&msg); /* concatenate error msg. entry */
  310. }
  311. luaL_pushresult(&msg); /* create error message */
  312. return NULL; /* not found */
  313. }
  314. static int ll_searchpath (lua_State *L) {
  315. const char *f = searchpath(L, luaL_checkstring(L, 1),
  316. luaL_checkstring(L, 2),
  317. luaL_optstring(L, 3, "."),
  318. luaL_optstring(L, 4, LUA_DIRSEP));
  319. if (f != NULL) return 1;
  320. else { /* error message is on top of the stack */
  321. lua_pushnil(L);
  322. lua_insert(L, -2);
  323. return 2; /* return nil + error message */
  324. }
  325. }
  326. static const char *findfile (lua_State *L, const char *name,
  327. const char *pname,
  328. const char *dirsep) {
  329. const char *path;
  330. lua_getfield(L, lua_upvalueindex(1), pname);
  331. path = lua_tostring(L, -1);
  332. if (path == NULL)
  333. luaL_error(L, "'package.%s' must be a string", pname);
  334. return searchpath(L, name, path, ".", dirsep);
  335. }
  336. static int checkload (lua_State *L, int stat, const char *filename) {
  337. if (stat) { /* module loaded successfully? */
  338. lua_pushstring(L, filename); /* will be 2nd argument to module */
  339. return 2; /* return open function and file name */
  340. }
  341. else
  342. return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
  343. lua_tostring(L, 1), filename, lua_tostring(L, -1));
  344. }
  345. static int searcher_Lua (lua_State *L) {
  346. const char *filename;
  347. const char *name = luaL_checkstring(L, 1);
  348. filename = findfile(L, name, "path", LUA_LSUBSEP);
  349. if (filename == NULL) return 1; /* module not found in this path */
  350. return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
  351. }
  352. /*
  353. ** Try to find a load function for module 'modname' at file 'filename'.
  354. ** First, change '.' to '_' in 'modname'; then, if 'modname' has
  355. ** the form X-Y (that is, it has an "ignore mark"), build a function
  356. ** name "luaopen_X" and look for it. (For compatibility, if that
  357. ** fails, it also tries "luaopen_Y".) If there is no ignore mark,
  358. ** look for a function named "luaopen_modname".
  359. */
  360. static int loadfunc (lua_State *L, const char *filename, const char *modname) {
  361. const char *openfunc;
  362. const char *mark;
  363. modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
  364. mark = strchr(modname, *LUA_IGMARK);
  365. if (mark) {
  366. int stat;
  367. openfunc = lua_pushlstring(L, modname, mark - modname);
  368. openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
  369. stat = lookforfunc(L, filename, openfunc);
  370. if (stat != ERRFUNC) return stat;
  371. modname = mark + 1; /* else go ahead and try old-style name */
  372. }
  373. openfunc = lua_pushfstring(L, LUA_POF"%s", modname);
  374. return lookforfunc(L, filename, openfunc);
  375. }
  376. static int searcher_C (lua_State *L) {
  377. const char *name = luaL_checkstring(L, 1);
  378. const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
  379. if (filename == NULL) return 1; /* module not found in this path */
  380. return checkload(L, (loadfunc(L, filename, name) == 0), filename);
  381. }
  382. static int searcher_Croot (lua_State *L) {
  383. const char *filename;
  384. const char *name = luaL_checkstring(L, 1);
  385. const char *p = strchr(name, '.');
  386. int stat;
  387. if (p == NULL) return 0; /* is root */
  388. lua_pushlstring(L, name, p - name);
  389. filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
  390. if (filename == NULL) return 1; /* root not found */
  391. if ((stat = loadfunc(L, filename, name)) != 0) {
  392. if (stat != ERRFUNC)
  393. return checkload(L, 0, filename); /* real error */
  394. else { /* open function not found */
  395. lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename);
  396. return 1;
  397. }
  398. }
  399. lua_pushstring(L, filename); /* will be 2nd argument to module */
  400. return 2;
  401. }
  402. static int searcher_preload (lua_State *L) {
  403. const char *name = luaL_checkstring(L, 1);
  404. lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
  405. if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
  406. lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
  407. return 1;
  408. }
  409. static void findloader (lua_State *L, const char *name) {
  410. int i;
  411. luaL_Buffer msg; /* to build error message */
  412. luaL_buffinit(L, &msg);
  413. lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
  414. if (!lua_istable(L, 3))
  415. luaL_error(L, "'package.searchers' must be a table");
  416. /* iterate over available searchers to find a loader */
  417. for (i = 1; ; i++) {
  418. if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */
  419. lua_pop(L, 1); /* remove nil */
  420. luaL_pushresult(&msg); /* create error message */
  421. luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
  422. }
  423. lua_pushstring(L, name);
  424. lua_call(L, 1, 2); /* call it */
  425. if (lua_isfunction(L, -2)) /* did it find a loader? */
  426. return; /* module loader found */
  427. else if (lua_isstring(L, -2)) { /* searcher returned error message? */
  428. lua_pop(L, 1); /* remove extra return */
  429. luaL_addvalue(&msg); /* concatenate error message */
  430. }
  431. else
  432. lua_pop(L, 2); /* remove both returns */
  433. }
  434. }
  435. static int ll_require (lua_State *L) {
  436. const char *name = luaL_checkstring(L, 1);
  437. lua_settop(L, 1); /* _LOADED table will be at index 2 */
  438. lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
  439. lua_getfield(L, 2, name); /* _LOADED[name] */
  440. if (lua_toboolean(L, -1)) /* is it there? */
  441. return 1; /* package is already loaded */
  442. /* else must load package */
  443. lua_pop(L, 1); /* remove 'getfield' result */
  444. findloader(L, name);
  445. lua_pushstring(L, name); /* pass name as argument to module loader */
  446. lua_insert(L, -2); /* name is 1st argument (before search data) */
  447. lua_call(L, 2, 1); /* run loader to load module */
  448. if (!lua_isnil(L, -1)) /* non-nil return? */
  449. lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
  450. if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
  451. lua_pushboolean(L, 1); /* use true as result */
  452. lua_pushvalue(L, -1); /* extra copy to be returned */
  453. lua_setfield(L, 2, name); /* _LOADED[name] = true */
  454. }
  455. return 1;
  456. }
  457. /* }====================================================== */
  458. /*
  459. ** {======================================================
  460. ** 'module' function
  461. ** =======================================================
  462. */
  463. #if defined(LUA_COMPAT_MODULE)
  464. /*
  465. ** changes the environment variable of calling function
  466. */
  467. static void set_env (lua_State *L) {
  468. lua_Debug ar;
  469. if (lua_getstack(L, 1, &ar) == 0 ||
  470. lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
  471. lua_iscfunction(L, -1))
  472. luaL_error(L, "'module' not called from a Lua function");
  473. lua_pushvalue(L, -2); /* copy new environment table to top */
  474. lua_setupvalue(L, -2, 1);
  475. lua_pop(L, 1); /* remove function */
  476. }
  477. static void dooptions (lua_State *L, int n) {
  478. int i;
  479. for (i = 2; i <= n; i++) {
  480. if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
  481. lua_pushvalue(L, i); /* get option (a function) */
  482. lua_pushvalue(L, -2); /* module */
  483. lua_call(L, 1, 0);
  484. }
  485. }
  486. }
  487. static void modinit (lua_State *L, const char *modname) {
  488. const char *dot;
  489. lua_pushvalue(L, -1);
  490. lua_setfield(L, -2, "_M"); /* module._M = module */
  491. lua_pushstring(L, modname);
  492. lua_setfield(L, -2, "_NAME");
  493. dot = strrchr(modname, '.'); /* look for last dot in module name */
  494. if (dot == NULL) dot = modname;
  495. else dot++;
  496. /* set _PACKAGE as package name (full module name minus last part) */
  497. lua_pushlstring(L, modname, dot - modname);
  498. lua_setfield(L, -2, "_PACKAGE");
  499. }
  500. static int ll_module (lua_State *L) {
  501. const char *modname = luaL_checkstring(L, 1);
  502. int lastarg = lua_gettop(L); /* last parameter */
  503. luaL_pushmodule(L, modname, 1); /* get/create module table */
  504. /* check whether table already has a _NAME field */
  505. if (lua_getfield(L, -1, "_NAME") != LUA_TNIL)
  506. lua_pop(L, 1); /* table is an initialized module */
  507. else { /* no; initialize it */
  508. lua_pop(L, 1);
  509. modinit(L, modname);
  510. }
  511. lua_pushvalue(L, -1);
  512. set_env(L);
  513. dooptions(L, lastarg);
  514. return 1;
  515. }
  516. static int ll_seeall (lua_State *L) {
  517. luaL_checktype(L, 1, LUA_TTABLE);
  518. if (!lua_getmetatable(L, 1)) {
  519. lua_createtable(L, 0, 1); /* create new metatable */
  520. lua_pushvalue(L, -1);
  521. lua_setmetatable(L, 1);
  522. }
  523. lua_pushglobaltable(L);
  524. lua_setfield(L, -2, "__index"); /* mt.__index = _G */
  525. return 0;
  526. }
  527. #endif
  528. /* }====================================================== */
  529. /* auxiliary mark (for internal use) */
  530. #define AUXMARK "\1"
  531. /*
  532. ** return registry.LUA_NOENV as a boolean
  533. */
  534. static int noenv (lua_State *L) {
  535. int b;
  536. lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
  537. b = lua_toboolean(L, -1);
  538. lua_pop(L, 1); /* remove value */
  539. return b;
  540. }
  541. static void setpath (lua_State *L, const char *fieldname, const char *envname1,
  542. const char *envname2, const char *def) {
  543. const char *path = getenv(envname1);
  544. if (path == NULL) /* no environment variable? */
  545. path = getenv(envname2); /* try alternative name */
  546. if (path == NULL || noenv(L)) /* no environment variable? */
  547. lua_pushstring(L, def); /* use default */
  548. else {
  549. /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
  550. path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
  551. LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
  552. luaL_gsub(L, path, AUXMARK, def);
  553. lua_remove(L, -2);
  554. }
  555. setprogdir(L);
  556. lua_setfield(L, -2, fieldname);
  557. }
  558. static const luaL_Reg pk_funcs[] = {
  559. {"loadlib", ll_loadlib},
  560. {"searchpath", ll_searchpath},
  561. #if defined(LUA_COMPAT_MODULE)
  562. {"seeall", ll_seeall},
  563. #endif
  564. /* placeholders */
  565. {"preload", NULL},
  566. {"cpath", NULL},
  567. {"path", NULL},
  568. {"searchers", NULL},
  569. {"loaded", NULL},
  570. {NULL, NULL}
  571. };
  572. static const luaL_Reg ll_funcs[] = {
  573. #if defined(LUA_COMPAT_MODULE)
  574. {"module", ll_module},
  575. #endif
  576. {"require", ll_require},
  577. {NULL, NULL}
  578. };
  579. static void createsearcherstable (lua_State *L) {
  580. static const lua_CFunction searchers[] =
  581. {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
  582. int i;
  583. /* create 'searchers' table */
  584. lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
  585. /* fill it with pre-defined searchers */
  586. for (i=0; searchers[i] != NULL; i++) {
  587. lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
  588. lua_pushcclosure(L, searchers[i], 1);
  589. lua_rawseti(L, -2, i+1);
  590. }
  591. #if defined(LUA_COMPAT_LOADERS)
  592. lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
  593. lua_setfield(L, -3, "loaders"); /* put it in field 'loaders' */
  594. #endif
  595. lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
  596. }
  597. /*
  598. ** create table CLIBS to keep track of loaded C libraries,
  599. ** setting a finalizer to close all libraries when closing state.
  600. */
  601. static void createclibstable (lua_State *L) {
  602. luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
  603. lua_createtable(L, 0, 1); /* create metatable for CLIBS */
  604. lua_pushcfunction(L, gctm);
  605. lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
  606. lua_setmetatable(L, -2);
  607. }
  608. LUAMOD_API int luaopen_package (lua_State *L) {
  609. createclibstable(L);
  610. luaL_newlib(L, pk_funcs); /* create 'package' table */
  611. createsearcherstable(L);
  612. /* set field 'path' */
  613. setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
  614. /* set field 'cpath' */
  615. setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
  616. /* store config information */
  617. lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
  618. LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
  619. lua_setfield(L, -2, "config");
  620. /* set field 'loaded' */
  621. luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
  622. lua_setfield(L, -2, "loaded");
  623. /* set field 'preload' */
  624. luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
  625. lua_setfield(L, -2, "preload");
  626. lua_pushglobaltable(L);
  627. lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
  628. luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
  629. lua_pop(L, 1); /* pop global table */
  630. return 1; /* return 'package' table */
  631. }