1// -*- Mode: C++ -*- 2// vim:ft=cpp 3/** 4 * \file 5 * \brief Namespace interface 6 */ 7/* 8 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>, 9 * Alexander Warg <warg@os.inf.tu-dresden.de>, 10 * Björn Döbel <doebel@os.inf.tu-dresden.de> 11 * economic rights: Technische Universität Dresden (Germany) 12 * 13 * This file is part of TUD:OS and distributed under the terms of the 14 * GNU General Public License 2. 15 * Please see the COPYING-GPL-2 file for details. 16 * 17 * As a special exception, you may use this file as part of a free software 18 * library without restriction. Specifically, if other files instantiate 19 * templates or use macros or inline functions from this file, or you compile 20 * this file and link it with other files to produce an executable, this 21 * file does not by itself cause the resulting executable to be covered by 22 * the GNU General Public License. This exception does not however 23 * invalidate any other reasons why the executable file might be covered by 24 * the GNU General Public License. 25 */ 26#pragma once 27 28#include <l4/sys/capability> 29#include <l4/re/protocols.h> 30#include <l4/sys/cxx/ipc_iface> 31#include <l4/sys/cxx/ipc_array> 32#include <l4/sys/cxx/ipc_string> 33 34namespace L4Re { 35 36/** 37 * \defgroup api_l4re_namespace Name-space API 38 * \ingroup api_l4re 39 * \brief API for name spaces that store capabilities. 40 * 41 * This is a basic abstraction for managing a mapping from 42 * human-readable names to capabilities. In particular, a name 43 * can also be mapped to a capability that refers to another name space 44 * object. By this means name spaces can be constructed hierarchically. 45 * 46 * Name spaces play a central role in L4Re, because the implementation of the 47 * name space objects determines the policy which capabilities (which objects) 48 * are accessible to a client of a name space. 49 */ 50/** 51 * \brief Name-space interface. 52 * \ingroup api_l4re_namespace 53 * 54 * All name space objects must provide this interface. However, it is not 55 * mandatory that a name space object allows to register new capabilities. 56 * 57 * The name lookup is done iteratively, this means the hierarchical names 58 * are resolved component wise by the client itself. 59 */ 60class L4_EXPORT Namespace : 61 public L4::Kobject_t<Namespace, L4::Kobject, L4RE_PROTO_NAMESPACE, 62 L4::Type_info::Demand_t<1> > 63{ 64public: 65 /** 66 * Flags for registering name spaces. 67 */ 68 enum Register_flags 69 { 70 Ro = L4_CAP_FPAGE_RO, ///< Read-only 71 Rw = L4_CAP_FPAGE_RW, ///< Read-write 72 Rs = L4_CAP_FPAGE_RS, ///< Read-only + strong 73 Rws = L4_CAP_FPAGE_RWS, ///< Read-write + strong 74 Strong = L4_CAP_FPAGE_S, ///< Strong 75 Trusted = 0x008, ///< Obsolete, do not use 76 77 Cap_flags = Ro | Rw | Strong | Trusted, 78 79 Link = 0x100, ///< Obsolete, do not use 80 Overwrite = 0x200, ///< If entry already exists, overwrite it. 81 }; 82 83 /** 84 * Flags returned by query IPC, only used internally. 85 * 86 * \internal 87 */ 88 enum Query_result_flags 89 { 90 Partly_resolved = 0x020, ///< Name was only partly resolved. 91 }; 92 93 enum Query_timeout 94 { 95 To_default = 3600000, 96 To_non_blocking = 0, 97 To_forever = -1, 98 }; 99 100 L4_RPC_NF( 101 long, query, (L4::Ipc::Array_ref<char const, unsigned long> name, 102 L4::Ipc::Small_buf cap, 103 L4::Ipc::Snd_fpage &snd_cap, L4::Ipc::Opt<L4::Opcode &> dummy, 104 L4::Ipc::Opt<L4::Ipc::Array_ref<char const, unsigned long> &> out_name)); 105 106 /** 107 * Query the name space for a named object. 108 * 109 * \param[in] name String to query (without any leading slashes). 110 * \param[out] cap Capability slot where the received capability will 111 * be put. 112 * \param[in] timeout Timeout of query in milliseconds. The client will only 113 * wait if a name has already been registered with the 114 * server but no object has yet been attached. 115 * \param[out] local_id If given, #L4_RCV_ITEM_LOCAL_ID will be set for the 116 * IPC from the name space, so that if the capability 117 * that was received is a local item, the capability ID 118 * will be returned with this parameter. 119 * \param[in] iterate If true, the client will try to resolve 120 * names by iteratively calling the name spaces 121 * until the name is fully resolved. 122 * 123 * \retval 0 Name could be fully resolved. 124 * \retval >0 Name could only be partly resolved. The number of remaining 125 * characters is returned. 126 * \retval -L4_ENOENT Entry could not be found. 127 * \retval -L4_EAGAIN Entry exists but no object is yet attached. 128 * Try again later. 129 * \retval <0 IPC errors, see #l4_error_code_t. 130 */ 131 long query(char const *name, L4::Cap<void> const &cap, 132 int timeout = To_default, 133 l4_umword_t *local_id = 0, bool iterate = true) const noexcept; 134 135 /** 136 * Query the name space for a named object. 137 * 138 * The query string does not necessarily need to be null-terminated. 139 * 140 * \param[in] len Length of the string to query without any 141 * terminating null characters. 142 * \copydetails query() 143 */ 144 long query(char const *name, unsigned len, L4::Cap<void> const &cap, 145 int timeout = To_default, 146 l4_umword_t *local_id = 0, bool iterate = true) const noexcept; 147 148 L4_RPC_NF(long, register_obj, (unsigned flags, 149 L4::Ipc::Array<char const, unsigned long> name, 150 L4::Ipc::Opt< L4::Ipc::Cap<void> > obj), 151 L4::Ipc::Call_t<L4_CAP_FPAGE_W>); 152 153 /** 154 * Register an object with a name. 155 * 156 * \param name Name under which the object should be registered. 157 * \param obj Capability to object to register. An invalid capability may 158 * be given to only reserve the name for later use. 159 * \param flags Flags to assign to the entry, 160 * see #L4Re::Namespace::Register_flags. Note that the rights 161 * that are assigned to a capability are not only determined 162 * by the rights given in these flags but also by the rights 163 * with which the `obj` capability was mapped to the name 164 * space. 165 * 166 * \retval 0 Object was successfully registered with \a name. 167 * \retval -L4_EEXIST Name already registered. 168 * \retval -L4_EPERM Caller doesn't have necessary permissions. 169 * \retval -L4_ENOMEM Server has insufficient resources. 170 * \retval -L4_EINVAL Invalid parameter. 171 * \retval <0 IPC errors, see #l4_error_code_t. 172 * 173 * \caprights{RW} 174 * 175 */ 176 long register_obj(char const *name, L4::Ipc::Cap<void> obj, 177 unsigned flags = Rw) const noexcept 178 { 179 return register_obj_t::call(c(), flags, 180 L4::Ipc::Array<char const, unsigned long>( 181 __builtin_strlen(name), name), 182 obj); 183 } 184 185 L4_RPC_NF_OP(3, // backward compatibility opcode 186 long, unlink, (L4::Ipc::Array<char const, unsigned long> name), 187 L4::Ipc::Call_t<L4_CAP_FPAGE_W>); 188 189 /** 190 * Remove an entry from the name space. 191 * 192 * \param name Name of the entry to remove. 193 * 194 * \retval 0 Entry successfully removed. 195 * \retval -L4_ENOENT Given name does not exist. 196 * \retval -L4_EPERM Caller does not have write permission. 197 * \retval -L4_EACCESS Name cannot be removed. 198 * \retval <0 IPC errors, see #l4_error_code_t. 199 * 200 * \caprights{RW} 201 */ 202 long unlink(char const* name) 203 { 204 return unlink_t::call(c(), L4::Ipc::Array<char const, unsigned long>( 205 __builtin_strlen(name), name)); 206 } 207 208 typedef L4::Typeid::Rpcs<query_t, register_obj_t, unlink_t> Rpcs; 209 210private: 211 long _query(char const *name, unsigned len, 212 L4::Cap<void> const &target, l4_umword_t *local_id, 213 bool iterate) const noexcept; 214 215}; 216 217}; 218