summaryrefslogtreecommitdiffhomepage
path: root/libs/nixio/src/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/nixio/src/process.c')
-rw-r--r--libs/nixio/src/process.c374
1 files changed, 311 insertions, 63 deletions
diff --git a/libs/nixio/src/process.c b/libs/nixio/src/process.c
index a82e5660d..0e8ac8a29 100644
--- a/libs/nixio/src/process.c
+++ b/libs/nixio/src/process.c
@@ -17,15 +17,98 @@
*/
#include "nixio.h"
-#include <pwd.h>
-#include <grp.h>
+#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
-#include <sys/wait.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
+#define NIXIO_EXECVE 0x01
+#define NIXIO_EXECV 0x02
+#define NIXIO_EXECVP 0x03
+
+int nixio__exec(lua_State *L, int m) {
+ const char *path = luaL_checkstring(L, 1);
+ const char *arg;
+ int argn, i;
+
+ if (m == NIXIO_EXECVE) {
+ luaL_checktype(L, 2, LUA_TTABLE);
+ argn = lua_objlen(L, 2) + 1;
+ } else {
+ argn = lua_gettop(L);
+ }
+
+ char **args = lua_newuserdata(L, sizeof(char*) * (argn + 1));
+ args[argn] = NULL;
+ args[0] = (char *)path;
+
+ if (m == NIXIO_EXECVE) {
+ for (i = 1; i < argn; i++) {
+ lua_rawgeti(L, 2, i);
+ arg = lua_tostring(L, -1);
+ luaL_argcheck(L, arg, 2, "invalid argument");
+ args[i] = (char *)arg;
+ }
+
+ if (lua_isnoneornil(L, 3)) {
+ execv(path, args);
+ } else {
+ luaL_checktype(L, 3, LUA_TTABLE);
+ argn = 0;
+ lua_pushnil(L);
+ while (lua_next(L, 3)) {
+ if (!lua_checkstack(L, 1)) {
+ lua_settop(L, 0);
+ return luaL_error(L, "stack overflow");
+ }
+
+ if (!lua_type(L, -2) != LUA_TSTRING || !lua_isstring(L, -1)) {
+ return luaL_argerror(L, 3, "invalid environment");
+ }
+
+ lua_pushfstring(L, "%s=%s",
+ lua_tostring(L, -2), lua_tostring(L, -1));
+
+ lua_insert(L, 4);
+ lua_pop(L, 1);
+ argn++;
+ }
+
+ char **env = lua_newuserdata(L, sizeof(char*) * (argn + 1));
+ env[argn] = NULL;
+
+ for (i = 1; i < argn; i++) {
+ env[i-1] = (char *)lua_tostring(L, -i);
+ }
+
+ execve(path, args, env);
+ }
+ } else {
+ for (i = 2; i <= argn; i++) {
+ arg = luaL_checkstring(L, i);
+ args[i-1] = (char *)arg;
+ }
+
+ if (m == NIXIO_EXECV) {
+ execv(path, args);
+ } else {
+ execvp(path, args);
+ }
+ }
+
+ return nixio__perror(L);
+}
+
+#ifndef __WINNT__
+#include <sys/utsname.h>
+#include <sys/times.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#include <grp.h>
+
static int nixio_fork(lua_State *L) {
pid_t pid = fork();
if (pid == -1) {
@@ -36,16 +119,55 @@ static int nixio_fork(lua_State *L) {
}
}
-static int nixio_signal(lua_State *L) {
- int sig = luaL_checkinteger(L, 1);
- const char *val = luaL_checkstring(L, 2);
+static int nixio_kill(lua_State *L) {
+ return nixio__pstatus(L, !kill(luaL_checkint(L, 1), luaL_checkint(L, 2)));
+}
- if (!strcmp(val, "ign") || !strcmp(val, "ignore")) {
- return nixio__pstatus(L, signal(sig, SIG_IGN) != SIG_ERR);
- } else if (!strcmp(val, "dfl") || !strcmp(val, "default")) {
- return nixio__pstatus(L, signal(sig, SIG_DFL) != SIG_ERR);
+static int nixio_getppid(lua_State *L) {
+ lua_pushinteger(L, getppid());
+ return 1;
+}
+
+static int nixio_getuid(lua_State *L) {
+ lua_pushinteger(L, getuid());
+ return 1;
+}
+
+static int nixio_getgid(lua_State *L) {
+ lua_pushinteger(L, getgid());
+ return 1;
+}
+
+static int nixio_setgid(lua_State *L) {
+ return nixio__pstatus(L, !setgid(nixio__check_group(L, 1)));
+}
+
+static int nixio_setuid(lua_State *L) {
+ return nixio__pstatus(L, !setuid(nixio__check_user(L, 1)));
+}
+
+static int nixio_nice(lua_State *L) {
+ int nval = luaL_checkint(L, 1);
+
+ errno = 0;
+ nval = nice(nval);
+
+ if (nval == -1 && errno) {
+ return nixio__perror(L);
} else {
- return luaL_argerror(L, 2, "supported values: ign, dfl");
+ lua_pushinteger(L, nval);
+ return 1;
+ }
+}
+
+static int nixio_setsid(lua_State *L) {
+ pid_t pid = setsid();
+
+ if (pid == -1) {
+ return nixio__perror(L);
+ } else {
+ lua_pushinteger(L, pid);
+ return 1;
}
}
@@ -97,103 +219,229 @@ static int nixio_wait(lua_State *L) {
return 3;
}
-static int nixio_kill(lua_State *L) {
- return nixio__pstatus(L, !kill(luaL_checkint(L, 1), luaL_checkint(L, 2)));
+static int nixio_times(lua_State *L) {
+ struct tms buf;
+ if (times(&buf) == -1) {
+ return nixio__perror(L);
+ } else {
+ lua_createtable(L, 0, 4);
+ lua_pushnumber(L, buf.tms_cstime);
+ lua_setfield(L, -2, "cstime");
+
+ lua_pushnumber(L, buf.tms_cutime);
+ lua_setfield(L, -2, "cutime");
+
+ lua_pushnumber(L, buf.tms_stime);
+ lua_setfield(L, -2, "stime");
+
+ lua_pushnumber(L, buf.tms_utime);
+ lua_setfield(L, -2, "utime");
+
+ return 1;
+ }
}
-static int nixio_getpid(lua_State *L) {
- lua_pushinteger(L, getpid());
+static int nixio_uname(lua_State *L) {
+ struct utsname buf;
+ if (uname(&buf)) {
+ return nixio__perror(L);
+ }
+
+ lua_createtable(L, 0, 5);
+
+ lua_pushstring(L, buf.machine);
+ lua_setfield(L, -2, "machine");
+
+ lua_pushstring(L, buf.version);
+ lua_setfield(L, -2, "version");
+
+ lua_pushstring(L, buf.release);
+ lua_setfield(L, -2, "release");
+
+ lua_pushstring(L, buf.nodename);
+ lua_setfield(L, -2, "nodename");
+
+ lua_pushstring(L, buf.sysname);
+ lua_setfield(L, -2, "sysname");
+
return 1;
}
-static int nixio_getppid(lua_State *L) {
- lua_pushinteger(L, getppid());
- return 1;
+#endif /* !__WINNT__ */
+
+static int nixio_chdir(lua_State *L) {
+ return nixio__pstatus(L, !chdir(luaL_checkstring(L, 1)));
}
-static int nixio_getuid(lua_State *L) {
- lua_pushinteger(L, getuid());
- return 1;
+static int nixio_signal(lua_State *L) {
+ int sig = luaL_checkinteger(L, 1);
+ const char *val = luaL_checkstring(L, 2);
+
+ if (!strcmp(val, "ign") || !strcmp(val, "ignore")) {
+ return nixio__pstatus(L, signal(sig, SIG_IGN) != SIG_ERR);
+ } else if (!strcmp(val, "dfl") || !strcmp(val, "default")) {
+ return nixio__pstatus(L, signal(sig, SIG_DFL) != SIG_ERR);
+ } else {
+ return luaL_argerror(L, 2, "supported values: ign, dfl");
+ }
}
-static int nixio_getgid(lua_State *L) {
- lua_pushinteger(L, getgid());
+static int nixio_getpid(lua_State *L) {
+ lua_pushinteger(L, getpid());
return 1;
}
-static int nixio_setgid(lua_State *L) {
- gid_t gid;
- if (lua_isstring(L, 1)) {
- struct group *g = getgrnam(lua_tostring(L, 1));
- gid = (!g) ? -1 : g->gr_gid;
- } else if (lua_isnumber(L, 1)) {
- gid = lua_tointeger(L, 1);
+static int nixio_getenv(lua_State *L) {
+ const char *key = luaL_optstring(L, 1, NULL);
+ if (key) {
+ const char *val = getenv(key);
+ if (val) {
+ lua_pushstring(L, val);
+ } else {
+ lua_pushnil(L);
+ }
} else {
- return luaL_argerror(L, 1, "supported values: <groupname>, <gid>");
+ lua_newtable(L);
+ extern char **environ;
+ for (char **c = environ; *c; c++) {
+ const char *delim = strchr(*c, '=');
+ if (!delim) {
+ return luaL_error(L, "invalid environment");
+ }
+ lua_pushlstring(L, *c, delim-*c);
+ lua_pushstring(L, delim + 1);
+ lua_rawset(L, -3);
+ }
}
+ return 1;
+}
- return nixio__pstatus(L, !setgid(gid));
+static int nixio_setenv(lua_State *L) {
+ const char *key = luaL_checkstring(L, 1);
+ const char *val = luaL_optstring(L, 2, NULL);
+ return nixio__pstatus(L, (val) ? !setenv(key, val, 1) : !unsetenv(key));
}
-static int nixio_setuid(lua_State *L) {
- uid_t uid;
- if (lua_isstring(L, 1)) {
- struct passwd *p = getpwnam(lua_tostring(L, 1));
- uid = (!p) ? -1 : p->pw_uid;
- } else if (lua_isnumber(L, 1)) {
- uid = lua_tointeger(L, 1);
- } else {
- return luaL_argerror(L, 1, "supported values: <username>, <uid>");
- }
+static int nixio_exec(lua_State *L) {
+ return nixio__exec(L, NIXIO_EXECV);
+}
- return nixio__pstatus(L, !setuid(uid));
+static int nixio_execp(lua_State *L) {
+ return nixio__exec(L, NIXIO_EXECVP);
}
-static int nixio_nice(lua_State *L) {
- int nval = luaL_checkint(L, 1);
+static int nixio_exece(lua_State *L) {
+ return nixio__exec(L, NIXIO_EXECVE);
+}
- errno = 0;
- nval = nice(nval);
+static int nixio_getcwd(lua_State *L) {
+ char path[PATH_MAX];
- if (nval == -1 && errno) {
- return nixio__perror(L);
- } else {
- lua_pushinteger(L, nval);
+ if (getcwd(path, sizeof(path))) {
+ lua_pushstring(L, path);
return 1;
+ } else {
+ return nixio__perror(L);
}
}
-static int nixio_setsid(lua_State *L) {
- pid_t pid = setsid();
+static int nixio_umask(lua_State *L) {
+ char mask[9];
+ lua_pushinteger(L,
+ nixio__mode_write(umask(nixio__check_mode(L, 1, -1)), mask));
+ lua_pushlstring(L, mask, 9);
+ return 2;
+}
- if (pid == -1) {
+#ifdef __linux__
+
+#include <sys/sysinfo.h>
+
+static int nixio_sysinfo(lua_State *L) {
+ struct sysinfo info;
+ if (sysinfo(&info)) {
return nixio__perror(L);
- } else {
- lua_pushinteger(L, pid);
- return 1;
}
-}
-static int nixio_chdir(lua_State *L) {
- return nixio__pstatus(L, !chdir(luaL_checkstring(L, 1)));
+ lua_createtable(L, 0, 12);
+
+ lua_pushnumber(L, info.bufferram);
+ lua_setfield(L, -2, "bufferram");
+
+ lua_pushnumber(L, info.freehigh);
+ lua_setfield(L, -2, "freehigh");
+
+ lua_pushnumber(L, info.freeram);
+ lua_setfield(L, -2, "freeram");
+
+ lua_pushnumber(L, info.freeswap);
+ lua_setfield(L, -2, "freeswap");
+
+ lua_createtable(L, 0, 3);
+ for (int i=0; i<3; i++) {
+ lua_pushnumber(L, info.loads[i] / 65536.);
+ lua_rawseti(L, -2, i+1);
+ }
+ lua_setfield(L, -2, "loads");
+
+ lua_pushnumber(L, info.mem_unit);
+ lua_setfield(L, -2, "mem_unit");
+
+ lua_pushnumber(L, info.procs);
+ lua_setfield(L, -2, "procs");
+
+ lua_pushnumber(L, info.sharedram);
+ lua_setfield(L, -2, "sharedram");
+
+ lua_pushnumber(L, info.totalhigh);
+ lua_setfield(L, -2, "totalhigh");
+
+ lua_pushnumber(L, info.totalram);
+ lua_setfield(L, -2, "totalram");
+
+ lua_pushnumber(L, info.totalswap);
+ lua_setfield(L, -2, "totalswap");
+
+ lua_pushnumber(L, info.uptime);
+ lua_setfield(L, -2, "uptime");
+
+ return 1;
}
+#endif
+
/* module table */
static const luaL_reg R[] = {
+#ifdef __linux__
+ {"sysinfo", nixio_sysinfo},
+#endif
+#ifndef __WINNT__
{"fork", nixio_fork},
- {"wait", nixio_wait},
{"kill", nixio_kill},
{"nice", nixio_nice},
- {"chdir", nixio_chdir},
- {"getpid", nixio_getpid},
{"getppid", nixio_getppid},
{"getuid", nixio_getuid},
{"getgid", nixio_getgid},
{"setuid", nixio_setuid},
{"setgid", nixio_setgid},
{"setsid", nixio_setsid},
+ {"wait", nixio_wait},
+ {"waitpid", nixio_wait},
+ {"times", nixio_times},
+ {"uname", nixio_uname},
+#endif
+ {"chdir", nixio_chdir},
{"signal", nixio_signal},
+ {"getpid", nixio_getpid},
+ {"getenv", nixio_getenv},
+ {"setenv", nixio_setenv},
+ {"putenv", nixio_setenv},
+ {"exec", nixio_exec},
+ {"execp", nixio_execp},
+ {"exece", nixio_exece},
+ {"getcwd", nixio_getcwd},
+ {"umask", nixio_umask},
{NULL, NULL}
};