L4Re - L4 Runtime Environment
backend
1 // vi:set ft=cpp: -*- Mode: C++ -*-
2 /*
3  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4  * Alexander Warg <warg@os.inf.tu-dresden.de>
5  * economic rights: Technische Universit├Ąt Dresden (Germany)
6  *
7  * This file is part of TUD:OS and distributed under the terms of the
8  * GNU General Public License 2.
9  * Please see the COPYING-GPL-2 file for details.
10  *
11  * As a special exception, you may use this file as part of a free software
12  * library without restriction. Specifically, if other files instantiate
13  * templates or use macros or inline functions from this file, or you compile
14  * this file and link it with other files to produce an executable, this
15  * file does not by itself cause the resulting executable to be covered by
16  * the GNU General Public License. This exception does not however
17  * invalidate any other reasons why the executable file might be covered by
18  * the GNU General Public License.
19  */
20 #pragma once
21 
22 #include <l4/l4re_vfs/vfs.h>
23 #include <l4/crtn/initpriorities.h>
24 
25 namespace L4Re { namespace Vfs {
26 
27 /// Reference to the applications L4Re::Vfs::Ops singleton.
28 extern L4Re::Vfs::Ops *vfs_ops asm ("l4re_env_posix_vfs_ops");
29 extern L4Re::Cap_alloc *vfs_cap_alloc asm ("l4re_env_posix_vfs_cap_alloc");
30 
31 class Mount_tree;
32 
33 /**
34  * \brief Boiler plate class for implementing an open file for L4Re::Vfs.
35  *
36  * This class may be used as a base class for everything that a POSIX
37  * file descriptor may point to. This are things such as regular files,
38  * directories, special device files, streams, pipes, and so on.
39  */
40 class Be_file : public File
41 {
42 public:
43  void *operator new (size_t size) throw()
44  { return vfs_ops->malloc(size); }
45 
46  void *operator new (size_t, void *m) throw()
47  { return m; }
48 
49  void operator delete (void *m)
50  { vfs_ops->free(m); }
51 
52  // used in close, to unlock all locks of a file (as POSIX says)
53  int unlock_all_locks() throw()
54  { return 0; }
55 
56  // for mmap
57  L4::Cap<L4Re::Dataspace> data_space() const throw()
58  { return L4::Cap<L4Re::Dataspace>::Invalid; }
59 
60  /// Default backend for POSIX read and readv functions.
61  ssize_t readv(const struct iovec*, int) throw()
62  { return -EINVAL; }
63 
64  /// Default backend for POSIX write and writev functions.
65  ssize_t writev(const struct iovec*, int) throw()
66  { return -EINVAL; }
67 
68  /// Default backend for POSIX pwrite and pwritev functions.
69  ssize_t pwritev(const struct iovec*, int, off64_t) throw()
70  { return -EINVAL; }
71 
72  /// Default backend for POSIX pread and preadv functions.
73  ssize_t preadv(const struct iovec*, int, off64_t) throw()
74  { return -EINVAL; }
75 
76  /// Default backend for POSIX seek and lseek functions.
77  off64_t lseek64(off64_t, int) throw()
78  { return -ESPIPE; }
79 
80  /// Default backend for the POSIX truncate, ftruncate and similar functions.
81  int ftruncate64(off64_t) throw()
82  { return -EINVAL; }
83 
84  /// Default backend for POSIX fsync.
85  int fsync() const throw()
86  { return -EINVAL; }
87 
88  /// Default backend for POSIX fdatasync.
89  int fdatasync() const throw()
90  { return -EINVAL; }
91 
92  /// Default backend for POSIX ioctl.
93  int ioctl(unsigned long, va_list) throw()
94  { return -EINVAL; }
95 
96  int fstat64(struct stat64 *) const throw()
97  { return -EINVAL; }
98 
99  /// Default backend for POSIX chmod and fchmod.
100  int fchmod(mode_t) throw()
101  { return -EINVAL; }
102 
103  /// Default backend for POSIX fcntl subfunctions.
104  int get_status_flags() const throw()
105  { return 0; }
106 
107  /// Default backend for POSIX fcntl subfunctions.
108  int set_status_flags(long) throw()
109  { return 0; }
110 
111  /// Default backend for POSIX fcntl subfunctions.
112  int get_lock(struct flock64 *) throw()
113  { return -ENOLCK; }
114 
115  /// Default backend for POSIX fcntl subfunctions.
116  int set_lock(struct flock64 *, bool) throw()
117  { return -ENOLCK; }
118 
119  /// Default backend for POSIX access and faccessat functions.
120  int faccessat(const char *, int, int) throw()
121  { return -ENOTDIR; }
122 
123  /// Default backend for POSIX utime.
124  int utime(const struct utimbuf *) throw()
125  { return -EROFS; }
126 
127  /// Default backend for POSIX utimes.
128  int utimes(const struct timeval [2]) throw()
129  { return -EROFS; }
130 
131  /// Default backend for POSIX mkdir and mkdirat.
132  int mkdir(const char *, mode_t) throw()
133  { return -ENOTDIR; }
134 
135  /// Default backend for POSIX unlink, unlinkat.
136  int unlink(const char *) throw()
137  { return -ENOTDIR; }
138 
139  /// Default backend for POSIX rename, renameat.
140  int rename(const char *, const char *) throw()
141  { return -ENOTDIR; }
142 
143  /// Default backend for POSIX link, linkat.
144  int link(const char *, const char *) throw()
145  { return -ENOTDIR; }
146 
147  /// Default backend for POSIX symlink, symlinkat.
148  int symlink(const char *, const char *) throw()
149  { return -EPERM; }
150 
151  /// Default backend for POSIX rmdir, rmdirat.
152  int rmdir(const char *) throw()
153  { return -ENOTDIR; }
154 
155  /// Default backend for POSIX readlink, readlinkat.
156  ssize_t readlink(char *, size_t)
157  { return -EINVAL; }
158 
159  ssize_t getdents(char *, size_t) throw()
160  { return -ENOTDIR; }
161 
162 
163 
164  // Socket interface
165  int bind(sockaddr const *, socklen_t) throw()
166  { return -ENOTSOCK; }
167 
168  int connect(sockaddr const *, socklen_t) throw()
169  { return -ENOTSOCK; }
170 
171  ssize_t send(void const *, size_t, int) throw()
172  { return -ENOTSOCK; }
173 
174  ssize_t recv(void *, size_t, int) throw()
175  { return -ENOTSOCK; }
176 
177  ssize_t sendto(void const *, size_t, int, sockaddr const *, socklen_t) throw()
178  { return -ENOTSOCK; }
179 
180  ssize_t recvfrom(void *, size_t, int, sockaddr *, socklen_t *) throw()
181  { return -ENOTSOCK; }
182 
183  ssize_t sendmsg(msghdr const *, int) throw()
184  { return -ENOTSOCK; }
185 
186  ssize_t recvmsg(msghdr *, int) throw()
187  { return -ENOTSOCK; }
188 
189  int getsockopt(int, int, void *, socklen_t *) throw()
190  { return -ENOTSOCK; }
191 
192  int setsockopt(int, int, void const *, socklen_t) throw()
193  { return -ENOTSOCK; }
194 
195  int listen(int) throw()
196  { return -ENOTSOCK; }
197 
198  int accept(sockaddr *, socklen_t *) throw()
199  { return -ENOTSOCK; }
200 
201  int shutdown(int) throw()
202  { return -ENOTSOCK; }
203 
204  int getsockname(sockaddr *, socklen_t *) throw()
205  { return -ENOTSOCK; }
206 
207  int getpeername(sockaddr *, socklen_t *) throw()
208  { return -ENOTSOCK; }
209 
210  ~Be_file() throw() = 0;
211 
212 private:
213  /// Default backend for POSIX openat, open.
214  int get_entry(const char *, int, mode_t, cxx::Ref_ptr<File> *) throw()
215  { return -ENOTDIR; }
216 
217 protected:
218  const char *get_mount(const char *path, cxx::Ref_ptr<File> *dir) throw();
219 };
220 
221 inline
222 Be_file::~Be_file() throw() {}
223 
224 class Be_file_pos : public Be_file
225 {
226 public:
227  Be_file_pos() throw() : Be_file(), _pos(0) {}
228 
229  virtual off64_t size() const throw() = 0;
230 
231  ssize_t readv(const struct iovec *v, int iovcnt) throw()
232  {
233  ssize_t r = preadv(v, iovcnt, _pos);
234  if (r > 0)
235  _pos += r;
236  return r;
237  }
238 
239  ssize_t writev(const struct iovec *v, int iovcnt) throw()
240  {
241  ssize_t r = pwritev(v, iovcnt, _pos);
242  if (r > 0)
243  _pos += r;
244  return r;
245  }
246 
247  ssize_t preadv(const struct iovec *v, int iovcnt, off64_t offset) throw() = 0;
248  ssize_t pwritev(const struct iovec *v, int iovcnt, off64_t offset) throw() = 0;
249 
250  off64_t lseek64(off64_t offset, int whence) throw()
251  {
252  off64_t r;
253  switch (whence)
254  {
255  case SEEK_SET: r = offset; break;
256  case SEEK_CUR: r = _pos + offset; break;
257  case SEEK_END: r = size() + offset; break;
258  default: return -EINVAL;
259  };
260 
261  if (r < 0)
262  return -EINVAL;
263 
264  _pos = r;
265  return _pos;
266  }
267 
268  ~Be_file_pos() throw() = 0;
269 
270 protected:
271  off64_t pos() const throw() { return _pos; }
272 
273 private:
274  off64_t _pos;
275 };
276 
277 inline Be_file_pos::~Be_file_pos() throw() {}
278 
279 class Be_file_stream : public Be_file
280 {
281 public:
282  ssize_t preadv(const struct iovec *v, int iovcnt, off64_t) throw()
283  { return readv(v, iovcnt); }
284 
285  ssize_t pwritev(const struct iovec *v, int iovcnt, off64_t) throw()
286  { return writev(v, iovcnt); }
287 
288  ~Be_file_stream() throw () = 0;
289 
290 };
291 
292 inline Be_file_stream::~Be_file_stream() throw() {}
293 
294 /**
295  * \brief Boilerplate class for implementing a L4Re::Vfs::File_system.
296  *
297  * This class already takes care of registering and unregistering the
298  * file system in the global registry and implements the type() method.
299  */
300 class Be_file_system : public File_system
301 {
302 private:
303  char const *const _fstype;
304 
305 public:
306 
307  /**
308  * \brief Create a file-system object for the given \a fstype.
309  * \param fstype The type that type() shall return.
310  *
311  * This constructor takes care of registering the file system
312  * in the registry of L4Re::Vfs::vfs_ops.
313  */
314  explicit Be_file_system(char const *fstype) throw()
315  : File_system(), _fstype(fstype)
316  {
317  vfs_ops->register_file_system(this);
318  }
319 
320  /**
321  * \brief Destroy a file-system object.
322  *
323  * This destructor takes care of removing this file system
324  * from the registry of L4Re::Vfs::vfs_ops.
325  */
326  ~Be_file_system() throw()
327  {
328  vfs_ops->unregister_file_system(this);
329  }
330 
331  /**
332  * \brief Return the file-system type.
333  *
334  * Returns the file-system type given as \a fstype in the constructor.
335  */
336  char const *type() const throw() { return _fstype; }
337 };
338 
339 /* Make sure filesystems can register before the constructor of libmount
340  * runs */
341 #define L4RE_VFS_FILE_SYSTEM_ATTRIBUTE \
342  __attribute__((init_priority(INIT_PRIO_LATE)))
343 
344 }}