diff options
author | Rob Kendrick (octopus) <rjek@rjek.com> | 2012-05-10 19:11:26 +0100 |
---|---|---|
committer | Rob Kendrick (octopus) <rjek@rjek.com> | 2012-05-10 19:11:26 +0100 |
commit | 2773e5427bd897791e32cd777d8f7a0a9596ca4b (patch) | |
tree | 1d6849fd8a53dea5771b72d7ad9dea0bfd89b70f | |
parent | aa8351806d0bdef74c3fd4845843dbf416b71797 (diff) | |
download | luxio-2773e5427bd897791e32cd777d8f7a0a9596ca4b.tar.gz |
Fix fdatasync, add splice
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | luxio.c | 30 | ||||
-rw-r--r-- | luxio_constants.h.in | 7 | ||||
-rw-r--r-- | tests/test-splice.lua | 45 |
4 files changed, 82 insertions, 1 deletions
@@ -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 @@ -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() |