summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Kendrick (octopus) <rjek@rjek.com>2012-05-10 19:11:26 +0100
committerRob Kendrick (octopus) <rjek@rjek.com>2012-05-10 19:11:26 +0100
commit2773e5427bd897791e32cd777d8f7a0a9596ca4b (patch)
tree1d6849fd8a53dea5771b72d7ad9dea0bfd89b70f
parentaa8351806d0bdef74c3fd4845843dbf416b71797 (diff)
downloadluxio-2773e5427bd897791e32cd777d8f7a0a9596ca4b.tar.gz
Fix fdatasync, add splice
-rw-r--r--config.h1
-rw-r--r--luxio.c30
-rw-r--r--luxio_constants.h.in7
-rw-r--r--tests/test-splice.lua45
4 files changed, 82 insertions, 1 deletions
diff --git a/config.h b/config.h
index 8eb5a35..91e5a83 100644
--- a/config.h
+++ b/config.h
@@ -9,6 +9,7 @@
#ifdef __linux__
# define HAVE_SENDFILE 1
+# define HAVE_SPLICE 1
# define HAVE_D_TYPE 1
# define _GNU_SOURCE
# define _LARGEFILE64_SOURCE
diff --git a/luxio.c b/luxio.c
index 165860d..6fa6c5c 100644
--- a/luxio.c
+++ b/luxio.c
@@ -1153,6 +1153,31 @@ luxio_sendfile(lua_State *L) /* Linux-specific */
}
#endif /* HAVE_SENDFILE */
+#ifdef HAVE_SPLICE
+static int
+luxio_splice(lua_State *L) /* Linux-specific */
+{
+ int fd_in = luaL_checkinteger(L, 1);
+ loff_t off_in = luaL_optlong(L, 2, -1);
+ int fd_out = luaL_checkinteger(L, 3);
+ loff_t off_out = luaL_optlong(L, 4, -1);
+ size_t len = luaL_checkinteger(L, 5);
+ unsigned int flags = luaL_checkinteger(L, 6);
+
+ loff_t *poff_in = &off_in;
+ loff_t *poff_out = &off_out;
+
+ if (off_in == -1) poff_in = NULL;
+ if (off_out == -1) poff_out = NULL;
+
+ lua_pushinteger(L, splice(fd_in, poff_in, fd_out, poff_out,
+ len, flags));
+ lua_pushinteger(L, errno);
+
+ return 2;
+}
+#endif
+
/* 6.5 Control operations on files *******************************************/
static int
@@ -1241,7 +1266,7 @@ luxio_fsync(lua_State *L) /* 6.6.1 */
static int
luxio_fdatasync(lua_State *L) /* 6.6.2 */
{
- int fildes = luaL_checkinteger(L, 2);
+ int fildes = luaL_checkinteger(L, 1);
lua_pushinteger(L, fdatasync(fildes));
lua_pushinteger(L, errno);
@@ -2237,6 +2262,9 @@ luxio_functions[] = {
#ifdef HAVE_SENDFILE
{ "sendfile", luxio_sendfile },
#endif
+#ifdef HAVE_SPLICE
+ { "splice", luxio_splice },
+#endif
{ "dup", luxio_dup },
{ "dup2", luxio_dup2 },
#ifdef _GNU_SOURCE
diff --git a/luxio_constants.h.in b/luxio_constants.h.in
index f6e7acc..0d65d52 100644
--- a/luxio_constants.h.in
+++ b/luxio_constants.h.in
@@ -39,6 +39,7 @@ static const struct {
E(EPERM),
E(EPROTONOSUPPORT),
E(EROFS),
+? E(ESPIPE),
E(ESRCH),
E(ETXTBSY),
E(EWOULDBLOCK),
@@ -66,6 +67,12 @@ static const struct {
E(SEEK_CUR),
E(SEEK_END),
+ /* splice-related defines */
+? E(SPLICE_F_MOVE),
+? E(SPLICE_F_NONBLOCK),
+? E(SPLICE_F_MORE),
+? E(SPLICE_F_GIFT),
+
/* stat-related defines */
E(S_IRWXU), E(S_IRUSR), E(S_IWUSR), E(S_IXUSR),
E(S_IRWXG), E(S_IRGRP), E(S_IWGRP), E(S_IXGRP),
diff --git a/tests/test-splice.lua b/tests/test-splice.lua
new file mode 100644
index 0000000..2f434c4
--- /dev/null
+++ b/tests/test-splice.lua
@@ -0,0 +1,45 @@
+local l = require "luxio"
+
+function check(r, e, ...)
+ if r < 0 then
+ error(l.strerror(r))
+ end
+ return r, e, ...
+end
+
+r, w = 1, 2
+pipe = {}
+check(l.pipe(pipe))
+
+pr = pipe[1]
+pw = pipe[2]
+
+-- discover pipe read/write size to use
+local pz = 64 * 1024
+if l.F_GETPIPE_SZ then
+ local ppz = check(l.fcntl(pipe[w], l.F_GETPIPE_SZ))
+ if ppz > pz then pz = ppz end
+end
+
+r, in_stat = l.stat(arg[1])
+if r == -1 then error "unable to stat input file" end
+
+
+in_file = check(l.open(arg[1], l.O_RDONLY))
+out_file = check(l.open(arg[2], l.bit.bor(l.O_CREAT, l.O_WRONLY), in_stat.mode))
+
+repeat
+ r = l.splice(in_file, nil, pw, nil, pz, l.SPLICE_F_MORE)
+ if r > 0 then
+ l.splice(pr, nil, out_file, nil, pz, l.SPLICE_F_MORE)
+ end
+until r == 0
+
+l.fdatasync(out_file)
+
+l.close(pr)
+l.close(pw)
+l.close(out_file)
+l.close(in_file)
+
+os.exit()