/* * Returns: fd_udata */ static int sys_file (lua_State *L) { lua_boxinteger(L, -1); luaL_getmetatable(L, FD_TYPENAME); lua_setmetatable(L, -2); return 1; }
/* * Returns: sd_udata */ static int sock_new (lua_State *L) { lua_boxinteger(L, -1); luaL_getmetatable(L, SD_TYPENAME); lua_setmetatable(L, -2); return 1; }
/* * Arguments: ..., sys_lib (table) */ static void createmeta (lua_State *L) { const int top = lua_gettop(L); const struct meta_s { const char *tname; luaL_reg *meth; int is_index; } meta[] = { {DIR_TYPENAME, dir_meth, 0}, {EVQ_TYPENAME, evq_meth, 1}, {FD_TYPENAME, fd_meth, 1}, {PERIOD_TYPENAME, period_meth, 1}, {PID_TYPENAME, pid_meth, 1}, {RAND_TYPENAME, rand_meth, 0}, {LOG_TYPENAME, log_meth, 0}, }; int i; for (i = 0; i < (int) (sizeof(meta) / sizeof(struct meta_s)); ++i) { luaL_newmetatable(L, meta[i].tname); if (meta[i].is_index) { lua_pushvalue(L, -1); /* push metatable */ lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ } luaL_register(L, NULL, meta[i].meth); lua_pop(L, 1); } /* Predefined file handles */ luaL_getmetatable(L, FD_TYPENAME); { const char *std[] = {"stdin", "stdout", "stderr"}; #ifdef _WIN32 const fd_t std_fd[] = { GetStdHandle(STD_INPUT_HANDLE), GetStdHandle(STD_OUTPUT_HANDLE), GetStdHandle(STD_ERROR_HANDLE) }; #endif for (i = 3; i--; ) { #ifndef _WIN32 const fd_t fd = i; #else const fd_t fd = std_fd[i]; #endif lua_pushstring(L, std[i]); lua_boxinteger(L, fd); lua_pushvalue(L, -3); /* metatable */ lua_pushboolean(L, 1); lua_rawseti(L, -2, (int) fd); /* don't close std. handles */ lua_setmetatable(L, -2); lua_rawset(L, top); } } lua_settop(L, top); }
/* * Returns: processors_load_average (number), is_per_cpu (boolean) */ static int sys_loadavg (lua_State *L) { double loadavg; #ifndef _WIN32 const int res = 0; if (getloadavg(&loadavg, 1) == 1) { const int is_per_cpu = 1; #else const int res = getloadavg(&loadavg); if (!res) { const int is_per_cpu = 0; #endif lua_pushnumber(L, (lua_Number) loadavg); lua_pushboolean(L, is_per_cpu); return 2; } return sys_seterror(L, res); } /* * Arguments: [number_of_files (number)] * Returns: number_of_files (number) */ static int sys_limit_nfiles (lua_State *L) { #ifndef _WIN32 const int narg = lua_gettop(L); struct rlimit rlim; rlim.rlim_max = 0; getrlimit(RLIMIT_NOFILE, &rlim); lua_pushinteger(L, rlim.rlim_max); if (narg != 0) { const int n = lua_tointeger(L, 1); rlim.rlim_cur = rlim.rlim_max = n; if (setrlimit(RLIMIT_NOFILE, &rlim)) return sys_seterror(L, 0); } return 1; #else (void) L; lua_pushinteger(L, -1); return 1; #endif } /* * Arguments: string * Returns: number */ static int sys_toint (lua_State *L) { const char *s = lua_tostring(L, 1); int num = 0, sign = 1; if (s) { switch (*s) { case '-': sign = -1; case '+': ++s; } while (*s >= '0' && *s <= '9') num = (num << 3) + (num << 1) + (*s++ & ~'0'); } lua_pushinteger(L, sign * num); return 1; } /* * Arguments: error_handler (function), function, any ... * Returns: status (boolean), any ... */ static int sys_xpcall (lua_State *L) { const int status = lua_pcall(L, lua_gettop(L) - 2, LUA_MULTRET, 1); lua_pushboolean(L, !status); lua_insert(L, 2); return lua_gettop(L) - 1; } #include "isa/fcgi/sys_fcgi.c" #include "mem/sys_mem.c" #include "thread/sys_thread.c" #ifndef _WIN32 #include "sys_unix.c" #else #include "win32/sys_win32.c" #endif #include "sys_file.c" #include "sys_date.c" #include "sys_env.c" #include "sys_evq.c" #include "sys_fs.c" #include "sys_log.c" #include "sys_proc.c" #include "sys_rand.c" static luaL_Reg sys_lib[] = { {"strerror", sys_strerror}, {"nprocs", sys_nprocs}, {"loadavg", sys_loadavg}, {"limit_nfiles", sys_limit_nfiles}, {"toint", sys_toint}, {"xpcall", sys_xpcall}, DATE_METHODS, ENV_METHODS, EVQ_METHODS, FCGI_METHODS, FD_METHODS, FS_METHODS, LOG_METHODS, PROC_METHODS, RAND_METHODS, #ifndef _WIN32 UNIX_METHODS, #endif {NULL, NULL} }; /* * Arguments: ..., sys_lib (table) */ static void createmeta (lua_State *L) { const int top = lua_gettop(L); const struct meta_s { const char *tname; luaL_Reg *meth; int is_index; } meta[] = { {DIR_TYPENAME, dir_meth, 0}, {EVQ_TYPENAME, evq_meth, 1}, {FD_TYPENAME, fd_meth, 1}, {PERIOD_TYPENAME, period_meth, 1}, {PID_TYPENAME, pid_meth, 1}, {LOG_TYPENAME, log_meth, 0}, {RAND_TYPENAME, rand_meth, 0}, }; int i; for (i = 0; i < (int) (sizeof(meta) / sizeof(struct meta_s)); ++i) { luaL_newmetatable(L, meta[i].tname); if (meta[i].is_index) { lua_pushvalue(L, -1); /* push metatable */ lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ } luaL_setfuncs(L, meta[i].meth, 0); lua_pop(L, 1); } /* Predefined file handles */ luaL_getmetatable(L, FD_TYPENAME); { const char *std[] = {"stdin", "stdout", "stderr"}; for (i = 3; i--; ) { #ifndef _WIN32 const fd_t fd = i; #else const fd_t fd = GetStdHandle(i == 0 ? STD_INPUT_HANDLE : (i == 1 ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE)); #endif lua_pushstring(L, std[i]); lua_boxinteger(L, fd); lua_pushvalue(L, -3); /* metatable */ lua_pushboolean(L, 1); lua_rawseti(L, -2, (int) fd); /* don't close std. handles */ lua_setmetatable(L, -2); lua_rawset(L, top); } } lua_settop(L, top); } LUALIB_API int luaopen_sys (lua_State *L) { luaL_register(L, LUA_SYSLIBNAME, sys_lib); createmeta(L); signal_init(); #ifdef _WIN32 luaopen_sys_win32(L); #endif luaopen_sys_mem(L); luaopen_sys_thread(L); return 1; }