From fd2ce1e76190eaffe581ed7c9b0e7e6ab84cb68d Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Sat, 28 Jul 2012 22:21:10 +0200
Subject: util.pposix: Add fallocate method, backed by either posix_fallocate()
 or Linux fallocate()

---
 util-src/pposix.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/util-src/pposix.c b/util-src/pposix.c
index 65f8b4ab..7600766f 100644
--- a/util-src/pposix.c
+++ b/util-src/pposix.c
@@ -32,8 +32,14 @@
 #include <string.h>
 #include <errno.h>
 #include "lua.h"
+#include "lualib.h"
 #include "lauxlib.h"
 
+#include <fcntl.h>
+#if defined(_GNU_SOURCE)
+#include <linux/falloc.h>
+#endif
+
 #if (defined(_SVID_SOURCE) && !defined(WITHOUT_MALLINFO))
 	#include <malloc.h>
 	#define WITH_MALLINFO
@@ -642,6 +648,39 @@ int lc_meminfo(lua_State* L)
 }
 #endif
 
+/* File handle extraction blatantly stolen from
+ * https://github.com/rrthomas/luaposix/blob/master/lposix.c#L631
+ * */
+
+#if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L || defined(_GNU_SOURCE)
+int lc_fallocate(lua_State* L)
+{
+	off_t offset, len;
+	FILE *f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE);
+
+	offset = luaL_checkinteger(L, 2);
+	len = luaL_checkinteger(L, 3);
+
+#if defined(_GNU_SOURCE)
+	if(fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len) != 0)
+#elif _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L
+	if(posix_fallocate(fileno(f), offset, len) != 0)
+#endif
+	{
+#if ! defined(_GNU_SOURCE)
+		/* posix_fallocate() can leave a bunch of NULs at the end, so we cut that
+		 * this assumes that offset == length of the file */
+		ftruncate(fileno(f), offset);
+#endif
+		lua_pushnil(L);
+		lua_pushstring(L, strerror(errno));
+		return 2;
+	}
+	lua_pushboolean(L, 1);
+	return 1;
+}
+#endif
+
 /* Register functions */
 
 int luaopen_util_pposix(lua_State *L)
@@ -679,6 +718,10 @@ int luaopen_util_pposix(lua_State *L)
 		{ "meminfo", lc_meminfo },
 #endif
 
+#if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L || defined(_GNU_SOURCE)
+		{ "fallocate", lc_fallocate },
+#endif
+
 		{ NULL, NULL }
 	};
 
-- 
cgit v1.2.3