]> git.e2factory.org Git - e2factory.git/commitdiff
luafile: new function cloexec() to set FD_CLOEXEC on file
authorTobias Ulmer <tu@emlix.com>
Wed, 7 Oct 2015 16:37:42 +0000 (18:37 +0200)
committerTobias Ulmer <tu@emlix.com>
Thu, 8 Oct 2015 15:49:17 +0000 (17:49 +0200)
Signed-off-by: Tobias Ulmer <tu@emlix.com>
generic/luafile.lua
generic/luafile_ll.c

index b79c67847c80c47312f5772a6e50f29b7747fd05..cadb35411aa062a7d16ab9dad4f1712d4be6c2c0 100644 (file)
@@ -141,6 +141,22 @@ function luafile.dup2(oldfd, newfd)
     return nil
 end
 
+
+--- Set the CLOEXEC flag on underlying file descriptor. Throws exception on
+-- invalid input.
+-- @param something can be a file descriptor number, luafile object, or io file
+-- @param set True to set the CLOEXEC, False to unset it. Defaults to True.
+-- @return True on success, False on error.
+function luafile.cloexec(something, set)
+    assert(something ~= nil)
+    assert(set == nil or type(set) == "boolean")
+    if set == nil then
+        set = true
+    end
+
+    return luafile_ll.cloexec(something, set)
+end
+
 return strict.lock(luafile)
 
 -- vim:sw=4:sts=4:et:
index 121bf8b05dee32db067bb7ea52b597edd3a86c8a..b3c6994771434b1bf75a84d596611b0169508e9c 100644 (file)
@@ -250,6 +250,50 @@ lua_dup2(lua_State *lua)
        return 1;
 }
 
+static int
+lua_cloexec(lua_State *lua)
+{
+       int fd = -1, rc, cloexec;
+       FILE *f = NULL;
+
+       if (lua_isnumber(lua, 1)) {
+               fd = luaL_checkint(lua, 1);
+       } else if (lua_istable(lua, 1)) {
+               lua_pushstring(lua, "file"); // key
+               lua_gettable(lua, 1);
+               if (!lua_islightuserdata(lua, -1))
+                   luaL_argerror(lua, 1, "not a luafile table");
+               f = (FILE *)lua_topointer(lua, -1);
+       } else if (lua_isuserdata(lua, 1)) {
+               FILE **p;
+               p = (FILE **)luaL_checkudata(lua, 1, LUA_FILEHANDLE);
+               if (*p == NULL) {
+                       lua_pushfstring(lua, "%s: closed lua filehandle",
+                           __func__);
+                       lua_error(lua);
+               }
+               f = *p;
+       }
+
+       if (f) {
+               fd = fileno(f);
+       }
+
+       if (fd < 0) {
+               luaL_argerror(lua, 1, "fd/luafile/io file required");
+       }
+
+       if (lua_isboolean(lua, 2)) {
+               cloexec = lua_toboolean(lua, 2);
+       } else {
+               luaL_argerror(lua, 2, "boolean required");
+       }
+
+       rc = fcntl(fd, F_SETFD, cloexec ? FD_CLOEXEC : 0);
+       lua_pushboolean(lua, (rc == 0));
+       return 1;
+}
+
 static luaL_Reg lib[] = {
   { "fopen", lua_fopen },
   { "fdopen", lua_fdopen },
@@ -264,6 +308,7 @@ static luaL_Reg lib[] = {
   { "setlinebuf", lua_setlinebuf },
   { "pipe", lua_pipe },
   { "dup2", lua_dup2 },
+  { "cloexec", lua_cloexec },
   { NULL, NULL }
 };