diff options
author | Rob Kendrick (monotony) <rjek@rjek.com> | 2012-08-11 16:54:54 +0100 |
---|---|---|
committer | Rob Kendrick (monotony) <rjek@rjek.com> | 2012-08-11 16:54:54 +0100 |
commit | 9e9e75d685aa265e16ec12a1bad7b8f5c15a1a35 (patch) | |
tree | 8cebd64810c43c8a1826a4aa5e79b7b0a9500a28 | |
parent | 757a7e576073a1a338cab6df735fdca1b25cc012 (diff) | |
download | luxio-9e9e75d685aa265e16ec12a1bad7b8f5c15a1a35.tar.gz |
luxio: advisory locking via fcntl
-rw-r--r-- | luxio.c | 37 | ||||
-rw-r--r-- | luxio_constants.h.in | 6 | ||||
-rw-r--r-- | tests/test-fcntl-lock-1.lua | 21 | ||||
-rw-r--r-- | tests/test-fcntl-lock-2.lua | 21 |
4 files changed, 84 insertions, 1 deletions
@@ -1510,7 +1510,7 @@ luxio_splice(lua_State *L) /* Linux-specific */ /**> fcntl * Supported commands: * F_GETFD/F_SETFD, F_GETFL/F_SETFL, F_GETPIPE_SZ/F_SETPIPE_SZ, F_DUPFD, - * F_DUPFD_CLOEXEC. + * F_DUPFD_CLOEXEC, F_SETLK, F_SETLKW, F_GETLK * * C-Style: retval = fcntl(fd, cmd[, argument]); * @@ -1522,6 +1522,7 @@ luxio_fcntl(lua_State *L) /* 6.5.2 */ int fd = luaL_checkint(L, 1); int cmd = luaL_checkint(L, 2); long arg_long; + struct flock flock; switch (cmd) { /* commands that take no argument */ @@ -1549,6 +1550,40 @@ luxio_fcntl(lua_State *L) /* 6.5.2 */ lua_pushinteger(L, errno); return 2; + + /* commands that take exciting things */ + case F_SETLK: + case F_SETLKW: + case F_GETLK: + luaL_checktype(L, 3, LUA_TTABLE); + + lua_getfield(L, 3, "l_type"); + lua_getfield(L, 3, "l_whence"); + lua_getfield(L, 3, "l_start"); + lua_getfield(L, 3, "l_len"); + flock.l_type = lua_tonumber(L, -4); + flock.l_whence = lua_tonumber(L, -3); + flock.l_start = lua_tonumber(L, -2); + flock.l_len = lua_tonumber(L, -1); + flock.l_pid = 0; + + lua_pushinteger(L, fcntl(fd, cmd, &flock)); + lua_pushinteger(L, errno); + + if (cmd == F_GETLK) { + lua_pushnumber(L, flock.l_type); + lua_pushnumber(L, flock.l_whence); + lua_pushnumber(L, flock.l_start); + lua_pushnumber(L, flock.l_len); + lua_pushnumber(L, flock.l_pid); + lua_setfield(L, 3, "l_pid"); + lua_setfield(L, 3, "l_len"); + lua_setfield(L, 3, "l_start"); + lua_setfield(L, 3, "l_whence"); + lua_setfield(L, 3, "l_type"); + } + + return 2; default: lua_pushstring(L, "unhandled fcntl() command"); diff --git a/luxio_constants.h.in b/luxio_constants.h.in index 909cf69..05a73d9 100644 --- a/luxio_constants.h.in +++ b/luxio_constants.h.in @@ -94,6 +94,12 @@ static const struct { ? E(F_DUPFD_CLOEXEC), ? E(F_SETPIPE_SZ), ? E(F_GETPIPE_SZ), + E(F_SETLK), + E(F_SETLKW), + E(F_GETLK), + E(F_RDLCK), + E(F_WRLCK), + E(F_UNLCK), /* socket types */ E(PF_UNSPEC), diff --git a/tests/test-fcntl-lock-1.lua b/tests/test-fcntl-lock-1.lua new file mode 100644 index 0000000..a221b98 --- /dev/null +++ b/tests/test-fcntl-lock-1.lua @@ -0,0 +1,21 @@ +local l = require "luxio" + +local fd, r, errno + +fd, errno = l.open("test-lock-file", l.bit.bor(l.O_CREAT, l.O_RDWR), tonumber("600", 8)) +print("open: fd,errno:", fd, errno) +assert(fd >= 0) + +t = { + l_type = l.F_WRLCK, + l_whence = l.SEEK_SET, + l_start = 0, + l_len = 4096 +} + +r, errno = l.fcntl(fd, l.F_SETLK, t) +print("fnctl: r,errno:", r, errno) +print("sleeping 10 seconds") +l.sleep(10) + +l.unlink "test-lock-file" diff --git a/tests/test-fcntl-lock-2.lua b/tests/test-fcntl-lock-2.lua new file mode 100644 index 0000000..3a6dbd1 --- /dev/null +++ b/tests/test-fcntl-lock-2.lua @@ -0,0 +1,21 @@ +local l = require "luxio" + +local fd, r, errno + +fd, errno = l.open("test-lock-file", l.O_RDWR) +assert(fd >= 0) + +t = { + l_type = l.F_WRLCK, + l_whence = l.SEEK_SET, + l_start = 0, + l_len = 4096 +} + +r, errno = l.fcntl(fd, l.F_GETLK, t) +print("fnctl: r,errno:", r, errno) +print("held by pid, waiting for unlock", t.l_pid) + +t.l_type = l.F_WRLCK +r, errno = l.fcntl(fd, l.F_SETLKW, t) +print("fnctl: r,errno:", r, errno) |