static int runexec(lua_State *L, int use_shell) { char **argv; const char *path = luaL_checkstring(L, 1); int i, n; checknargs(L, 2); if (lua_type(L, 2) != LUA_TTABLE) argtypeerror(L, 2, "table"); n = lua_objlen(L, 2); argv = lua_newuserdata(L, (n + 2) * sizeof(char*)); /* Set argv[0], defaulting to command */ argv[0] = (char*) path; lua_pushinteger(L, 0); lua_gettable(L, 2); if (lua_type(L, -1) == LUA_TSTRING) argv[0] = (char*)lua_tostring(L, -1); else lua_pop(L, 1); /* Read argv[1..n] from table. */ for (i=1; i<=n; i++) { lua_pushinteger(L, i); lua_gettable(L, 2); argv[i] = (char*)lua_tostring(L, -1); } argv[n+1] = NULL; (use_shell ? execvp : execv) (path, argv); return pusherror(L, path); }
static lua_Integer checkinteger(lua_State *L, int narg, const char *expected) { lua_Integer d = lua_tointeger(L, narg); if (d == 0 && !lua_isinteger(L, narg)) argtypeerror(L, narg, expected); return d; }
static chtype optch(lua_State *L, int narg, chtype def) { if (lua_isnoneornil(L, narg)) return def; if (lua_isnumber(L, narg) || lua_isstring(L, narg)) return checkch(L, narg); return argtypeerror(L, narg, "int or char or nil"); }
static chtype checkch(lua_State *L, int narg) { if (lua_isnumber(L, narg)) return (chtype)checkint(L, narg); if (lua_isstring(L, narg)) return *lua_tostring(L, narg); return argtypeerror(L, narg, "int or char"); }
static const char * optstring(lua_State *L, int narg, const char *def) { const char *s; if (lua_isnoneornil(L, narg)) return def; s = lua_tolstring(L, narg, NULL); if (!s) argtypeerror(L, narg, "string or nil"); return s; }
static gid_t mygetgid(lua_State *L, int i) { if (lua_isnoneornil(L, i)) return (gid_t)-1; else if (lua_isinteger(L, i)) return (gid_t) lua_tointeger(L, i); else if (lua_isstring(L, i)) { struct group *g = getgrnam(lua_tostring(L, i)); return (g == NULL) ? (uid_t) -1 : g->gr_gid; } else return argtypeerror(L, i, "string, int or nil"); }
static uid_t mygetuid(lua_State *L, int i) { if (lua_isnoneornil(L, i)) return (uid_t)-1; else if (lua_isinteger(L, i)) return (uid_t) lua_tointeger(L, i); else if (lua_isstring(L, i)) { struct passwd *p = getpwnam(lua_tostring(L, i)); return (p == NULL) ? (uid_t) -1 : p->pw_uid; } else return argtypeerror(L, i, "string, int or nil"); }
/*** Install a signal handler for this signal number. Although this is the same API as signal(2), it uses sigaction for guaranteed semantics. @function signal @see signal.lua @int signum @tparam[opt=SIG_DFL] function handler function, or `SIG_IGN` or `SIG_DFL` constants @param[opt] flags the `sa_flags` element of `struct sigaction` @treturn function previous handler function @see sigaction(2) */ static int Psignal (lua_State *L) { struct sigaction sa, oldsa; int sig = checkint(L, 1), ret; void (*handler)(int) = sig_postpone; checknargs(L, 3); /* Check handler is OK */ switch (lua_type(L, 2)) { case LUA_TNIL: case LUA_TSTRING: handler = Fsigmacros[luaL_checkoption(L, 2, "SIG_DFL", Ssigmacros)]; break; case LUA_TFUNCTION: if (lua_tocfunction(L, 2) == sig_handler_wrap) { lua_getupvalue(L, 2, 1); handler = lua_touserdata(L, -1); lua_pop(L, 1); } break; default: argtypeerror(L, 2, "function, string or nil"); break; } /* Set up C signal handler, getting old handler */ sa.sa_handler = handler; sa.sa_flags = optint(L, 3, 0); sigfillset(&sa.sa_mask); ret = sigaction(sig, &sa, &oldsa); if (ret == -1) return 0; /* Set Lua handler if necessary */ if (handler == sig_postpone) { lua_pushlightuserdata(L, &signalL); /* We could use an upvalue, but we need this for sig_handle anyway. */ lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, 1); lua_pushvalue(L, 2); lua_rawset(L, -3); lua_pop(L, 1); } /* Push old handler as result */ if (oldsa.sa_handler == sig_postpone) { lua_pushlightuserdata(L, &signalL); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, 1); lua_rawget(L, -2); } else if (oldsa.sa_handler == SIG_DFL) lua_pushstring(L, "SIG_DFL"); else if (oldsa.sa_handler == SIG_IGN) lua_pushstring(L, "SIG_IGN"); else { lua_pushinteger(L, sig); lua_pushlightuserdata(L, oldsa.sa_handler); lua_pushcclosure(L, sig_handler_wrap, 2); } return 1; }
static void checktype(lua_State *L, int narg, int t, const char *expected) { if (lua_type(L, narg) != t) argtypeerror (L, narg, expected); }
/*** Network address and service translation. @function getaddrinfo @string host name of a host @string service name of service @tparam[opt] PosixAddrInfo hints table @treturn[1] list of @{sockaddr} tables @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see getaddrinfo(2) @usage local res, errmsg, errcode = posix.getaddrinfo ("www.lua.org", "http", { family = P.IF_INET, socktype = P.SOCK_STREAM } ) */ static int Pgetaddrinfo(lua_State *L) { int n = 1; const char *host = optstring(L, 1, NULL); const char *service = NULL; struct addrinfo *res, hints; hints.ai_family = PF_UNSPEC; checknargs(L, 3); switch (lua_type(L, 2)) { case LUA_TNONE: case LUA_TNIL: if (host == NULL) argtypeerror(L, 2, "string or int"); break; case LUA_TNUMBER: case LUA_TSTRING: service = lua_tostring(L, 2); break; default: argtypeerror(L, 2, "string, int or nil"); break; } switch (lua_type(L, 3)) { case LUA_TNONE: case LUA_TNIL: break; case LUA_TTABLE: checkfieldnames (L, 3, Sai_fields); hints.ai_family = optintfield(L, 3, "family", PF_UNSPEC); hints.ai_socktype = optintfield(L, 3, "socktype", 0); hints.ai_protocol = optintfield(L, 3, "protocol", 0); hints.ai_flags = optintfield(L, 3, "flags", 0); break; default: argtypeerror(L, 3, "table or nil"); break; } { int r; if ((r = getaddrinfo(host, service, &hints, &res)) != 0) { lua_pushnil(L); lua_pushstring(L, gai_strerror(r)); lua_pushinteger(L, r); return 3; } } /* Copy getaddrinfo() result into Lua table */ { struct addrinfo *p; lua_newtable(L); for (p = res; p != NULL; p = p->ai_next) { lua_pushnumber(L, n++); pushsockaddrinfo(L, p->ai_family, p->ai_addr); pushnumberfield("socktype", p->ai_socktype); pushstringfield("canonname", p->ai_canonname); pushnumberfield("protocol", p->ai_protocol); lua_settable(L, -3); } } freeaddrinfo(res); return 1; }