/* ** Lua eXtended system library */ #define lxsyslib_c #define LUA_LIB #include #include #include #include #include #include #include #include #include #include "lxlib.h" static int sys_dbg_print(lua_State *L) { const char *str = luaL_checkstring(L, 1); sc_dbg_print(str); return 0; } static int sys_yield(lua_State *L) { sc_yield(); return 0; } static int sys_exit(lua_State *L) { int code = luaL_checkinteger(L, 1); sc_exit(code); return 0; } static int sys_usleep(lua_State *L) { int usecs = luaL_checkinteger(L, 1); sc_usleep(usecs); return 0; } /* Missing syscalls : - sys_new_thread, exit_thread -> into specific threading library - mmap, mmap_file, mchmap, munmap -> into specific memory-related library ?? - ioctl, fctl -> into ioctl library */ static int sys_create(lua_State *L) { const char *name = luaL_checkstring(L, 1); int type = luaL_checkinteger(L, 2); lua_pushboolean(L, sc_create(name, type)); return 1; } static int sys_delete(lua_State *L) { const char *name = luaL_checkstring(L, 1); lua_pushboolean(L, sc_delete(name)); return 1; } static int sys_move(lua_State *L) { const char *oldname = luaL_checkstring(L, 1); const char *newname = luaL_checkstring(L, 2); lua_pushboolean(L, sc_move(oldname, newname)); return 1; } static int sys_stat(lua_State *L) { const char* name = luaL_checkstring(L, 1); stat_t s; if (sc_stat(name, &s)) { lua_createtable(L, 0, 3); setintfield(L, "type", s.type); setintfield(L, "access", s.access); setintfield(L, "size", s.size); } else { lua_pushnil(L); } return 1; } static int sys_open(lua_State *L) { const char* name = luaL_checkstring(L, 1); int mode = luaL_checkinteger(L, 2); fd_t fh = sc_open(name, mode); if (fh) { lua_pushinteger(L, fh); } else { lua_pushnil(L); } return 1; } static int sys_close(lua_State *L) { int fd = luaL_checkinteger(L, 1); sc_close(fd); return 0; } static int sys_read(lua_State *L) { int fd = luaL_checkinteger(L, 1); int offset = luaL_checkinteger(L, 2); int len = luaL_checkinteger(L, 3); luaL_Buffer b; char* bufptr = luaL_buffinitsize(L, &b, len); int ret = sc_read(fd, offset, len, bufptr); luaL_pushresultsize(&b, ret); lua_pushinteger(L, ret); return 2; } static int sys_write(lua_State *L) { int fd = luaL_checkinteger(L, 1); int offset = luaL_checkinteger(L, 2); const char* str = luaL_checkstring(L, 3); int len = luaL_len(L, 3); int ret = sc_write(fd, offset, len, str); lua_pushinteger(L, ret); return 1; } static int sys_readdir(lua_State *L) { int fd = luaL_checkinteger(L, 1); int ent_no = luaL_checkinteger(L, 2); dirent_t d; bool ret = sc_readdir(fd, ent_no, &d); if (ret) { lua_createtable(L, 0, 4); setstrfield(L, "name", d.name); setintfield(L, "type", d.st.type); setintfield(L, "access", d.st.access); setintfield(L, "size", d.st.size); } else { lua_pushnil(L); } return 1; } static int sys_stat_open(lua_State *L) { int fd = luaL_checkinteger(L, 1); stat_t s; if (sc_stat_open(fd, &s)) { lua_createtable(L, 0, 3); setintfield(L, "type", s.type); setintfield(L, "access", s.access); setintfield(L, "size", s.size); } else { lua_pushnil(L); } return 1; } static int sys_select(lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); int nfds = luaL_len(L, 1); int timeout = luaL_checkinteger(L, 2); sel_fd_t *fds = (sel_fd_t*)malloc(nfds*sizeof(sel_fd_t)); if (fds == NULL) luaL_error(L, "Out of memory, could not allocate %d sel_fd_t", nfds); for (int i = 0; i < nfds; i++) { lua_rawgeti(L, 1, i+1); luaL_checktype(L, -1, LUA_TTABLE); lua_rawgeti(L, -1, 1); fds[i].fd = luaL_checkinteger(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); fds[i].req_flags = luaL_checkinteger(L, -1); lua_pop(L, 2); } bool result = sc_select(fds, nfds, timeout); for (int i = 0; i < nfds; i++) { lua_rawgeti(L, 1, i+1); lua_pushinteger(L, fds[i].got_flags); lua_rawseti(L, -2, 3); lua_pop(L, 1); } free(fds); lua_pushboolean(L, result); return 1; } static int sys_make_channel(lua_State *L) { bool blocking = lx_checkboolean(L, 1); fd_pair_t pair = sc_make_channel(blocking); lua_pushinteger(L, pair.a); lua_pushinteger(L, pair.b); return 2; } static int sys_make_shm(lua_State *L) { int size = luaL_checkinteger(L, 1); int fd = sc_make_shm(size); if (fd) { lua_pushinteger(L, fd); } else { lua_pushnil(L); } return 1; } static int sys_gen_token(lua_State *L) { int fd = luaL_checkinteger(L, 1); token_t t; if (sc_gen_token(fd, &t)) { lua_pushlstring(L, t.bytes, TOKEN_LENGTH); } else { lua_pushnil(L); } return 1; } static int sys_use_token(lua_State *L) { const char* tok = luaL_checkstring(L, 1); if (!(luaL_len(L, 1) == TOKEN_LENGTH)) { luaL_argerror(L, 1, "invalid token length"); } token_t t; memcpy(t.bytes, tok, TOKEN_LENGTH); fd_t f = sc_use_token(&t); if (f) { lua_pushinteger(L, f); } else { lua_pushnil(L); } return 1; } static int sys_make_fs(lua_State *L) { const char* name = luaL_checkstring(L, 1); const char* driver = luaL_checkstring(L, 2); int source = luaL_checkinteger(L, 3); const char* options = luaL_checkstring(L, 4); lua_pushboolean(L, sc_make_fs(name, driver, source, options)); return 1; } static int sys_fs_add_source(lua_State *L) { const char* fs = luaL_checkstring(L, 1); int source = luaL_checkinteger(L, 2); const char* options = luaL_checkstring(L, 3); lua_pushboolean(L, sc_fs_add_source(fs, source, options)); return 1; } static int sys_fs_subfs(lua_State *L) { const char* name = luaL_checkstring(L, 1); const char* orig_fs = luaL_checkstring(L, 2); const char* root = luaL_checkstring(L, 3); int ok_modes = luaL_checkinteger(L, 4); lua_pushboolean(L, sc_fs_subfs(name, orig_fs, root, ok_modes)); return 1; } static int sys_fs_remove(lua_State *L) { const char* name = luaL_checkstring(L, 1); sc_fs_remove(name); return 0; } static int sys_new_proc(lua_State *L) { lua_pushinteger(L, sc_new_proc()); return 1; } static int sys_bind_fs(lua_State *L) { int pid = luaL_checkinteger(L, 1); const char* new_name = luaL_checkstring(L, 2); const char* name = luaL_checkstring(L, 3); lua_pushboolean(L, sc_bind_fs(pid, new_name, name)); return 1; } static int sys_bind_subfs(lua_State *L) { int pid = luaL_checkinteger(L, 1); const char* new_name = luaL_checkstring(L, 2); const char* fs = luaL_checkstring(L, 3); const char* root = luaL_checkstring(L, 4); int ok_modes = luaL_checkinteger(L, 5); lua_pushboolean(L, sc_bind_subfs(pid, new_name, fs, root, ok_modes)); return 1; } static int sys_bind_make_fs(lua_State *L) { int pid = luaL_checkinteger(L, 1); const char* new_name = luaL_checkstring(L, 2); const char* driver = luaL_checkstring(L, 3); fd_t source = luaL_checkinteger(L, 4); const char* options = luaL_checkstring(L, 5); lua_pushboolean(L, sc_bind_make_fs(pid, new_name, driver, source, options)); return 1; } static int sys_bind_fd(lua_State *L) { int pid = luaL_checkinteger(L, 1); int new_fd = luaL_checkinteger(L, 2); int fd = luaL_checkinteger(L, 3); lua_pushboolean(L, sc_bind_fd(pid, new_fd, fd)); return 1; } static int sys_proc_exec(lua_State *L) { int pid = luaL_checkinteger(L, 1); const char *name = luaL_checkstring(L, 2); lua_pushboolean(L, sc_proc_exec(pid, name)); return 1; } static int sys_proc_status(lua_State *L) { int pid = luaL_checkinteger(L, 1); proc_status_t s; if (sc_proc_status(pid, &s)) { lua_createtable(L, 0, 3); setintfield(L, "pid", s.pid); setintfield(L, "status",s.status); setintfield(L, "exit_code", s.exit_code); } else { lua_pushnil(L); } return 1; } static int sys_proc_kill(lua_State *L) { int pid = luaL_checkinteger(L, 1); proc_status_t s; if (sc_proc_kill(pid, &s)) { lua_createtable(L, 0, 3); setintfield(L, "pid", s.pid); setintfield(L, "status",s.status); setintfield(L, "exit_code", s.exit_code); } else { lua_pushnil(L); } return 1; } static int sys_proc_wait(lua_State *L) { int pid = luaL_checkinteger(L, 1); bool wait = lx_checkboolean(L, 2); proc_status_t s; sc_proc_wait(pid, wait, &s); lua_createtable(L, 0, 3); setintfield(L, "pid", s.pid); setintfield(L, "status",s.status); setintfield(L, "exit_code", s.exit_code); return 1; } /* }====================================================== */ static const luaL_Reg syslib[] = { {"dbg_print", sys_dbg_print}, {"yield", sys_yield}, {"exit", sys_exit}, {"usleep", sys_usleep}, {"create", sys_create}, {"delete", sys_delete}, {"move", sys_move}, {"stat", sys_stat}, {"open", sys_open}, {"close", sys_close}, {"read", sys_read}, {"write", sys_write}, {"readdir", sys_readdir}, {"stat_open", sys_stat_open}, {"select", sys_select}, {"make_channel",sys_make_channel}, {"make_shm", sys_make_shm}, {"gen_token", sys_gen_token}, {"use_token", sys_use_token}, {"make_fs", sys_make_fs}, {"fs_add_source",sys_fs_add_source}, {"fs_subfs", sys_fs_subfs}, {"fs_remove", sys_fs_remove}, {"new_proc", sys_new_proc}, {"bind_fs", sys_bind_fs}, {"bind_subfs",sys_bind_subfs}, {"bind_make_fs",sys_bind_make_fs}, {"bind_fd", sys_bind_fd}, {"proc_exec", sys_proc_exec}, {"proc_status",sys_proc_status}, {"proc_kill", sys_proc_kill}, {"proc_wait", sys_proc_wait}, {NULL, NULL} }; LUAMOD_API int lx_open_sys (lua_State *L) { luaL_newlib(L, syslib); return 1; } /* vim: set sts=2 ts=2 sw=2 tw=0 et :*/