Diff

util-src/pposix.c @ 13184:d16845afb3e2

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.
author Kim Alvefur <zash@zash.se>
date Wed, 07 Jun 2023 05:07:03 +0200
parent 13152:792f360a582b
line wrap: on
line diff
--- a/util-src/pposix.c	Wed Jul 12 11:42:41 2023 +0200
+++ b/util-src/pposix.c	Wed Jun 07 05:07:03 2023 +0200
@@ -802,6 +802,41 @@
 	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 @@
 #endif
 
 		{ "atomic_append", lc_atomic_append },
+		{ "remove_blocks", lc_remove_blocks },
 
 		{ "isatty", lc_isatty },