1 | ␊ |
2 | #include "base.hh"␊ |
3 | #include "lua.hh"␊ |
4 | ␊ |
5 | #include <signal.h>␊ |
6 | #include <cstdlib>␊ |
7 | ␊ |
8 | #include "platform.hh"␊ |
9 | ␊ |
10 | using std::malloc;␊ |
11 | using std::free;␊ |
12 | ␊ |
13 | LUAEXT(get_ostype, )␊ |
14 | {␊ |
15 | std::string str;␊ |
16 | get_system_flavour(str);␊ |
17 | lua_pushstring(L, str.c_str());␊ |
18 | return 1;␊ |
19 | }␊ |
20 | ␊ |
21 | LUAEXT(existsonpath, )␊ |
22 | {␊ |
23 | const char *exe = luaL_checkstring(L, -1);␊ |
24 | lua_pushnumber(L, existsonpath(exe));␊ |
25 | return 1;␊ |
26 | }␊ |
27 | ␊ |
28 | LUAEXT(is_executable, )␊ |
29 | {␊ |
30 | const char *path = luaL_checkstring(L, -1);␊ |
31 | lua_pushboolean(L, is_executable(path));␊ |
32 | return 1;␊ |
33 | }␊ |
34 | ␊ |
35 | LUAEXT(make_executable, )␊ |
36 | {␊ |
37 | const char *path = luaL_checkstring(L, -1);␊ |
38 | lua_pushnumber(L, make_executable(path));␊ |
39 | return 1;␊ |
40 | }␊ |
41 | ␊ |
42 | LUAEXT(spawn, )␊ |
43 | {␊ |
44 | int n = lua_gettop(L);␊ |
45 | const char *path = luaL_checkstring(L, 1);␊ |
46 | char **argv = (char**)malloc((n+1)*sizeof(char*));␊ |
47 | int i;␊ |
48 | pid_t ret;␊ |
49 | if (argv==NULL)␊ |
50 | return 0;␊ |
51 | argv[0] = (char*)path;␊ |
52 | for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(L, i+1);␊ |
53 | argv[i] = NULL;␊ |
54 | ret = process_spawn(argv);␊ |
55 | free(argv);␊ |
56 | lua_pushnumber(L, ret);␊ |
57 | return 1;␊ |
58 | }␊ |
59 | ␊ |
60 | LUAEXT(spawn_redirected, )␊ |
61 | {␊ |
62 | int n = lua_gettop(L);␊ |
63 | char const * infile = luaL_checkstring(L, 1);␊ |
64 | char const * outfile = luaL_checkstring(L, 2);␊ |
65 | char const * errfile = luaL_checkstring(L, 3);␊ |
66 | const char *path = luaL_checkstring(L, 4);␊ |
67 | n -= 3;␊ |
68 | char **argv = (char**)malloc((n+1)*sizeof(char*));␊ |
69 | int i;␊ |
70 | pid_t ret;␊ |
71 | if (argv==NULL)␊ |
72 | return 0;␊ |
73 | argv[0] = (char*)path;␊ |
74 | for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(L, i+4);␊ |
75 | argv[i] = NULL;␊ |
76 | ret = process_spawn_redirected(infile, outfile, errfile, argv);␊ |
77 | free(argv);␊ |
78 | lua_pushnumber(L, ret);␊ |
79 | return 1;␊ |
80 | }␊ |
81 | ␊ |
82 | // borrowed from lua/liolib.cc␊ |
83 | // Note that making C functions that return FILE* in Lua is tricky␊ |
84 | // There is a Lua FAQ entitled:␊ |
85 | // "Why does my library-created file segfault on :close() but work otherwise?"␊ |
86 | ␊ |
87 | #define topfile(L)␉((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))␊ |
88 | ␊ |
89 | static int io_fclose (lua_State *L) {␊ |
90 | FILE **p = topfile(L);␊ |
91 | int ok = (fclose(*p) == 0);␊ |
92 | *p = NULL;␊ |
93 | lua_pushboolean(L, ok);␊ |
94 | return 1;␊ |
95 | }␊ |
96 | ␊ |
97 | static FILE **newfile (lua_State *L) {␊ |
98 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));␊ |
99 | *pf = NULL; /* file handle is currently `closed' */␊ |
100 | luaL_getmetatable(L, LUA_FILEHANDLE);␊ |
101 | lua_setmetatable(L, -2);␊ |
102 | ␊ |
103 | lua_pushcfunction(L, io_fclose);␊ |
104 | lua_setfield(L, LUA_ENVIRONINDEX, "__close");␊ |
105 | ␊ |
106 | return pf;␊ |
107 | }␊ |
108 | ␊ |
109 | LUAEXT(spawn_pipe, )␊ |
110 | {␊ |
111 | int n = lua_gettop(L);␊ |
112 | char **argv = (char**)malloc((n+1)*sizeof(char*));␊ |
113 | int i;␊ |
114 | pid_t pid;␊ |
115 | if (argv==NULL)␊ |
116 | return 0;␊ |
117 | if (n<1)␊ |
118 | return 0;␊ |
119 | for (i=0; i<n; i++) argv[i] = (char*)luaL_checkstring(L, i+1);␊ |
120 | argv[i] = NULL;␊ |
121 | ␊ |
122 | int infd;␊ |
123 | FILE **inpf = newfile(L);␊ |
124 | int outfd;␊ |
125 | FILE **outpf = newfile(L);␊ |
126 | ␊ |
127 | pid = process_spawn_pipe(argv, inpf, outpf);␊ |
128 | free(argv);␊ |
129 | ␊ |
130 | lua_pushnumber(L, pid);␊ |
131 | ␊ |
132 | return 3;␊ |
133 | }␊ |
134 | ␊ |
135 | LUAEXT(wait, )␊ |
136 | {␊ |
137 | pid_t pid = static_cast<pid_t>(luaL_checknumber(L, -1));␊ |
138 | int res;␊ |
139 | int ret;␊ |
140 | ret = process_wait(pid, &res);␊ |
141 | lua_pushnumber(L, res);␊ |
142 | lua_pushnumber(L, ret);␊ |
143 | return 2;␊ |
144 | }␊ |
145 | ␊ |
146 | LUAEXT(kill, )␊ |
147 | {␊ |
148 | int n = lua_gettop(L);␊ |
149 | pid_t pid = static_cast<pid_t>(luaL_checknumber(L, -2));␊ |
150 | int sig;␊ |
151 | if (n>1)␊ |
152 | sig = static_cast<int>(luaL_checknumber(L, -1));␊ |
153 | else␊ |
154 | sig = SIGTERM;␊ |
155 | lua_pushnumber(L, process_kill(pid, sig));␊ |
156 | return 1;␊ |
157 | }␊ |
158 | ␊ |
159 | LUAEXT(sleep, )␊ |
160 | {␊ |
161 | int seconds = static_cast<int>(luaL_checknumber(L, -1));␊ |
162 | lua_pushnumber(L, process_sleep(seconds));␊ |
163 | return 1;␊ |
164 | }␊ |
165 | ␊ |
166 | LUAEXT(get_pid, )␊ |
167 | {␊ |
168 | pid_t pid = get_process_id();␊ |
169 | lua_pushnumber(L, pid);␊ |
170 | return 1;␊ |
171 | }␊ |
172 | ␊ |
173 | // Local Variables:␊ |
174 | // mode: C++␊ |
175 | // fill-column: 76␊ |
176 | // c-file-style: "gnu"␊ |
177 | // indent-tabs-mode: nil␊ |
178 | // End:␊ |
179 | // vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:␊ |
180 | ␊ |