monotone

monotone Mtn Source Tree

Root/src/luaext_platform.cc

1// Copyright (C) 2006 Timothy Brownawell <tbrownaw@gmail.com>
2//
3// This program is made available under the GNU GPL version 2.0 or
4// greater. See the accompanying file COPYING for details.
5//
6// This program is distributed WITHOUT ANY WARRANTY; without even the
7// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8// PURPOSE.
9
10#include "base.hh"
11#include "lua.hh"
12
13#include <signal.h>
14#include <cstdlib>
15
16#include "platform.hh"
17#include "sanity.hh"
18
19using std::string;
20using std::malloc;
21using std::free;
22
23LUAEXT(get_ostype, )
24{
25 std::string str;
26 get_system_flavour(str);
27 lua_pushstring(LS, str.c_str());
28 return 1;
29}
30
31LUAEXT(existsonpath, )
32{
33 const char *exe = luaL_checkstring(LS, -1);
34 lua_pushnumber(LS, existsonpath(exe));
35 return 1;
36}
37
38LUAEXT(is_executable, )
39{
40 const char *path = luaL_checkstring(LS, -1);
41 lua_pushboolean(LS, is_executable(path));
42 return 1;
43}
44
45LUAEXT(set_executable, )
46{
47 const char *path = luaL_checkstring(LS, -1);
48 lua_pushnumber(LS, set_executable(path));
49 return 1;
50}
51
52LUAEXT(clear_executable, )
53{
54 const char *path = luaL_checkstring(LS, -1);
55 lua_pushnumber(LS, clear_executable(path));
56 return 1;
57}
58
59LUAEXT(spawn, )
60{
61 int n = lua_gettop(LS);
62 const char *path = luaL_checkstring(LS, 1);
63 char **argv = (char**)malloc((n+1)*sizeof(char*));
64 int i;
65 pid_t ret;
66 if (argv==NULL)
67 return 0;
68 argv[0] = (char*)path;
69 for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(LS, i+1);
70 argv[i] = NULL;
71 ret = process_spawn(argv);
72 free(argv);
73 lua_pushnumber(LS, ret);
74 return 1;
75}
76
77LUAEXT(spawn_redirected, )
78{
79 int n = lua_gettop(LS);
80 char const * infile = luaL_checkstring(LS, 1);
81 char const * outfile = luaL_checkstring(LS, 2);
82 char const * errfile = luaL_checkstring(LS, 3);
83 const char *path = luaL_checkstring(LS, 4);
84 n -= 3;
85 char **argv = (char**)malloc((n+1)*sizeof(char*));
86 int i;
87 pid_t ret;
88 if (argv==NULL)
89 return 0;
90 argv[0] = (char*)path;
91 for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(LS, i+4);
92 argv[i] = NULL;
93 ret = process_spawn_redirected(infile, outfile, errfile, argv);
94 free(argv);
95 lua_pushnumber(LS, ret);
96 return 1;
97}
98
99// borrowed from lua/liolib.cc
100// Note that making C functions that return FILE* in Lua is tricky
101// There is a Lua FAQ entitled:
102// "Why does my library-created file segfault on :close() but work otherwise?"
103
104#define topfile(LS) ((FILE **)luaL_checkudata(LS, 1, LUA_FILEHANDLE))
105
106static int io_fclose (lua_State *LS) {
107 FILE **p = topfile(LS);
108 int ok = (fclose(*p) == 0);
109 *p = NULL;
110 lua_pushboolean(LS, ok);
111 return 1;
112}
113
114static FILE **newfile (lua_State *LS) {
115 FILE **pf = (FILE **)lua_newuserdata(LS, sizeof(FILE *));
116 *pf = NULL; /* file handle is currently `closed' */
117 luaL_getmetatable(LS, LUA_FILEHANDLE);
118 lua_setmetatable(LS, -2);
119
120 lua_pushcfunction(LS, io_fclose);
121#ifdef LUA_ENVIRONINDEX
122 // Lua 5.2 removes C function environments
123 lua_setfield(LS, LUA_ENVIRONINDEX, "__close");
124#endif
125
126 return pf;
127}
128
129LUAEXT(spawn_pipe, )
130{
131 int n = lua_gettop(LS);
132 char **argv = (char**)malloc((n+1)*sizeof(char*));
133 int i;
134 pid_t pid;
135 if (argv==NULL)
136 return 0;
137 if (n<1)
138 return 0;
139 for (i=0; i<n; i++) argv[i] = (char*)luaL_checkstring(LS, i+1);
140 argv[i] = NULL;
141
142 int infd;
143 FILE **inpf = newfile(LS);
144 int outfd;
145 FILE **outpf = newfile(LS);
146
147 pid = process_spawn_pipe(argv, inpf, outpf);
148 free(argv);
149
150 lua_pushnumber(LS, pid);
151
152 return 3;
153}
154
155LUAEXT(wait, )
156{
157 pid_t pid = static_cast<pid_t>(luaL_checknumber(LS, -1));
158 int res;
159 int ret;
160 ret = process_wait(pid, &res);
161 lua_pushnumber(LS, res);
162 lua_pushnumber(LS, ret);
163 return 2;
164}
165
166LUAEXT(kill, )
167{
168 int n = lua_gettop(LS);
169 pid_t pid = static_cast<pid_t>(luaL_checknumber(LS, -2));
170 int sig;
171 if (n>1)
172 sig = static_cast<int>(luaL_checknumber(LS, -1));
173 else
174 sig = SIGTERM;
175 lua_pushnumber(LS, process_kill(pid, sig));
176 return 1;
177}
178
179LUAEXT(sleep, )
180{
181 int seconds = static_cast<int>(luaL_checknumber(LS, -1));
182 lua_pushnumber(LS, process_sleep(seconds));
183 return 1;
184}
185
186LUAEXT(get_pid, )
187{
188 pid_t pid = get_process_id();
189 lua_pushnumber(LS, pid);
190 return 1;
191}
192
193// fs extensions
194
195LUAEXT(mkdir, )
196{
197 try
198 {
199 char const * dirname = luaL_checkstring(LS, -1);
200 do_mkdir(dirname);
201 lua_pushboolean(LS, true);
202 return 1;
203 }
204 catch(recoverable_failure & e)
205 {
206 lua_pushnil(LS);
207 return 1;
208 }
209}
210
211LUAEXT(exists, )
212{
213 try
214 {
215 char const * name = luaL_checkstring(LS, -1);
216 switch (get_path_status(name))
217 {
218 case path::nonexistent: lua_pushboolean(LS, false); break;
219 case path::file:
220 case path::directory: lua_pushboolean(LS, true); break;
221 }
222 }
223 catch(recoverable_failure & e)
224 {
225 lua_pushnil(LS);
226 }
227 return 1;
228}
229
230LUAEXT(isdir, )
231{
232 try
233 {
234 char const * name = luaL_checkstring(LS, -1);
235 switch (get_path_status(name))
236 {
237 case path::nonexistent:
238 case path::file: lua_pushboolean(LS, false); break;
239 case path::directory: lua_pushboolean(LS, true); break;
240 }
241 }
242 catch(recoverable_failure & e)
243 {
244 lua_pushnil(LS);
245 }
246 return 1;
247}
248
249namespace
250{
251 struct build_table : public dirent_consumer
252 {
253 build_table(lua_State * st) : st(st), n(1)
254 {
255 lua_newtable(st);
256 }
257 virtual void consume(const char *s)
258 {
259 lua_pushstring(st, s);
260 lua_rawseti(st, -2, n);
261 n++;
262 }
263 private:
264 lua_State * st;
265 unsigned int n;
266 };
267}
268
269LUAEXT(read_directory, )
270{
271 int top = lua_gettop(LS);
272 try
273 {
274 string path(luaL_checkstring(LS, -1));
275 build_table tbl(LS);
276
277 read_directory(path, tbl, tbl, tbl);
278 }
279 catch(recoverable_failure &)
280 {
281 // discard the table and any pending path element
282 lua_settop(LS, top);
283 lua_pushnil(LS);
284 }
285 catch (...)
286 {
287 lua_settop(LS, top);
288 throw;
289 }
290 return 1;
291}
292
293// Local Variables:
294// mode: C++
295// fill-column: 76
296// c-file-style: "gnu"
297// indent-tabs-mode: nil
298// End:
299// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status