ref: aaaf0950ed2342ba80faea7f5941061542070775
parent: 8b4185716fbbb9b83eb2b2041037f389c3de9b7f
author: kvik <kvik@a-b.xyz>
date: Sun Apr 18 18:37:49 EDT 2021
fs: implement file:dup()
--- a/fs.c
+++ b/fs.c
@@ -303,24 +303,45 @@
}
static int
-p9_remove(lua_State *L)
+p9_iounit(lua_State *L)
{
- const char *file;
+ int fd;
- file = luaL_checkstring(L, 1);
- if(remove(file) == -1)
- return error(L, "remove: %r");
- lua_pushboolean(L, 1);
+ fd = filefd(L, 1);
+ lua_pushinteger(L, iounit(fd));
return 1;
}
static int
-p9_iounit(lua_State *L)
+p9_dup(lua_State *L)
{
- int fd;
+ int fd, new, na;
+ na = lua_gettop(L);
fd = filefd(L, 1);
- lua_pushinteger(L, iounit(fd));
+ if(na == 2)
+ new = filefd(L, 2);
+ else
+ new = -1;
+ if((new = dup(fd, new)) == -1)
+ return error(L, "dup: %r");
+ if(na == 2){
+ lua_pushinteger(L, new);
+ lua_setfield(L, 2, "fd");
+ return 1;
+ }
+ return filenew(L, new);
+}
+
+static int
+p9_remove(lua_State *L)
+{
+ const char *file;
+
+ file = luaL_checkstring(L, 1);
+ if(remove(file) == -1)
+ return error(L, "remove: %r");
+ lua_pushboolean(L, 1);
return 1;
}
--- a/p9.c
+++ b/p9.c
@@ -192,6 +192,7 @@
{"seek", p9_seek},
{"iounit", p9_iounit},
{"path", p9_path},
+ {"dup", p9_dup},
{nil, nil},
};
luaL_newmetatable(L, "p9-File");
--- a/test.lua
+++ b/test.lua
@@ -82,6 +82,24 @@
f:close()
end
+-- file:dup()
+do
+ local a, b = assert(p9.pipe())
+ local c = assert(a:dup())
+ a:write("hello")
+ assert(b:read() == "hello")
+ c:write("world")
+ assert(b:read() == "world")
+ a:close() b:close() c:close()
+
+ a = assert(p9.open("/lib/glass"))
+ local buf = a:read()
+ b = assert(p9.open("/lib/bullshit"))
+ b = assert(a:dup(b))
+ b:seek(0)
+ assert(b:read() == buf)
+end
+
-- pipe
do
local p₀, p₁ = assert(p9.pipe())