nixio:
[project/luci.git] / libs / nixio / src / process.c
1 /*
2 * nixio - Linux I/O library for lua
3 *
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include "nixio.h"
20 #include <unistd.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <sys/wait.h>
24
25 static int nixio_fork(lua_State *L) {
26 pid_t pid = fork();
27 if (pid == -1) {
28 return nixio__perror(L);
29 } else {
30 lua_pushinteger(L, pid);
31 return 1;
32 }
33 }
34
35 static int nixio_wait(lua_State *L) {
36 pid_t pidin = luaL_optinteger(L, 1, -1), pidout;
37 int options = 0, status;
38
39 const int j = lua_gettop(L);
40 for (int i=2; i<=j; i++) {
41 const char *flag = luaL_checkstring(L, i);
42 if (!strcmp(flag, "nohang")) {
43 options |= WNOHANG;
44 } else if (!strcmp(flag, "untraced")) {
45 options |= WUNTRACED;
46 } else if (!strcmp(flag, "continued")) {
47 options |= WCONTINUED;
48 } else {
49 return luaL_argerror(L, i,
50 "supported values: nohang, untraced, continued");
51 }
52 }
53
54 do {
55 pidout = waitpid(pidin, &status, options);
56 } while (pidout == -1 && errno == EINTR);
57
58 if (pidout == -1) {
59 return nixio__perror(L);
60 } else {
61 lua_pushinteger(L, pidout);
62 }
63
64 if (WIFEXITED(status)) {
65 lua_pushliteral(L, "exited");
66 lua_pushinteger(L, WEXITSTATUS(status));
67 } else if (WIFSIGNALED(status)) {
68 lua_pushliteral(L, "signaled");
69 lua_pushinteger(L, WTERMSIG(status));
70 } else if (WIFSTOPPED(status)) {
71 lua_pushliteral(L, "stopped");
72 lua_pushinteger(L, WSTOPSIG(status));
73 } else {
74 return 1;
75 }
76
77 return 3;
78 }
79
80 static int nixio_kill(lua_State *L) {
81 return nixio__pstatus(L, !kill(luaL_checkint(L, 1), luaL_checkint(L, 2)));
82 }
83
84
85 /* module table */
86 static const luaL_reg R[] = {
87 {"fork", nixio_fork},
88 {"wait", nixio_wait},
89 {"kill", nixio_kill},
90 {NULL, NULL}
91 };
92
93 void nixio_open_process(lua_State *L) {
94 luaL_register(L, NULL, R);
95 }