diff options
author | Matthew Wild <mwild1@gmail.com> | 2024-11-20 12:08:59 +0000 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2024-11-20 12:08:59 +0000 |
commit | a3b71e8fc944f65861f2d0123bf0c6497e61b31c (patch) | |
tree | fe4ed04a10b4a51b40ba13133d7c2fc38efc8d4f | |
parent | 19429a5e7de3fb70b50c56b060b97a6ff4cc5e30 (diff) | |
download | prosody-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.c | 32 |
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 }, |