2 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
10 * As a special exception, you may use this file as part of a free software
11 * library without restriction. Specifically, if other files instantiate
12 * templates or use macros or inline functions from this file, or you compile
13 * this file and link it with other files to produce an executable, this
14 * file does not by itself cause the resulting executable to be covered by
15 * the GNU General Public License. This exception does not however
16 * invalidate any other reasons why the executable file might be covered by
17 * the GNU General Public License.
19 #include <l4/re/util/name_space_svr>
20 #include <l4/re/util/debug>
22 #include <l4/re/namespace-sys.h>
23 #include <l4/re/namespace>
24 #include <l4/re/protocols>
25 #include <l4/re/util/meta>
32 namespace L4Re { namespace Util { namespace Names {
35 Name::operator < (Name const &r) const
37 unsigned char l = cxx::min(len(), r.len());
38 int v = strncmp(start(), r.start(), l);
39 return v < 0 || (v == 0 && len() < r.len());
44 Entry::link(Entry *src)
46 if (src->obj()->is_replacable() || !src->obj()->is_complete())
49 if (src->obj()->is_complete())
50 obj()->set(*src->obj(), obj()->flags());
54 obj()->set(*src->obj(), obj()->flags());
59 Entry::set(Obj const &o)
64 e->obj()->set(o, e->obj()->flags());
70 Name_space::find_iter(Name const &pname) const
73 _dbg.printf("resolve '%.*s': ", name.len(), name.start());
74 Name_space const *ns = this;
77 cxx::String::Index sep = name.find("/");
80 part = name.head(sep);
84 _dbg.cprintf(" '%.*s'", part.len(), part.start());
85 Entry *o = ns->find(Name(part.start(), part.len()));
89 _dbg.cprintf(": resolution failed: '%.*s' remaining\n",
90 name.len(), name.start());
94 ns = dynamic_cast<Name_space const *>(o->obj()->obj());
99 name = name.substr(sep + 1);
104 _dbg.cprintf(": found object: %p (%s)\n", o->obj()->obj(), o->obj()->obj()?typeid(*(o->obj()->obj())).name():"");
114 Name_space::query(L4::Ipc::Iostream &ios, char *buffer, size_t max_len)
116 char const *name = 0;
117 unsigned long len = max_len;
118 ios >> L4::Ipc::Buf_in<char const>(name, len);
120 _dbg.printf("query: [%ld] '%.*s'\n", len, (int)len, name);
123 len = cxx::min<unsigned long>(len, max_len);
124 char const *sep = (char const*)memchr(name, '/', len);
129 memcpy(buffer, sep + 1, len - part - 1);
134 Entry *n = find(Name(name, part));
137 else if (!n->obj()->is_valid())
141 if (n->obj()->cap().validate(L4_BASE_TASK_CAP).label() <= 0)
143 assert (!n->obj()->is_local());
145 free_capability(n->obj()->cap());
150 free_dynamic_entry(n);
155 l4_umword_t result = 0;
159 result |= L4Re::Namespace::Partly_resolved;
160 ios << (l4_umword_t)0 << L4::Ipc::Buf_cp_out<char>(buffer, len - part - 1);
163 unsigned flags = L4_FPAGE_RO;
164 if (n->obj()->is_rw()) flags |= L4_FPAGE_RX;
165 if (n->obj()->is_strong()) flags |= L4_FPAGE_RW;
167 ios << L4::Ipc::Snd_fpage(n->obj()->cap(), flags );
168 _dbg.printf(" result = %lx flgs=%x strg=%d\n",
169 result, flags, (int)n->obj()->is_strong());
175 Name_space::insert_entry(Name const &name, unsigned flags, Entry **e)
177 Entry *n = find(name);
178 if (n && n->obj()->is_valid())
180 if (!(flags & L4Re::Namespace::Overwrite)
181 && n->obj()->cap().validate(L4_BASE_TASK_CAP).label() > 0)
184 if (!n->obj()->is_local())
185 free_capability(n->obj()->cap());
190 free_dynamic_entry(n);
195 n->obj()->reset(Obj::F_rw);
196 if (!n->obj()->is_replacable())
201 flags &= L4Re::Namespace::Cap_flags;
204 if (!(n = alloc_dynamic_entry(name, flags)))
211 free_dynamic_entry(n);
222 Name_space::link_entry(L4::Ipc::Iostream &ios, char *buffer, size_t max_len)
224 char const *name = 0, *src_name = 0;
225 unsigned long len, src_len;
227 L4::Ipc::Snd_fpage src_cap;
228 ios >> flags >> L4::Ipc::Buf_in<char const>(name, len)
229 >> L4::Ipc::Buf_in<char const>(src_name, src_len)
232 L4::Cap<void> reg_cap(L4::Cap_base::No_init);
233 L4::Server_object *src_ns_o = 0;
234 // Did we receive something we have handed out ourselves? If yes,
235 // register the object under the given name but do not allocate
237 if (int r = get_capability(src_cap, ®_cap, &src_ns_o))
240 Name_space *src_ns = dynamic_cast<Name_space*>(src_ns_o);
244 _dbg.printf("link: '%.*s' flags=%x\n", (int)len, name, flags);
246 Name const src_n(src_name, src_len);
248 Entry *n = src_ns->find(src_n);
251 if (!(n = src_ns->alloc_dynamic_entry(src_n, 0)))
255 int err = src_ns->insert(n);
258 src_ns->free_dynamic_entry(n);
264 // got a mapping at Rcv_cap
265 len = cxx::min(len, (unsigned long)max_len);
266 memcpy(buffer, name, len);
267 Name const dst_name(buffer, len);
271 if (int r = insert_entry(dst_name, flags, &dst))
281 Name_space::register_entry(L4::Ipc::Iostream &ios, char *buffer, size_t max_len)
283 char const *name = 0;
286 L4::Ipc::Snd_fpage cap;
287 ios >> flags >> L4::Ipc::Buf_in<char const>(name, len);
289 L4::Cap<void> reg_cap(L4_INVALID_CAP);
296 // Did we receive something we have handed out ourselves? If yes,
297 // register the object under the given name but do not allocate
299 if (int r = get_capability(cap, ®_cap))
303 _dbg.printf("register: '%.*s' flags=%x\n", (int)len, name, flags);
305 // got a mapping at Rcv_cap
306 len = cxx::min(len, (unsigned long)max_len);
307 memcpy(buffer, name, len);
308 Name _name(buffer, len);
311 if (int r = insert_entry(_name, flags, &n))
314 if (reg_cap.is_valid())
316 if (int r = save_capability(®_cap))
319 n->set(Names::Obj(flags & L4Re::Namespace::Cap_flags, reg_cap));
326 Name_space::unlink_entry(L4::Ipc::Iostream &ios, char *buffer, size_t max_len)
328 char const *name = 0;
329 unsigned long len = max_len;
330 ios >> L4::Ipc::Buf_in<char const>(name, len);
332 _dbg.printf("unlink: [%ld] '%.*s'\n", len, (int)len, name);
335 len = cxx::min<unsigned long>(len, max_len);
336 char const *sep = (char const*)memchr(name, '/', len);
341 memcpy(buffer, sep + 1, len - part - 1);
346 Entry *n = find(Name(name, part));
347 if (!n || !n->obj()->is_valid())
350 if (!n->obj()->is_local())
351 free_capability(n->obj()->cap());
356 free_dynamic_entry(n);
367 Name_space::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios, char *buffer,
375 case L4::Meta::Protocol:
376 return L4Re::Util::handle_meta_request<L4Re::Namespace>(ios);
378 case L4Re::Protocol::Namespace:
387 case L4Re::Namespace_::Query:
388 return query(ios, buffer, max_len);
389 case L4Re::Namespace_::Link:
390 if (!(obj & 1)) // & L4_FPAGE_X
392 err = link_entry(ios, buffer, max_len);
394 case L4Re::Namespace_::Register:
395 if (!(obj & 1)) // & L4_FPAGE_X
397 err = register_entry(ios, buffer, max_len);
399 case L4Re::Namespace_::Unlink:
400 if (!(obj & 1)) // & L4_FPAGE_X
402 err = unlink_entry(ios, buffer, max_len);
409 return -L4_EBADPROTO;