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