diff options
Diffstat (limited to 'util-src/pposix.c')
-rw-r--r-- | util-src/pposix.c | 202 |
1 files changed, 148 insertions, 54 deletions
diff --git a/util-src/pposix.c b/util-src/pposix.c index a8e0720f..502e5326 100644 --- a/util-src/pposix.c +++ b/util-src/pposix.c @@ -13,7 +13,7 @@ * POSIX support functions for Lua */ -#define MODULE_VERSION "0.4.0" +#define MODULE_VERSION "0.4.1" #if defined(__linux__) @@ -58,9 +58,6 @@ #include "lualib.h" #include "lauxlib.h" -#if (LUA_VERSION_NUM == 501) -#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R) -#endif #if (LUA_VERSION_NUM < 503) #define lua_isinteger(L, n) lua_isnumber(L, n) #endif @@ -510,55 +507,43 @@ static int lc_mkdir(lua_State *L) { * Example usage: * pposix.setrlimit("NOFILE", 1000, 2000) */ -static int string2resource(const char *s) { - if(!strcmp(s, "CORE")) { - return RLIMIT_CORE; - } - - if(!strcmp(s, "CPU")) { - return RLIMIT_CPU; - } - - if(!strcmp(s, "DATA")) { - return RLIMIT_DATA; - } - - if(!strcmp(s, "FSIZE")) { - return RLIMIT_FSIZE; - } - - if(!strcmp(s, "NOFILE")) { - return RLIMIT_NOFILE; - } - - if(!strcmp(s, "STACK")) { - return RLIMIT_STACK; - } +static const char *const resource_strings[] = { + /* Defined by POSIX */ + "CORE", + "CPU", + "DATA", + "FSIZE", + "NOFILE", + "STACK", #if !(defined(sun) || defined(__sun) || defined(__APPLE__)) - - if(!strcmp(s, "MEMLOCK")) { - return RLIMIT_MEMLOCK; - } - - if(!strcmp(s, "NPROC")) { - return RLIMIT_NPROC; - } - - if(!strcmp(s, "RSS")) { - return RLIMIT_RSS; - } - + "MEMLOCK", + "NPROC", + "RSS", #endif #ifdef RLIMIT_NICE + "NICE", +#endif + NULL +}; - if(!strcmp(s, "NICE")) { - return RLIMIT_NICE; - } - +static int resource_constants[] = { + RLIMIT_CORE, + RLIMIT_CPU, + RLIMIT_DATA, + RLIMIT_FSIZE, + RLIMIT_NOFILE, + RLIMIT_STACK, +#if !(defined(sun) || defined(__sun) || defined(__APPLE__)) + RLIMIT_MEMLOCK, + RLIMIT_NPROC, + RLIMIT_RSS, #endif - return -1; -} +#ifdef RLIMIT_NICE + RLIMIT_NICE, +#endif + -1, +}; static rlim_t arg_to_rlimit(lua_State *L, int idx, rlim_t current) { switch(lua_type(L, idx)) { @@ -592,7 +577,7 @@ static int lc_setrlimit(lua_State *L) { return 2; } - rid = string2resource(luaL_checkstring(L, 1)); + rid = resource_constants[luaL_checkoption(L, 1,NULL, resource_strings)]; if(rid == -1) { lua_pushboolean(L, 0); @@ -622,7 +607,6 @@ static int lc_setrlimit(lua_State *L) { static int lc_getrlimit(lua_State *L) { int arguments = lua_gettop(L); - const char *resource = NULL; int rid = -1; struct rlimit lim; @@ -632,8 +616,7 @@ static int lc_getrlimit(lua_State *L) { return 2; } - resource = luaL_checkstring(L, 1); - rid = string2resource(resource); + rid = resource_constants[luaL_checkoption(L, 1, NULL, resource_strings)]; if(rid != -1) { if(getrlimit(rid, &lim)) { @@ -671,6 +654,77 @@ static int lc_abort(lua_State *L) { return 0; } +const char *pipe_flag_names[] = { + "cloexec", + "direct", + "nonblock" +}; +const int pipe_flag_values[] = { + O_CLOEXEC, + O_DIRECT, + O_NONBLOCK +}; + + +static int lc_pipe(lua_State *L) { + int fds[2]; + int nflags = lua_gettop(L); + +#if defined(__linux__) + int flags=0; + for(int i = 1; i<=nflags; i++) { + int flag_index = luaL_checkoption(L, i, NULL, pipe_flag_names); + flags |= pipe_flag_values[flag_index]; + } + + if(pipe2(fds, flags) == -1) { +#else + if(nflags != 0) { + luaL_argerror(L, 1, "Flags are not supported on this platform"); + } + if(pipe(fds) == -1) { +#endif + luaL_pushfail(L); + lua_pushstring(L, strerror(errno)); + return 2; + } + + lua_pushinteger(L, fds[0]); + lua_pushinteger(L, fds[1]); + return 2; +} + +/* This helper function is adapted from Lua 5.3's liolib.c */ +static int stdio_fclose (lua_State *L) { + int res = -1; + luaL_Stream *p = ((luaL_Stream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)); + if (p->f == NULL) { + return 0; + } + res = fclose(p->f); + p->f = NULL; + return luaL_fileresult(L, (res == 0), NULL); +} + +static int lc_fdopen(lua_State *L) { + int fd = luaL_checkinteger(L, 1); + const char *mode = luaL_checkstring(L, 2); + + luaL_Stream *file = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream)); + file->closef = stdio_fclose; + file->f = fdopen(fd, mode); + + if (!file->f) { + luaL_pushfail(L); + lua_pushstring(L, strerror(errno)); + return 2; + } + + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return 1; +} + static int lc_uname(lua_State *L) { struct utsname uname_info; @@ -819,6 +873,41 @@ static int lc_atomic_append(lua_State *L) { return 3; } +static int lc_remove_blocks(lua_State *L) { +#if defined(__linux__) + int err; + + FILE *f = *(FILE **) luaL_checkudata(L, 1, LUA_FILEHANDLE); + off_t offset = (off_t)luaL_checkinteger(L, 2); + off_t length = (off_t)luaL_checkinteger(L, 3); + + errno = 0; + + if((err = fallocate(fileno(f), FALLOC_FL_COLLAPSE_RANGE, offset, length))) { + if(errno != 0) { + /* Some old versions of Linux apparently use the return value instead of errno */ + err = errno; + } + + switch(err) { + default: /* Other issues */ + luaL_pushfail(L); + lua_pushstring(L, strerror(err)); + lua_pushinteger(L, err); + return 3; + } + } + + lua_pushboolean(L, err == 0); + return 1; +#else + luaL_pushfail(L); + lua_pushstring(L, strerror(EOPNOTSUPP)); + lua_pushinteger(L, EOPNOTSUPP); + return 3; +#endif +} + static int lc_isatty(lua_State *L) { FILE *f = *(FILE **) luaL_checkudata(L, 1, LUA_FILEHANDLE); const int fd = fileno(f); @@ -828,10 +917,8 @@ static int lc_isatty(lua_State *L) { /* Register functions */ -int luaopen_util_pposix(lua_State *L) { -#if (LUA_VERSION_NUM > 501) +int luaopen_prosody_util_pposix(lua_State *L) { luaL_checkversion(L); -#endif luaL_Reg exports[] = { { "abort", lc_abort }, @@ -854,6 +941,9 @@ int luaopen_util_pposix(lua_State *L) { { "mkdir", lc_mkdir }, + { "pipe", lc_pipe }, + { "fdopen", lc_fdopen }, + { "setrlimit", lc_setrlimit }, { "getrlimit", lc_getrlimit }, @@ -866,6 +956,7 @@ int luaopen_util_pposix(lua_State *L) { #endif { "atomic_append", lc_atomic_append }, + { "remove_blocks", lc_remove_blocks }, { "isatty", lc_isatty }, @@ -888,3 +979,6 @@ int luaopen_util_pposix(lua_State *L) { return 1; } +int luaopen_util_pposix(lua_State *L) { + return luaopen_prosody_util_pposix(L); +} |