1/* 2** $Id: loadlib.c,v 1.111.1.1 2013/04/12 18:48:47 roberto Exp $ 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 11 12/* 13** if needed, includes windows header before everything else 14*/ 15#if defined(_WIN32) 16#include <windows.h> 17#endif 18 19/* Base the Lua paths on the Syslinux path */ 20#ifdef SYSLINUX 21#include <fs.h> 22#endif 23 24#include <stdlib.h> 25#include <string.h> 26 27 28#define loadlib_c 29#define LUA_LIB 30 31#include "lua.h" 32 33#include "lauxlib.h" 34#include "lualib.h" 35 36 37/* 38** LUA_PATH and LUA_CPATH are the names of the environment 39** variables that Lua check to set its paths. 40*/ 41#if !defined(LUA_PATH) 42#define LUA_PATH "LUA_PATH" 43#endif 44 45#if !defined(LUA_CPATH) 46#define LUA_CPATH "LUA_CPATH" 47#endif 48 49#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 50 51#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX 52#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX 53 54/* 55** LUA_PATH_SEP is the character that separates templates in a path. 56** LUA_PATH_MARK is the string that marks the substitution points in a 57** template. 58** LUA_EXEC_DIR in a Windows path is replaced by the executable's 59** directory. 60** LUA_IGMARK is a mark to ignore all before it when building the 61** luaopen_ function name. 62*/ 63#if !defined (LUA_PATH_SEP) 64#define LUA_PATH_SEP ";" 65#endif 66#if !defined (LUA_PATH_MARK) 67#define LUA_PATH_MARK "?" 68#endif 69#if !defined (LUA_EXEC_DIR) 70#define LUA_EXEC_DIR "!" 71#endif 72#if !defined (LUA_IGMARK) 73#define LUA_IGMARK "-" 74#endif 75 76 77/* 78** LUA_CSUBSEP is the character that replaces dots in submodule names 79** when searching for a C loader. 80** LUA_LSUBSEP is the character that replaces dots in submodule names 81** when searching for a Lua loader. 82*/ 83#if !defined(LUA_CSUBSEP) 84#define LUA_CSUBSEP LUA_DIRSEP 85#endif 86 87#if !defined(LUA_LSUBSEP) 88#define LUA_LSUBSEP LUA_DIRSEP 89#endif 90 91 92/* prefix for open functions in C libraries */ 93#define LUA_POF "luaopen_" 94 95/* separator for open functions in C libraries */ 96#define LUA_OFSEP "_" 97 98 99/* table (in the registry) that keeps handles for all loaded C libraries */ 100#define CLIBS "_CLIBS" 101 102#define LIB_FAIL "open" 103 104 105/* error codes for ll_loadfunc */ 106#define ERRLIB 1 107#define ERRFUNC 2 108 109#define setprogdir(L) ((void)0) 110 111 112/* 113** system-dependent functions 114*/ 115static void ll_unloadlib (void *lib); 116static void *ll_load (lua_State *L, const char *path, int seeglb); 117static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); 118 119 120 121#if defined(LUA_USE_DLOPEN) 122/* 123** {======================================================================== 124** This is an implementation of loadlib based on the dlfcn interface. 125** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, 126** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least 127** as an emulation layer on top of native functions. 128** ========================================================================= 129*/ 130 131#include <dlfcn.h> 132 133static void ll_unloadlib (void *lib) { 134 dlclose(lib); 135} 136 137 138static void *ll_load (lua_State *L, const char *path, int seeglb) { 139 void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); 140 if (lib == NULL) lua_pushstring(L, dlerror()); 141 return lib; 142} 143 144 145static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 146 lua_CFunction f = (lua_CFunction)dlsym(lib, sym); 147 if (f == NULL) lua_pushstring(L, dlerror()); 148 return f; 149} 150 151/* }====================================================== */ 152 153 154 155#elif defined(LUA_DL_DLL) 156/* 157** {====================================================================== 158** This is an implementation of loadlib for Windows using native functions. 159** ======================================================================= 160*/ 161 162#undef setprogdir 163 164/* 165** optional flags for LoadLibraryEx 166*/ 167#if !defined(LUA_LLE_FLAGS) 168#define LUA_LLE_FLAGS 0 169#endif 170 171 172static void setprogdir (lua_State *L) { 173 char buff[MAX_PATH + 1]; 174 char *lb; 175 DWORD nsize = sizeof(buff)/sizeof(char); 176 DWORD n = GetModuleFileNameA(NULL, buff, nsize); 177 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) 178 luaL_error(L, "unable to get ModuleFileName"); 179 else { 180 *lb = '\0'; 181 luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); 182 lua_remove(L, -2); /* remove original string */ 183 } 184} 185 186 187static void pusherror (lua_State *L) { 188 int error = GetLastError(); 189 char buffer[128]; 190 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 191 NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) 192 lua_pushstring(L, buffer); 193 else 194 lua_pushfstring(L, "system error %d\n", error); 195} 196 197static void ll_unloadlib (void *lib) { 198 FreeLibrary((HMODULE)lib); 199} 200 201 202static void *ll_load (lua_State *L, const char *path, int seeglb) { 203 HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); 204 (void)(seeglb); /* not used: symbols are 'global' by default */ 205 if (lib == NULL) pusherror(L); 206 return lib; 207} 208 209 210static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 211 lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); 212 if (f == NULL) pusherror(L); 213 return f; 214} 215 216/* }====================================================== */ 217 218 219#elif defined(SYSLINUX) 220/* 221** {========================================================================= 222** This is an implementation of loadlib for the Syslinux COM32 module system. 223** ========================================================================== 224*/ 225 226#include <sys/module.h> 227 228static void ll_unloadlib (void *lib) { 229 module_unload ((struct elf_module *)lib); 230} 231 232 233static void *ll_load (lua_State *L, const char *path, int seeglb) { 234 int err; 235 struct elf_module *lib = module_alloc (path); 236 if (lib == NULL) { 237 lua_pushstring (L, "module not found"); 238 return NULL; 239 } 240 (void)seeglb; /* gcc, ignore it */ 241 err = module_load (lib); 242 if (err) { 243 printf ("module load error: %d\n", err); 244 lua_pushstring (L, "failed to load module"); 245 return NULL; 246 } 247 return (void *)lib; 248} 249 250 251static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 252 Elf_Sym *p = module_find_symbol (sym, (struct elf_module *)lib); 253 if (p == NULL) { 254 lua_pushstring (L, "symbol not found in module"); 255 return NULL; 256 } 257 return (lua_CFunction)module_get_absolute(p->st_value, (struct elf_module *)lib); 258} 259 260/* }====================================================== */ 261 262 263 264#else 265/* 266** {====================================================== 267** Fallback for other systems 268** ======================================================= 269*/ 270 271#undef LIB_FAIL 272#define LIB_FAIL "absent" 273 274 275#define DLMSG "dynamic libraries not enabled; check your Lua installation" 276 277 278static void ll_unloadlib (void *lib) { 279 (void)(lib); /* not used */ 280} 281 282 283static void *ll_load (lua_State *L, const char *path, int seeglb) { 284 (void)(path); (void)(seeglb); /* not used */ 285 lua_pushliteral(L, DLMSG); 286 return NULL; 287} 288 289 290static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 291 (void)(lib); (void)(sym); /* not used */ 292 lua_pushliteral(L, DLMSG); 293 return NULL; 294} 295 296/* }====================================================== */ 297#endif 298 299 300static void *ll_checkclib (lua_State *L, const char *path) { 301 void *plib; 302 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); 303 lua_getfield(L, -1, path); 304 plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ 305 lua_pop(L, 2); /* pop CLIBS table and 'plib' */ 306 return plib; 307} 308 309 310static void ll_addtoclib (lua_State *L, const char *path, void *plib) { 311 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); 312 lua_pushlightuserdata(L, plib); 313 lua_pushvalue(L, -1); 314 lua_setfield(L, -3, path); /* CLIBS[path] = plib */ 315 lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ 316 lua_pop(L, 1); /* pop CLIBS table */ 317} 318 319 320/* 321** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib 322** handles in list CLIBS 323*/ 324static int gctm (lua_State *L) { 325 int n = luaL_len(L, 1); 326 for (; n >= 1; n--) { /* for each handle, in reverse order */ 327 lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ 328 ll_unloadlib(lua_touserdata(L, -1)); 329 lua_pop(L, 1); /* pop handle */ 330 } 331 return 0; 332} 333 334 335static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { 336 void *reg = ll_checkclib(L, path); /* check loaded C libraries */ 337 if (reg == NULL) { /* must load library? */ 338 reg = ll_load(L, path, *sym == '*'); 339 if (reg == NULL) return ERRLIB; /* unable to load library */ 340 ll_addtoclib(L, path, reg); 341 } 342 if (*sym == '*') { /* loading only library (no function)? */ 343 lua_pushboolean(L, 1); /* return 'true' */ 344 return 0; /* no errors */ 345 } 346 else { 347 lua_CFunction f = ll_sym(L, reg, sym); 348 if (f == NULL) 349 return ERRFUNC; /* unable to find function */ 350 lua_pushcfunction(L, f); /* else create new function */ 351 return 0; /* no errors */ 352 } 353} 354 355 356static int ll_loadlib (lua_State *L) { 357 const char *path = luaL_checkstring(L, 1); 358 const char *init = luaL_checkstring(L, 2); 359 int stat = ll_loadfunc(L, path, init); 360 if (stat == 0) /* no errors? */ 361 return 1; /* return the loaded function */ 362 else { /* error; error message is on stack top */ 363 lua_pushnil(L); 364 lua_insert(L, -2); 365 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); 366 return 3; /* return nil, error message, and where */ 367 } 368} 369 370 371 372/* 373** {====================================================== 374** 'require' function 375** ======================================================= 376*/ 377 378 379static int readable (const char *filename) { 380 FILE *f = fopen(filename, "r"); /* try to open file */ 381 if (f == NULL) return 0; /* open failed */ 382 fclose(f); 383 return 1; 384} 385 386 387static const char *pushnexttemplate (lua_State *L, const char *path) { 388 const char *l; 389 while (*path == *LUA_PATH_SEP) path++; /* skip separators */ 390 if (*path == '\0') return NULL; /* no more templates */ 391 l = strchr(path, *LUA_PATH_SEP); /* find next separator */ 392 if (l == NULL) l = path + strlen(path); 393 lua_pushlstring(L, path, l - path); /* template */ 394 return l; 395} 396 397 398static const char *searchpath (lua_State *L, const char *name, 399 const char *path, 400 const char *sep, 401 const char *dirsep) { 402 luaL_Buffer msg; /* to build error message */ 403 luaL_buffinit(L, &msg); 404 if (*sep != '\0') /* non-empty separator? */ 405 name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ 406 while ((path = pushnexttemplate(L, path)) != NULL) { 407 const char *filename = luaL_gsub(L, lua_tostring(L, -1), 408 LUA_PATH_MARK, name); 409 lua_remove(L, -2); /* remove path template */ 410 if (readable(filename)) /* does file exist and is readable? */ 411 return filename; /* return that file name */ 412 lua_pushfstring(L, "\n\tno file " LUA_QS, filename); 413 lua_remove(L, -2); /* remove file name */ 414 luaL_addvalue(&msg); /* concatenate error msg. entry */ 415 } 416 luaL_pushresult(&msg); /* create error message */ 417 return NULL; /* not found */ 418} 419 420 421static int ll_searchpath (lua_State *L) { 422 const char *f = searchpath(L, luaL_checkstring(L, 1), 423 luaL_checkstring(L, 2), 424 luaL_optstring(L, 3, "."), 425 luaL_optstring(L, 4, LUA_DIRSEP)); 426 if (f != NULL) return 1; 427 else { /* error message is on top of the stack */ 428 lua_pushnil(L); 429 lua_insert(L, -2); 430 return 2; /* return nil + error message */ 431 } 432} 433 434 435static const char *findfile (lua_State *L, const char *name, 436 const char *pname, 437 const char *dirsep) { 438 const char *path; 439 lua_getfield(L, lua_upvalueindex(1), pname); 440 path = lua_tostring(L, -1); 441 if (path == NULL) 442 luaL_error(L, LUA_QL("package.%s") " must be a string", pname); 443 return searchpath(L, name, path, ".", dirsep); 444} 445 446 447static int checkload (lua_State *L, int stat, const char *filename) { 448 if (stat) { /* module loaded successfully? */ 449 lua_pushstring(L, filename); /* will be 2nd argument to module */ 450 return 2; /* return open function and file name */ 451 } 452 else 453 return luaL_error(L, "error loading module " LUA_QS 454 " from file " LUA_QS ":\n\t%s", 455 lua_tostring(L, 1), filename, lua_tostring(L, -1)); 456} 457 458 459static int searcher_Lua (lua_State *L) { 460 const char *filename; 461 const char *name = luaL_checkstring(L, 1); 462 filename = findfile(L, name, "path", LUA_LSUBSEP); 463 if (filename == NULL) return 1; /* module not found in this path */ 464 return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); 465} 466 467 468static int loadfunc (lua_State *L, const char *filename, const char *modname) { 469 const char *funcname; 470 const char *mark; 471 modname = luaL_gsub(L, modname, ".", LUA_OFSEP); 472 mark = strchr(modname, *LUA_IGMARK); 473 if (mark) { 474 int stat; 475 funcname = lua_pushlstring(L, modname, mark - modname); 476 funcname = lua_pushfstring(L, LUA_POF"%s", funcname); 477 stat = ll_loadfunc(L, filename, funcname); 478 if (stat != ERRFUNC) return stat; 479 modname = mark + 1; /* else go ahead and try old-style name */ 480 } 481 funcname = lua_pushfstring(L, LUA_POF"%s", modname); 482 return ll_loadfunc(L, filename, funcname); 483} 484 485 486static int searcher_C (lua_State *L) { 487 const char *name = luaL_checkstring(L, 1); 488 const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); 489 if (filename == NULL) return 1; /* module not found in this path */ 490 return checkload(L, (loadfunc(L, filename, name) == 0), filename); 491} 492 493 494static int searcher_Croot (lua_State *L) { 495 const char *filename; 496 const char *name = luaL_checkstring(L, 1); 497 const char *p = strchr(name, '.'); 498 int stat; 499 if (p == NULL) return 0; /* is root */ 500 lua_pushlstring(L, name, p - name); 501 filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); 502 if (filename == NULL) return 1; /* root not found */ 503 if ((stat = loadfunc(L, filename, name)) != 0) { 504 if (stat != ERRFUNC) 505 return checkload(L, 0, filename); /* real error */ 506 else { /* open function not found */ 507 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, 508 name, filename); 509 return 1; 510 } 511 } 512 lua_pushstring(L, filename); /* will be 2nd argument to module */ 513 return 2; 514} 515 516 517static int searcher_preload (lua_State *L) { 518 const char *name = luaL_checkstring(L, 1); 519 lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); 520 lua_getfield(L, -1, name); 521 if (lua_isnil(L, -1)) /* not found? */ 522 lua_pushfstring(L, "\n\tno field package.preload['%s']", name); 523 return 1; 524} 525 526 527static void findloader (lua_State *L, const char *name) { 528 int i; 529 luaL_Buffer msg; /* to build error message */ 530 luaL_buffinit(L, &msg); 531 lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ 532 if (!lua_istable(L, 3)) 533 luaL_error(L, LUA_QL("package.searchers") " must be a table"); 534 /* iterate over available searchers to find a loader */ 535 for (i = 1; ; i++) { 536 lua_rawgeti(L, 3, i); /* get a searcher */ 537 if (lua_isnil(L, -1)) { /* no more searchers? */ 538 lua_pop(L, 1); /* remove nil */ 539 luaL_pushresult(&msg); /* create error message */ 540 luaL_error(L, "module " LUA_QS " not found:%s", 541 name, lua_tostring(L, -1)); 542 } 543 lua_pushstring(L, name); 544 lua_call(L, 1, 2); /* call it */ 545 if (lua_isfunction(L, -2)) /* did it find a loader? */ 546 return; /* module loader found */ 547 else if (lua_isstring(L, -2)) { /* searcher returned error message? */ 548 lua_pop(L, 1); /* remove extra return */ 549 luaL_addvalue(&msg); /* concatenate error message */ 550 } 551 else 552 lua_pop(L, 2); /* remove both returns */ 553 } 554} 555 556 557static int ll_require (lua_State *L) { 558 const char *name = luaL_checkstring(L, 1); 559 lua_settop(L, 1); /* _LOADED table will be at index 2 */ 560 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 561 lua_getfield(L, 2, name); /* _LOADED[name] */ 562 if (lua_toboolean(L, -1)) /* is it there? */ 563 return 1; /* package is already loaded */ 564 /* else must load package */ 565 lua_pop(L, 1); /* remove 'getfield' result */ 566 findloader(L, name); 567 lua_pushstring(L, name); /* pass name as argument to module loader */ 568 lua_insert(L, -2); /* name is 1st argument (before search data) */ 569 lua_call(L, 2, 1); /* run loader to load module */ 570 if (!lua_isnil(L, -1)) /* non-nil return? */ 571 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ 572 lua_getfield(L, 2, name); 573 if (lua_isnil(L, -1)) { /* module did not set a value? */ 574 lua_pushboolean(L, 1); /* use true as result */ 575 lua_pushvalue(L, -1); /* extra copy to be returned */ 576 lua_setfield(L, 2, name); /* _LOADED[name] = true */ 577 } 578 return 1; 579} 580 581/* }====================================================== */ 582 583 584 585/* 586** {====================================================== 587** 'module' function 588** ======================================================= 589*/ 590#if defined(LUA_COMPAT_MODULE) 591 592/* 593** changes the environment variable of calling function 594*/ 595static void set_env (lua_State *L) { 596 lua_Debug ar; 597 if (lua_getstack(L, 1, &ar) == 0 || 598 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ 599 lua_iscfunction(L, -1)) 600 luaL_error(L, LUA_QL("module") " not called from a Lua function"); 601 lua_pushvalue(L, -2); /* copy new environment table to top */ 602 lua_setupvalue(L, -2, 1); 603 lua_pop(L, 1); /* remove function */ 604} 605 606 607static void dooptions (lua_State *L, int n) { 608 int i; 609 for (i = 2; i <= n; i++) { 610 if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ 611 lua_pushvalue(L, i); /* get option (a function) */ 612 lua_pushvalue(L, -2); /* module */ 613 lua_call(L, 1, 0); 614 } 615 } 616} 617 618 619static void modinit (lua_State *L, const char *modname) { 620 const char *dot; 621 lua_pushvalue(L, -1); 622 lua_setfield(L, -2, "_M"); /* module._M = module */ 623 lua_pushstring(L, modname); 624 lua_setfield(L, -2, "_NAME"); 625 dot = strrchr(modname, '.'); /* look for last dot in module name */ 626 if (dot == NULL) dot = modname; 627 else dot++; 628 /* set _PACKAGE as package name (full module name minus last part) */ 629 lua_pushlstring(L, modname, dot - modname); 630 lua_setfield(L, -2, "_PACKAGE"); 631} 632 633 634static int ll_module (lua_State *L) { 635 const char *modname = luaL_checkstring(L, 1); 636 int lastarg = lua_gettop(L); /* last parameter */ 637 luaL_pushmodule(L, modname, 1); /* get/create module table */ 638 /* check whether table already has a _NAME field */ 639 lua_getfield(L, -1, "_NAME"); 640 if (!lua_isnil(L, -1)) /* is table an initialized module? */ 641 lua_pop(L, 1); 642 else { /* no; initialize it */ 643 lua_pop(L, 1); 644 modinit(L, modname); 645 } 646 lua_pushvalue(L, -1); 647 set_env(L); 648 dooptions(L, lastarg); 649 return 1; 650} 651 652 653static int ll_seeall (lua_State *L) { 654 luaL_checktype(L, 1, LUA_TTABLE); 655 if (!lua_getmetatable(L, 1)) { 656 lua_createtable(L, 0, 1); /* create new metatable */ 657 lua_pushvalue(L, -1); 658 lua_setmetatable(L, 1); 659 } 660 lua_pushglobaltable(L); 661 lua_setfield(L, -2, "__index"); /* mt.__index = _G */ 662 return 0; 663} 664 665#endif 666/* }====================================================== */ 667 668 669 670/* auxiliary mark (for internal use) */ 671#define AUXMARK "\1" 672 673 674#ifdef SYSLINUX 675static void setpath (lua_State *L, const char *fieldname, const char *envname1, 676 const char *envname2, const char *def) { 677 struct path_entry *entry; 678 luaL_Buffer b; 679 luaL_buffinit (L, &b); 680 (void)envname1; 681 (void)envname2; 682 list_for_each_entry(entry, &PATH, list) { 683 const char *e = entry->str; 684 int need_slash = e[strlen(e)-1] != '/'; 685 void add (const char *stem) { 686 luaL_addstring (&b, e); 687 if (need_slash) luaL_addchar (&b, '/'); 688 luaL_addstring (&b, stem); 689 luaL_addstring (&b, def); 690 luaL_addchar (&b, ';'); 691 } 692 add ("?"); 693 add ("?/init"); 694 } 695 luaL_addstring (&b, "./?"); 696 luaL_addstring (&b, def); 697 luaL_pushresult (&b); 698 lua_setfield(L, -2, fieldname); 699} 700#else 701/* 702** return registry.LUA_NOENV as a boolean 703*/ 704static int noenv (lua_State *L) { 705 int b; 706 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 707 b = lua_toboolean(L, -1); 708 lua_pop(L, 1); /* remove value */ 709 return b; 710} 711 712 713static void setpath (lua_State *L, const char *fieldname, const char *envname1, 714 const char *envname2, const char *def) { 715 const char *path = getenv(envname1); 716 if (path == NULL) /* no environment variable? */ 717 path = getenv(envname2); /* try alternative name */ 718 if (path == NULL || noenv(L)) /* no environment variable? */ 719 lua_pushstring(L, def); /* use default */ 720 else { 721 /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ 722 path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, 723 LUA_PATH_SEP AUXMARK LUA_PATH_SEP); 724 luaL_gsub(L, path, AUXMARK, def); 725 lua_remove(L, -2); 726 } 727 setprogdir(L); 728 lua_setfield(L, -2, fieldname); 729} 730#endif 731 732 733static const luaL_Reg pk_funcs[] = { 734 {"loadlib", ll_loadlib}, 735 {"searchpath", ll_searchpath}, 736#if defined(LUA_COMPAT_MODULE) 737 {"seeall", ll_seeall}, 738#endif 739 {NULL, NULL} 740}; 741 742 743static const luaL_Reg ll_funcs[] = { 744#if defined(LUA_COMPAT_MODULE) 745 {"module", ll_module}, 746#endif 747 {"require", ll_require}, 748 {NULL, NULL} 749}; 750 751 752static void createsearcherstable (lua_State *L) { 753 static const lua_CFunction searchers[] = 754 {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; 755 int i; 756 /* create 'searchers' table */ 757 lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); 758 /* fill it with pre-defined searchers */ 759 for (i=0; searchers[i] != NULL; i++) { 760 lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ 761 lua_pushcclosure(L, searchers[i], 1); 762 lua_rawseti(L, -2, i+1); 763 } 764} 765 766 767LUAMOD_API int luaopen_package (lua_State *L) { 768 /* create table CLIBS to keep track of loaded C libraries */ 769 luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); 770 lua_createtable(L, 0, 1); /* metatable for CLIBS */ 771 lua_pushcfunction(L, gctm); 772 lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ 773 lua_setmetatable(L, -2); 774 /* create `package' table */ 775 luaL_newlib(L, pk_funcs); 776 createsearcherstable(L); 777#if defined(LUA_COMPAT_LOADERS) 778 lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ 779 lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ 780#endif 781 lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ 782 /* set field 'path' */ 783 setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); 784 /* set field 'cpath' */ 785 setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); 786 /* store config information */ 787 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" 788 LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); 789 lua_setfield(L, -2, "config"); 790 /* set field `loaded' */ 791 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); 792 lua_setfield(L, -2, "loaded"); 793 /* set field `preload' */ 794 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 795 lua_setfield(L, -2, "preload"); 796 lua_pushglobaltable(L); 797 lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ 798 luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ 799 lua_pop(L, 1); /* pop global table */ 800 return 1; /* return 'package' table */ 801} 802 803