From 048b064fcdcc2309c952d7b5f9dae10aa7bf15cd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 7 Jun 2023 05:07:03 +0200 Subject: util.pposix: Add remove_blocks() for deleting parts of files Allows implementing e.g. a FIFO Will probably only work on some Linux file systems like ext4. --- teal-src/prosody/util/pposix.d.tl | 1 + util-src/pposix.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/teal-src/prosody/util/pposix.d.tl b/teal-src/prosody/util/pposix.d.tl index 68f49730..d7780835 100644 --- a/teal-src/prosody/util/pposix.d.tl +++ b/teal-src/prosody/util/pposix.d.tl @@ -97,6 +97,7 @@ local record pposix meminfo : function () : memoryinfo atomic_append : function (f : FILE, s : string) : boolean, string, integer + remove_blocks : function (f : FILE, integer, integer) isatty : function(FILE) : boolean diff --git a/util-src/pposix.c b/util-src/pposix.c index 2d5b6797..b2a8dbac 100644 --- a/util-src/pposix.c +++ b/util-src/pposix.c @@ -802,6 +802,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); @@ -847,6 +882,7 @@ int luaopen_prosody_util_pposix(lua_State *L) { #endif { "atomic_append", lc_atomic_append }, + { "remove_blocks", lc_remove_blocks }, { "isatty", lc_isatty }, -- cgit v1.2.3