aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2024-11-20 12:08:59 +0000
committerMatthew Wild <mwild1@gmail.com>2024-11-20 12:08:59 +0000
commita3b71e8fc944f65861f2d0123bf0c6497e61b31c (patch)
treefe4ed04a10b4a51b40ba13133d7c2fc38efc8d4f
parent19429a5e7de3fb70b50c56b060b97a6ff4cc5e30 (diff)
downloadprosody-a3b71e8fc944f65861f2d0123bf0c6497e61b31c.tar.gz
prosody-a3b71e8fc944f65861f2d0123bf0c6497e61b31c.zip
util.pposix: Add fdopen() to return a Lua file object from an fdHEADorigin/mastermaster
Now we can, for example, read/write pipes using Lua's standard I/O routines.
-rw-r--r--util-src/pposix.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/util-src/pposix.c b/util-src/pposix.c
index 23afd7b1..502e5326 100644
--- a/util-src/pposix.c
+++ b/util-src/pposix.c
@@ -694,6 +694,37 @@ static int lc_pipe(lua_State *L) {
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;
@@ -911,6 +942,7 @@ int luaopen_prosody_util_pposix(lua_State *L) {
{ "mkdir", lc_mkdir },
{ "pipe", lc_pipe },
+ { "fdopen", lc_fdopen },
{ "setrlimit", lc_setrlimit },
{ "getrlimit", lc_getrlimit },