aboutsummaryrefslogtreecommitdiffstats
path: root/util-src/pposix.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-src/pposix.c')
-rw-r--r--util-src/pposix.c202
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);
+}