536acd7fffe5cbc7433ecaf717139c8d4f8f1dae
2 * nixio - Linux I/O library for lua
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 #include <sys/types.h>
28 #define NIXIO_EXECVE 0x01
29 #define NIXIO_EXECV 0x02
30 #define NIXIO_EXECVP 0x03
32 int nixio__exec(lua_State
*L
, int m
) {
33 const char *path
= luaL_checkstring(L
, 1);
37 if (m
== NIXIO_EXECVE
) {
38 luaL_checktype(L
, 2, LUA_TTABLE
);
39 argn
= lua_objlen(L
, 2) + 1;
44 char **args
= lua_newuserdata(L
, sizeof(char*) * (argn
+ 1));
46 args
[0] = (char *)path
;
48 if (m
== NIXIO_EXECVE
) {
49 for (i
= 1; i
< argn
; i
++) {
51 arg
= lua_tostring(L
, -1);
52 luaL_argcheck(L
, arg
, 2, "invalid argument");
53 args
[i
] = (char *)arg
;
56 if (lua_isnoneornil(L
, 3)) {
59 luaL_checktype(L
, 3, LUA_TTABLE
);
62 while (lua_next(L
, 3)) {
63 if (!lua_checkstack(L
, 1)) {
65 return luaL_error(L
, "stack overflow");
68 if (!lua_type(L
, -2) != LUA_TSTRING
|| !lua_isstring(L
, -1)) {
69 return luaL_argerror(L
, 3, "invalid environment");
72 lua_pushfstring(L
, "%s=%s",
73 lua_tostring(L
, -2), lua_tostring(L
, -1));
80 char **env
= lua_newuserdata(L
, sizeof(char*) * (argn
+ 1));
83 for (i
= 1; i
< argn
; i
++) {
84 env
[i
-1] = (char *)lua_tostring(L
, -i
);
87 execve(path
, args
, env
);
90 for (i
= 2; i
<= argn
; i
++) {
91 arg
= luaL_checkstring(L
, i
);
92 args
[i
-1] = (char *)arg
;
95 if (m
== NIXIO_EXECV
) {
102 return nixio__perror(L
);
106 #include <sys/utsname.h>
107 #include <sys/times.h>
108 #include <sys/wait.h>
112 static int nixio_fork(lua_State
*L
) {
115 return nixio__perror(L
);
117 lua_pushinteger(L
, pid
);
122 static int nixio_kill(lua_State
*L
) {
123 return nixio__pstatus(L
, !kill(luaL_checkint(L
, 1), luaL_checkint(L
, 2)));
126 static int nixio_getppid(lua_State
*L
) {
127 lua_pushinteger(L
, getppid());
131 static int nixio_getuid(lua_State
*L
) {
132 lua_pushinteger(L
, getuid());
136 static int nixio_getgid(lua_State
*L
) {
137 lua_pushinteger(L
, getgid());
141 static int nixio_setgid(lua_State
*L
) {
142 return nixio__pstatus(L
, !setgid(nixio__check_group(L
, 1)));
145 static int nixio_setuid(lua_State
*L
) {
146 return nixio__pstatus(L
, !setuid(nixio__check_user(L
, 1)));
149 static int nixio_nice(lua_State
*L
) {
150 int nval
= luaL_checkint(L
, 1);
155 if (nval
== -1 && errno
) {
156 return nixio__perror(L
);
158 lua_pushinteger(L
, nval
);
163 static int nixio_setsid(lua_State
*L
) {
164 pid_t pid
= setsid();
167 return nixio__perror(L
);
169 lua_pushinteger(L
, pid
);
174 static int nixio_wait(lua_State
*L
) {
175 pid_t pidin
= luaL_optinteger(L
, 1, -1), pidout
;
176 int options
= 0, status
;
178 const int j
= lua_gettop(L
);
179 for (int i
=2; i
<=j
; i
++) {
180 const char *flag
= luaL_checkstring(L
, i
);
181 if (!strcmp(flag
, "nohang")) {
183 } else if (!strcmp(flag
, "untraced")) {
184 options
|= WUNTRACED
;
185 } else if (!strcmp(flag
, "continued")) {
186 options
|= WCONTINUED
;
188 return luaL_argerror(L
, i
,
189 "supported values: nohang, untraced, continued");
194 pidout
= waitpid(pidin
, &status
, options
);
195 } while (pidout
== -1 && errno
== EINTR
);
198 lua_pushboolean(L
, 0);
200 } else if (pidout
== -1) {
201 return nixio__perror(L
);
203 lua_pushinteger(L
, pidout
);
206 if (WIFEXITED(status
)) {
207 lua_pushliteral(L
, "exited");
208 lua_pushinteger(L
, WEXITSTATUS(status
));
209 } else if (WIFSIGNALED(status
)) {
210 lua_pushliteral(L
, "signaled");
211 lua_pushinteger(L
, WTERMSIG(status
));
212 } else if (WIFSTOPPED(status
)) {
213 lua_pushliteral(L
, "stopped");
214 lua_pushinteger(L
, WSTOPSIG(status
));
222 static int nixio_times(lua_State
*L
) {
224 if (times(&buf
) == -1) {
225 return nixio__perror(L
);
227 lua_createtable(L
, 0, 4);
228 lua_pushinteger(L
, buf
.tms_cstime
);
229 lua_setfield(L
, -2, "cstime");
231 lua_pushinteger(L
, buf
.tms_cutime
);
232 lua_setfield(L
, -2, "cutime");
234 lua_pushinteger(L
, buf
.tms_stime
);
235 lua_setfield(L
, -2, "stime");
237 lua_pushinteger(L
, buf
.tms_utime
);
238 lua_setfield(L
, -2, "utime");
244 static int nixio_uname(lua_State
*L
) {
247 return nixio__perror(L
);
250 lua_createtable(L
, 0, 5);
252 lua_pushstring(L
, buf
.machine
);
253 lua_setfield(L
, -2, "machine");
255 lua_pushstring(L
, buf
.version
);
256 lua_setfield(L
, -2, "version");
258 lua_pushstring(L
, buf
.release
);
259 lua_setfield(L
, -2, "release");
261 lua_pushstring(L
, buf
.nodename
);
262 lua_setfield(L
, -2, "nodename");
264 lua_pushstring(L
, buf
.sysname
);
265 lua_setfield(L
, -2, "sysname");
270 #endif /* !__WINNT__ */
272 static int nixio_chdir(lua_State
*L
) {
273 return nixio__pstatus(L
, !chdir(luaL_checkstring(L
, 1)));
276 static int nixio_signal(lua_State
*L
) {
277 int sig
= luaL_checkinteger(L
, 1);
278 const char *val
= luaL_checkstring(L
, 2);
280 if (!strcmp(val
, "ign") || !strcmp(val
, "ignore")) {
281 return nixio__pstatus(L
, signal(sig
, SIG_IGN
) != SIG_ERR
);
282 } else if (!strcmp(val
, "dfl") || !strcmp(val
, "default")) {
283 return nixio__pstatus(L
, signal(sig
, SIG_DFL
) != SIG_ERR
);
285 return luaL_argerror(L
, 2, "supported values: ign, dfl");
289 static int nixio_getpid(lua_State
*L
) {
290 lua_pushinteger(L
, getpid());
294 static int nixio_getenv(lua_State
*L
) {
295 const char *key
= luaL_optstring(L
, 1, NULL
);
297 const char *val
= getenv(key
);
299 lua_pushstring(L
, val
);
305 extern char **environ
;
306 for (char **c
= environ
; *c
; c
++) {
307 const char *delim
= strchr(*c
, '=');
309 return luaL_error(L
, "invalid environment");
311 lua_pushlstring(L
, *c
, delim
-*c
);
312 lua_pushstring(L
, delim
+ 1);
319 static int nixio_setenv(lua_State
*L
) {
320 const char *key
= luaL_checkstring(L
, 1);
321 const char *val
= luaL_optstring(L
, 2, NULL
);
322 return nixio__pstatus(L
, (val
) ? !setenv(key
, val
, 1) : !unsetenv(key
));
325 static int nixio_exec(lua_State
*L
) {
326 return nixio__exec(L
, NIXIO_EXECV
);
329 static int nixio_execp(lua_State
*L
) {
330 return nixio__exec(L
, NIXIO_EXECVP
);
333 static int nixio_exece(lua_State
*L
) {
334 return nixio__exec(L
, NIXIO_EXECVE
);
337 static int nixio_getcwd(lua_State
*L
) {
340 if (getcwd(path
, sizeof(path
))) {
341 lua_pushstring(L
, path
);
344 return nixio__perror(L
);
348 static int nixio_umask(lua_State
*L
) {
351 nixio__mode_write(umask(nixio__check_mode(L
, 1, -1)), mask
));
352 lua_pushlstring(L
, mask
, 9);
358 #include <sys/sysinfo.h>
360 static int nixio_sysinfo(lua_State
*L
) {
362 if (sysinfo(&info
)) {
363 return nixio__perror(L
);
366 lua_createtable(L
, 0, 12);
368 lua_pushinteger(L
, info
.bufferram
);
369 lua_setfield(L
, -2, "bufferram");
371 lua_pushinteger(L
, info
.freehigh
);
372 lua_setfield(L
, -2, "freehigh");
374 lua_pushinteger(L
, info
.freeram
);
375 lua_setfield(L
, -2, "freeram");
377 lua_pushinteger(L
, info
.freeswap
);
378 lua_setfield(L
, -2, "freeswap");
380 lua_createtable(L
, 0, 3);
381 for (int i
=0; i
<3; i
++) {
382 lua_pushinteger(L
, info
.loads
[i
] / 65536.);
383 lua_rawseti(L
, -2, i
+1);
385 lua_setfield(L
, -2, "loads");
387 lua_pushinteger(L
, info
.mem_unit
);
388 lua_setfield(L
, -2, "mem_unit");
390 lua_pushinteger(L
, info
.procs
);
391 lua_setfield(L
, -2, "procs");
393 lua_pushinteger(L
, info
.sharedram
);
394 lua_setfield(L
, -2, "sharedram");
396 lua_pushinteger(L
, info
.totalhigh
);
397 lua_setfield(L
, -2, "totalhigh");
399 lua_pushinteger(L
, info
.totalram
);
400 lua_setfield(L
, -2, "totalram");
402 lua_pushinteger(L
, info
.totalswap
);
403 lua_setfield(L
, -2, "totalswap");
405 lua_pushinteger(L
, info
.uptime
);
406 lua_setfield(L
, -2, "uptime");
415 static const luaL_reg R
[] = {
417 {"sysinfo", nixio_sysinfo
},
420 {"fork", nixio_fork
},
421 {"kill", nixio_kill
},
422 {"nice", nixio_nice
},
423 {"getppid", nixio_getppid
},
424 {"getuid", nixio_getuid
},
425 {"getgid", nixio_getgid
},
426 {"setuid", nixio_setuid
},
427 {"setgid", nixio_setgid
},
428 {"setsid", nixio_setsid
},
429 {"wait", nixio_wait
},
430 {"waitpid", nixio_wait
},
431 {"times", nixio_times
},
432 {"uname", nixio_uname
},
434 {"chdir", nixio_chdir
},
435 {"signal", nixio_signal
},
436 {"getpid", nixio_getpid
},
437 {"getenv", nixio_getenv
},
438 {"setenv", nixio_setenv
},
439 {"putenv", nixio_setenv
},
440 {"exec", nixio_exec
},
441 {"execp", nixio_execp
},
442 {"exece", nixio_exece
},
443 {"getcwd", nixio_getcwd
},
444 {"umask", nixio_umask
},
448 void nixio_open_process(lua_State
*L
) {
449 luaL_register(L
, NULL
, R
);