summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Kendrick (monotony) <rjek@rjek.com>2012-08-11 16:54:54 +0100
committerRob Kendrick (monotony) <rjek@rjek.com>2012-08-11 16:54:54 +0100
commit9e9e75d685aa265e16ec12a1bad7b8f5c15a1a35 (patch)
tree8cebd64810c43c8a1826a4aa5e79b7b0a9500a28
parent757a7e576073a1a338cab6df735fdca1b25cc012 (diff)
downloadluxio-9e9e75d685aa265e16ec12a1bad7b8f5c15a1a35.tar.gz
luxio: advisory locking via fcntl
-rw-r--r--luxio.c37
-rw-r--r--luxio_constants.h.in6
-rw-r--r--tests/test-fcntl-lock-1.lua21
-rw-r--r--tests/test-fcntl-lock-2.lua21
4 files changed, 84 insertions, 1 deletions
diff --git a/luxio.c b/luxio.c
index c255598..0e418ec 100644
--- a/luxio.c
+++ b/luxio.c
@@ -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)