]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ned/server/src/lua_ns.cc
Inital import
[l4.git] / l4 / pkg / ned / server / src / lua_ns.cc
1 #include <lua.h>
2 #include <lauxlib.h>
3 #include <lualib.h>
4 #include "lua.h"
5
6 #include <l4/re/namespace>
7 #include <l4/re/util/cap_alloc>
8 #include <l4/re/env>
9
10 #include "lua_cap.h"
11
12 #include <cstring>
13 #include <cstdio>
14
15 namespace Lua { namespace {
16
17 static int
18 __lookup(lua_State *l)
19 {
20   size_t len;
21   char const *s = lua_tolstring(l, lua_upvalueindex(2), &len);
22   Cap *_ns = Lua::check_cap(l, lua_upvalueindex(1));
23   L4_cap_fpage_rights rights
24     = (L4_cap_fpage_rights)lua_tointeger(l, lua_upvalueindex(3));
25
26   L4::Cap<L4Re::Namespace> ns(_ns->cap<L4Re::Namespace>().get());
27
28   L4Re::Util::Auto_cap<void>::Cap obj = L4Re::Util::cap_alloc.alloc<void>();
29   if (!obj.is_valid())
30     luaL_error(l, "out of caps");
31
32   lua_gc(l, LUA_GCCOLLECT, 0);
33
34   int r = ns->query(s, len, obj.get(), L4Re::Namespace::To_default);
35 #if 0
36   if (r == -L4_ENOENT)
37     return Cap::index(l);
38 #endif
39   if (r == -L4_ENOENT)
40     {
41       lua_pushnil(l);
42       return 1;
43     }
44
45   if (r < 0)
46     luaL_error(l, "runtime error %s (%d)\n", l4sys_errtostr(r), r);
47
48
49   Lua::Cap *no = Lua::push_void_cap(l);
50   no->set(obj.release());
51   no->set_rights(rights);
52
53   return 1;
54
55 }
56
57 static int
58 __query(lua_State *l)
59 {
60   //size_t len;
61   //char const *s = luaL_checklstring(l, 2, &len);
62   int argc = lua_gettop(l);
63   if (argc < 2)
64     luaL_error(l, "expected at least two arguments in name-space query");
65
66   lua_pushvalue(l, 1);
67   lua_pushvalue(l, 2);
68   if (argc > 2)
69     lua_pushvalue(l, 3);
70   else
71     lua_pushinteger(l, L4_FPAGE_RO);
72
73   lua_pushcclosure(l, __lookup, 3);
74   return 1;
75 }
76
77
78 static int
79 __register_link(lua_State *l)
80 {
81   size_t src_len;
82   char const *src_name = lua_tolstring(l, lua_upvalueindex(2), &src_len);
83   Cap *_src_ns = Lua::check_cap(l, lua_upvalueindex(1));
84   L4::Cap<L4Re::Namespace> src_ns(_src_ns->cap<L4Re::Namespace>().get());
85   lua_Integer flags = lua_tointeger(l, lua_upvalueindex(3));
86   flags |= L4_FPAGE_RO;
87
88   size_t dst_len;
89   char const *dst_name = lua_tolstring(l, 2, &dst_len);
90   Cap *_dst_ns = Lua::check_cap(l, 1);
91   L4::Cap<L4Re::Namespace> dst_ns(_dst_ns->cap<L4Re::Namespace>().get());
92 #if 0
93   printf("do register link dst='%.*s' at %lx src='%.*s' at %lx\n",
94          dst_len, dst_name, dst_ns.cap(), src_len, src_name, src_ns.cap());
95 #endif
96
97   lua_gc(l, LUA_GCCOLLECT, 0);
98
99   int r = dst_ns->link(dst_name, dst_len, src_ns, src_name, src_len, flags);
100   if (r < 0)
101     luaL_error(l, "runtime error: %s (%d)", l4sys_errtostr(r), r);
102   else
103     lua_pushnil(l);
104
105   return 1;
106 }
107
108
109
110 static int
111 __link(lua_State *l)
112 {
113   check_cap(l, 1);
114
115   lua_pushvalue(l, 1); // the source namespace
116   lua_pushvalue(l, 2); // the source name
117   lua_pushvalue(l, 3); // the flags
118   lua_pushcclosure(l, __register_link, 3);
119   return 1;
120 }
121
122 static int
123 __register(lua_State *l)
124 {
125   Cap *ns = check_cap(l, 1);
126   char const *key = luaL_checkstring(l, 2);
127
128   Cap *n = 0;
129   lua_Integer type = lua_type(l, 3);
130   lua_gc(l, LUA_GCCOLLECT, 0);
131   switch (type)
132     {
133     case LUA_TNIL:
134         {
135           int r = ns->cap<L4Re::Namespace>()->unlink(key);
136           if (r >= 0 || r == -L4_ENOENT)
137             return 1;
138
139           luaL_error(l, "runtime error %s (%d)", l4sys_errtostr(r), r);
140         }
141     case LUA_TSTRING:
142       break;
143
144     case LUA_TUSERDATA:
145       n = Lua::check_cap(l, 3);
146       break;
147     default:
148       luaL_error(l, "unexpected value to register in namespace (%s)",
149                  lua_typename(l, 3));
150     }
151
152 #if 0
153   printf("register %s=%lx in %lx\n", key, n ? n->cap<void>().cap() : ~0, ns->cap<void>().cap());
154 #endif
155
156   int r = ns->cap<L4Re::Namespace>()->register_obj(key,
157       n ? n->cap<void>().get() : L4::Cap<void>::Invalid,
158       L4Re::Namespace::Overwrite | (n ? n->rights() : 0x0f));
159   if (r < 0)
160     luaL_error(l, "runtime error %s (%d)", l4sys_errtostr(r), r);
161
162   return 1;
163 }
164
165
166
167 struct Ns_model
168 {
169   static void
170   register_methods(lua_State *l)
171   {
172   static const luaL_Reg l4_cap_class[] =
173     {
174       { "q", __query },
175       { "query", __query },
176       { "__register", __register },
177       { "l", __link },
178       { "link", __link },
179       { NULL, NULL }
180     };
181   luaL_register(l, NULL, l4_cap_class);
182   Cap::add_class_metatable(l);
183   }
184 };
185
186
187 static Lua::Cap_type_lib<L4Re::Namespace, Ns_model> __lib;
188
189 }}
190