summaryrefslogtreecommitdiff
path: root/src/luamq.c
blob: c2bb03f7699a560832ac6db5c0c3a2e1b1b3ee1c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "lua.h"
#include "lauxlib.h"

#include <sys/stat.h>
#include <mqueue.h>
#include <errno.h>
#include <string.h>


#define MQD_TYPENAME "mqd_t"

LUALIB_API int luaopen_luamq(lua_State *L);

static int get_oflags(const char* flagstr)
{
  if(strcmp(flagstr, "ro"))
    return O_RDONLY;

  if(strcmp(flagstr, "wo"))
    return O_WRONLY;

  return O_RDWR;
}

static int l_luamq_create(lua_State *L)
{
  mqd_t id, *ptr;
  int flags;
  flags = get_oflags(luaL_optlstring(L, 2, "", NULL));
  id = mq_open(luaL_checkstring(L, 1), flags | O_CREAT, S_IRWXU | S_IRWXG, NULL);
  if(id == (mqd_t)-1) {
    lua_pushnil(L);
    lua_pushstring(L, strerror(errno)); /* TODO: thread safety */
    return 2;
  }
  ptr = (mqd_t*)lua_newuserdata(L, sizeof(mqd_t));
  *ptr = id;
  luaL_newmetatable(L, MQD_TYPENAME);
  lua_setmetatable(L, -2);
  return 1;
}

static int l_luamq_open(lua_State *L)
{
  mqd_t id, *ptr;
  int flags;
  flags = get_oflags(luaL_optlstring(L, 2, "", NULL));
  id = mq_open(luaL_checkstring(L, 1), flags);
  if(id == (mqd_t)-1) {
    lua_pushnil(L);
    lua_pushstring(L, strerror(errno)); /* TODO: thread safety */
    return 2;
  }
  ptr = (mqd_t*)lua_newuserdata(L, sizeof(mqd_t));
  *ptr = id;
  luaL_newmetatable(L, MQD_TYPENAME);
  lua_setmetatable(L, -2);
  return 1;
}

static int l_luamq_send(lua_State *L)
{
  mqd_t* id;
  unsigned int prio;
  size_t len;
  const char* str;

  id = luaL_checkudata(L, 1, MQD_TYPENAME);
  str = luaL_checklstring(L, 2, &len);
  prio = luaL_optint(L, 3, 0);
  if(mq_send(*id, str, len, prio)) {
    lua_pushnil(L);
    lua_pushstring(L, strerror(errno)); /* TODO: thread safety */
    return 2;
  }
  return 0;
}

static int l_luamq_receive(lua_State *L)
{
  return 0;
}

static int l_luamq_close(lua_State *L)
{
  mqd_t* id;
  id = luaL_checkudata(L, 1, MQD_TYPENAME);
  if(mq_close(*id)) {
    lua_pushnil(L);
    lua_pushstring(L, strerror(errno)); /* TODO: thread safety */
    return 2;
  }

  lua_pushboolean(L, 1);
  return 1;
}

static int l_luamq_unlink(lua_State *L)
{
  if(mq_unlink(luaL_checkstring(L, 1))) {
    lua_pushnil(L);
    lua_pushstring(L, strerror(errno)); /* TODO: thread safety */
    return 2;
  }

  lua_pushboolean(L, 1);
  return 1;
}

static const struct luaL_reg luamq_funcs [] = {
  { "create", l_luamq_create },
  { "open", l_luamq_open },
  { "send", l_luamq_send },
  { "receive", l_luamq_receive },
  { "close", l_luamq_close },
  { "unlink", l_luamq_unlink },
  { NULL, NULL }
};

LUALIB_API int luaopen_luamq(lua_State *L)
{
  luaL_register(L, "luamq", luamq_funcs);
  return 1;
}