summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Kendrick (plinth) <rjek@rjek.com>2013-08-27 11:41:36 +0100
committerRob Kendrick (plinth) <rjek@rjek.com>2013-08-27 11:41:36 +0100
commit87bfc8a846ed86d650550c6606fe9e3148d4c1a3 (patch)
tree109c9c6a40fae1decc80d9fc4876d947c6463989
parentfd0bb566d130d7bb2e2813ecffce670b8a5c40cb (diff)
parent47c4323a22541dad7d2a4052dd6a80959d941db1 (diff)
downloadluxio-87bfc8a846ed86d650550c6606fe9e3148d4c1a3.tar.gz
Merge
-rw-r--r--luxio.c87
-rw-r--r--tests/test-mqueue-read.lua29
-rw-r--r--tests/test-mqueue-write.lua15
3 files changed, 108 insertions, 23 deletions
diff --git a/luxio.c b/luxio.c
index 112111a..233cdb7 100644
--- a/luxio.c
+++ b/luxio.c
@@ -1797,14 +1797,31 @@ luxio_nanosleep(lua_State *L) /* 14.2.5 */
/**# Message passing *********************************************************/
-#if defined(_POSIX_MESSAGE_PASSING) && defined(__linux__)
-
-/* TODO: This code assumes mqd_t is an integer. On BSD it is not, so
- * this needs to be rewritten using userdata.
- */
+#if defined(_POSIX_MESSAGE_PASSING)
#include <mqueue.h>
+#define LUXIO_MQ_METATABLE_NAME "luxio.mq"
+
+struct luxio_mq_data {
+ mqd_t mq;
+ char name[NAME_MAX];
+};
+
+static int
+luxio__mq_tostring(lua_State *L)
+{
+ char buf[NAME_MAX + 64];
+
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
+
+ sprintf(buf, "<mq %p %s>", (void *)(intptr_t)m->mq, m->name);
+
+ lua_pushstring(L, buf);
+ return 1;
+}
+
/**% mq_open
* retval = mq_open(name, oflag[, mode, attr]);
* retval, errno = mq_open(name, oflag[, mode])
@@ -1816,6 +1833,7 @@ luxio_mq_open(lua_State *L) /* 15.2.1 */
int oflag = luaL_checkinteger(L, 2);
mode_t mode = luaL_optinteger(L, 3, INVALID_MODE);
mqd_t mq;
+ struct luxio_mq_data *m;
if ((oflag & O_CREAT) && mode == INVALID_MODE) {
lua_pushstring(L, "mq_open with O_CREATE called with no mode");
@@ -1828,7 +1846,23 @@ luxio_mq_open(lua_State *L) /* 15.2.1 */
mq = mq_open(name, oflag);
}
- lua_pushinteger(L, mq);
+ if (mq == (mqd_t)-1) {
+ lua_pushnumber(L, -1);
+ lua_pushinteger(L, errno);
+
+ return 2;
+ }
+
+ m = lua_newuserdata(L, sizeof(*m));
+ m->mq = mq;
+ strncpy(m->name, name, NAME_MAX);
+
+ if (luaL_newmetatable(L, LUXIO_MQ_METATABLE_NAME) != 0) {
+ lua_pushcfunction(L, luxio__mq_tostring);
+ lua_setfield(L, -2, "__tostring");
+ }
+
+ lua_setmetatable(L, -2);
lua_pushinteger(L, errno);
return 2;
@@ -1841,9 +1875,10 @@ luxio_mq_open(lua_State *L) /* 15.2.1 */
static int
luxio_mq_close(lua_State *L) /* 15.2.2 */
{
- mqd_t mq = luaL_checkinteger(L, 1);
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
- lua_pushinteger(L, mq_close(mq));
+ lua_pushinteger(L, mq_close(m->mq));
lua_pushinteger(L, errno);
return 2;
}
@@ -1869,12 +1904,13 @@ luxio_mq_unlink(lua_State *L) /* 15.2.3 */
static int
luxio_mq_send(lua_State *L) /* 15.2.4 */
{
- mqd_t mq = luaL_checkinteger(L, 1);
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
size_t msg_len;
const char *msg_ptr = luaL_checklstring(L, 2, &msg_len);
unsigned int msg_prio = luaL_checkinteger(L, 3);
- lua_pushinteger(L, mq_send(mq, msg_ptr, msg_len, msg_prio));
+ lua_pushinteger(L, mq_send(m->mq, msg_ptr, msg_len, msg_prio));
lua_pushinteger(L, errno);
return 2;
}
@@ -1886,18 +1922,19 @@ luxio_mq_send(lua_State *L) /* 15.2.4 */
static int
luxio_mq_receive(lua_State *L) /* 15.2.5 */
{
- mqd_t mq = luaL_checkinteger(L, 1);
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
unsigned int msg_prio;
struct mq_attr attr;
/* Find out the maximum size of a message */
- if (mq_getattr(mq, &attr) == -1) {
+ if (mq_getattr(m->mq, &attr) == -1) {
lua_pushinteger(L, -1);
lua_pushinteger(L, errno);
return 2;
} else {
char msg_ptr[attr.mq_msgsize];
- int r = mq_receive(mq, msg_ptr, sizeof(msg_ptr), &msg_prio);
+ int r = mq_receive(m->mq, msg_ptr, sizeof(msg_ptr), &msg_prio);
lua_pushinteger(L, r);
lua_pushinteger(L, errno);
if (r == -1) {
@@ -1939,11 +1976,12 @@ luxio_make_attr_table(lua_State *L, struct mq_attr *attr)
static int
luxio_mq_setattr(lua_State *L) /* 15.2.7 */
{
- mqd_t mq = luaL_checkinteger(L, 1);
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
struct mq_attr mqstat = { luaL_checkinteger(L, 2), 0, 0, 0 };
struct mq_attr omqstat = { 0, 0, 0, 0 };
- lua_pushinteger(L, mq_setattr(mq, &mqstat, &omqstat));
+ lua_pushinteger(L, mq_setattr(m->mq, &mqstat, &omqstat));
lua_pushinteger(L, errno);
luxio_make_attr_table(L, &omqstat);
@@ -1957,10 +1995,11 @@ luxio_mq_setattr(lua_State *L) /* 15.2.7 */
static int
luxio_mq_getattr(lua_State *L) /* 15.2.8 */
{
- mqd_t mq = luaL_checkinteger(L, 1);
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
struct mq_attr mqstat;
- lua_pushinteger(L, mq_getattr(mq, &mqstat));
+ lua_pushinteger(L, mq_getattr(m->mq, &mqstat));
lua_pushinteger(L, errno);
luxio_make_attr_table(L, &mqstat);
@@ -1976,7 +2015,8 @@ luxio_mq_getattr(lua_State *L) /* 15.2.8 */
static int
luxio_mq_timedsend(lua_State *L) /* POSIX.1-2001 */
{
- mqd_t mq = luaL_checkinteger(L, 1);
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
size_t msg_len;
const char *msg_ptr = luaL_checklstring(L, 2, &msg_len);
unsigned int msg_prio = luaL_checkinteger(L, 3);
@@ -1984,7 +2024,7 @@ luxio_mq_timedsend(lua_State *L) /* POSIX.1-2001 */
long tv_nsec = luaL_checkinteger(L, 5);
struct timespec abs_timeout = { tv_secs, tv_nsec };
- lua_pushinteger(L, mq_timedsend(mq, msg_ptr, msg_len, msg_prio,
+ lua_pushinteger(L, mq_timedsend(m->mq, msg_ptr, msg_len, msg_prio,
&abs_timeout));
lua_pushinteger(L, errno);
return 2;
@@ -1997,7 +2037,8 @@ luxio_mq_timedsend(lua_State *L) /* POSIX.1-2001 */
static int
luxio_mq_timedreceive(lua_State *L) /* POSIX.1-2001 */
{
- mqd_t mq = luaL_checkinteger(L, 1);
+ struct luxio_mq_data *m =
+ luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME);
unsigned int msg_prio;
struct mq_attr attr;
time_t tv_secs = luaL_checkinteger(L, 2);
@@ -2005,14 +2046,14 @@ luxio_mq_timedreceive(lua_State *L) /* POSIX.1-2001 */
struct timespec abs_timeout = { tv_secs, tv_nsec };
/* Find out the maximum size of a message */
- if (mq_getattr(mq, &attr) == -1) {
+ if (mq_getattr(m->mq, &attr) == -1) {
lua_pushinteger(L, -1);
lua_pushinteger(L, errno);
return 2;
} else {
char msg_ptr[attr.mq_msgsize];
- int r = mq_timedreceive(mq, msg_ptr, sizeof(msg_ptr), &msg_prio,
- &abs_timeout);
+ int r = mq_timedreceive(m->mq, msg_ptr, sizeof(msg_ptr),
+ &msg_prio, &abs_timeout);
lua_pushinteger(L, r);
lua_pushinteger(L, errno);
if (r == -1) {
diff --git a/tests/test-mqueue-read.lua b/tests/test-mqueue-read.lua
new file mode 100644
index 0000000..d8aeb90
--- /dev/null
+++ b/tests/test-mqueue-read.lua
@@ -0,0 +1,29 @@
+l = require "luxio"
+s = require "luxio.simple"
+
+local mq, errno
+
+mq, errno = l.mq_open("/luxio.test", l.bit.bor(l.O_RDONLY, l.O_CREAT), s.tomode "0777")
+
+if mq == -1 then
+ error(l.strerror(errno))
+end
+
+
+io.stdout:write(tostring(mq) .. " attributes:\n")
+
+r, errno, attr = l.mq_getattr(mq)
+
+for i, v in pairs(attr) do
+ io.stdout:write(" ", i, " ", v, "\n")
+end
+
+local message, bytes, priority
+
+repeat
+ bytes, errno, message, priority = l.mq_receive(mq)
+ print(bytes, errno, message, priority)
+until message == "QUIT" or bytes == -1
+
+l.mq_close(mq)
+l.mq_unlink "/luxio-test"
diff --git a/tests/test-mqueue-write.lua b/tests/test-mqueue-write.lua
new file mode 100644
index 0000000..42eff87
--- /dev/null
+++ b/tests/test-mqueue-write.lua
@@ -0,0 +1,15 @@
+l = require "luxio"
+s = require "luxio.simple"
+
+local mq, errno
+
+mq, errno = l.mq_open("/luxio.test", l.O_WRONLY)
+
+if mq == -1 then
+ error(l.strerror(errno))
+end
+
+r, errno = l.mq_send(mq, table.concat({ ... }, " "), 42)
+
+print(r)
+