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 */ 115 static void ll_unloadlib (void *lib); 116 static void *ll_load (lua_State *L, const char *path, int seeglb); 117 static 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 133 static void ll_unloadlib (void *lib) { 134 dlclose(lib); 135 } 136 137 138 static 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 145 static 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 172 static 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 187 static 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 197 static void ll_unloadlib (void *lib) { 198 FreeLibrary((HMODULE)lib); 199 } 200 201 202 static 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 210 static 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 228 static void ll_unloadlib (void *lib) { 229 module_unload ((struct elf_module *)lib); 230 } 231 232 233 static 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 251 static 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 278 static void ll_unloadlib (void *lib) { 279 (void)(lib); /* not used */ 280 } 281 282 283 static 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 290 static 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 300 static 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 310 static 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 */ 324 static 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 335 static 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 356 static 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 379 static 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 387 static 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 398 static 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 421 static 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 435 static 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 447 static 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 459 static 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 468 static 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 486 static 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 494 static 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 517 static 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 527 static 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 557 static 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 */ 595 static 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 607 static 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 619 static 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 634 static 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 653 static 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 675 static 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 */ 704 static 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 713 static 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 733 static 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 743 static 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 752 static 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 767 LUAMOD_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