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