]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re_vfs/include/backend
update
[l4.git] / l4 / pkg / l4re_vfs / include / backend
1 // vi:ft=cpp
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
30 class Mount_tree;
31
32 /**
33  * \brief Boiler plate class for implementing an open file for L4Re::Vfs.
34  *
35  * This class may be used as a base class for everything that a POSIX
36  * file descriptor may point to. This are things such as regular files,
37  * directories, special device files, streams, pipes, and so on.
38  */
39 class Be_file : public File
40 {
41 public:
42   // used in close, to unlock all locks of a file (as POSIX says)
43   int unlock_all_locks() throw()
44   { return 0; }
45
46   // for mmap
47   L4::Cap<L4Re::Dataspace> data_space() const throw()
48   { return L4::Cap<L4Re::Dataspace>::Invalid; }
49
50   /// Default backend for POSIX read and readv functions.
51   ssize_t readv(const struct iovec*, int) throw()
52   { return -EINVAL; }
53
54   /// Default backend for POSIX write and writev functions.
55   ssize_t writev(const struct iovec*, int) throw()
56   { return -EINVAL; }
57
58   /// Default backend for POSIX pwrite and pwritev functions.
59   ssize_t pwritev(const struct iovec*, int, off64_t) throw()
60   { return -EINVAL; }
61
62   /// Default backend for POSIX pread and preadv functions.
63   ssize_t preadv(const struct iovec*, int, off64_t) throw()
64   { return -EINVAL; }
65
66   /// Default backend for POSIX seek and lseek functions.
67   off64_t lseek64(off64_t, int) throw()
68   { return -ESPIPE; }
69
70   /// Default backend for the POSIX truncate, ftruncate and similar functions.
71   int ftruncate64(off64_t) throw()
72   { return -EINVAL; }
73
74   /// Default backend for POSIX fsync.
75   int fsync() const throw()
76   { return -EINVAL; }
77
78   /// Default backend for POSIX fdatasync.
79   int fdatasync() const throw()
80   { return -EINVAL; }
81
82   /// Default backend for POSIX ioctl.
83   int ioctl(unsigned long, va_list) throw()
84   { return -EINVAL; }
85
86   int fstat64(struct stat64 *) const throw()
87   { return -EINVAL; }
88
89   /// Default backend for POSIX chmod and fchmod.
90   int fchmod(mode_t) throw()
91   { return -EINVAL; }
92
93   /// Default backend for POSIX fcntl subfunctions.
94   int get_status_flags() const throw()
95   { return 0; }
96
97   /// Default backend for POSIX fcntl subfunctions.
98   int set_status_flags(long) throw()
99   { return 0; }
100
101   /// Default backend for POSIX fcntl subfunctions.
102   int get_lock(struct flock64 *) throw()
103   { return -ENOLCK; }
104
105   /// Default backend for POSIX fcntl subfunctions.
106   int set_lock(struct flock64 *, bool) throw()
107   { return -ENOLCK; }
108
109   /// Default backend for POSIX access and faccessat functions.
110   int faccessat(const char *, int, int) throw()
111   { return -ENOTDIR; }
112
113   /// Default backend for POSIX utime.
114   int utime(const struct utimbuf *) throw()
115   { return -EROFS; }
116
117   /// Default backend for POSIX utimes.
118   int utimes(const struct timeval [2]) throw()
119   { return -EROFS; }
120
121   /// Default backend for POSIX mkdir and mkdirat.
122   int mkdir(const char *, mode_t) throw()
123   { return -ENOTDIR; }
124
125   /// Default backend for POSIX unlink, unlinkat.
126   int unlink(const char *) throw()
127   { return -ENOTDIR; }
128
129   /// Default backend for POSIX rename, renameat.
130   int rename(const char *, const char *) throw()
131   { return -ENOTDIR; }
132
133   /// Default backend for POSIX link, linkat.
134   int link(const char *, const char *) throw()
135   { return -ENOTDIR; }
136
137   /// Default backend for POSIX symlink, symlinkat.
138   int symlink(const char *, const char *) throw()
139   { return -EPERM; }
140
141   /// Default backend for POSIX rmdir, rmdirat.
142   int rmdir(const char *) throw()
143   { return -ENOTDIR; }
144
145   /// Default backend for POSIX readlink, readlinkat.
146   ssize_t readlink(char *, size_t)
147   { return -EINVAL; }
148
149   ssize_t getdents(char *, size_t) throw()
150   { return -ENOTDIR; }
151
152
153
154   // Socket interface
155   int bind(sockaddr const *, socklen_t) throw()
156   { return -ENOTSOCK; }
157
158   int connect(sockaddr const *, socklen_t) throw()
159   { return -ENOTSOCK; }
160
161   ssize_t send(void const *, size_t, int) throw()
162   { return -ENOTSOCK; }
163
164   ssize_t recv(void *, size_t, int) throw()
165   { return -ENOTSOCK; }
166
167   ssize_t sendto(void const *, size_t, int, sockaddr const *, socklen_t) throw()
168   { return -ENOTSOCK; }
169
170   ssize_t recvfrom(void *, size_t, int, sockaddr *, socklen_t *) throw()
171   { return -ENOTSOCK; }
172
173   ssize_t sendmsg(msghdr const *, int) throw()
174   { return -ENOTSOCK; }
175
176   ssize_t recvmsg(msghdr *, int) throw()
177   { return -ENOTSOCK; }
178
179   int getsockopt(int, int, void *, socklen_t *) throw()
180   { return -ENOTSOCK; }
181
182   int setsockopt(int, int, void const *, socklen_t) throw()
183   { return -ENOTSOCK; }
184
185   int listen(int) throw()
186   { return -ENOTSOCK; }
187
188   int accept(sockaddr *, socklen_t *) throw()
189   { return -ENOTSOCK; }
190
191   int shutdown(int) throw()
192   { return -ENOTSOCK; }
193
194   int getsockname(sockaddr *, socklen_t *) throw()
195   { return -ENOTSOCK; }
196
197   int getpeername(sockaddr *, socklen_t *) throw()
198   { return -ENOTSOCK; }
199
200   ~Be_file() throw() = 0;
201
202 private:
203   /// Default backend for POSIX openat, open.
204   int get_entry(const char *, int, mode_t, cxx::Ref_ptr<File> *) throw()
205   { return -ENOTDIR; }
206
207 protected:
208   const char *get_mount(const char *path, cxx::Ref_ptr<File> *dir) throw();
209 };
210
211 inline
212 Be_file::~Be_file() throw() {}
213
214 class Be_file_pos : public Be_file
215 {
216 public:
217   Be_file_pos() throw() : Be_file(), _pos(0) {}
218
219   virtual off64_t size() const throw() = 0;
220
221   ssize_t readv(const struct iovec *v, int iovcnt) throw()
222   {
223     ssize_t r = preadv(v, iovcnt, _pos);
224     if (r > 0)
225       _pos += r;
226     return r;
227   }
228
229   ssize_t writev(const struct iovec *v, int iovcnt) throw()
230   {
231     ssize_t r = pwritev(v, iovcnt, _pos);
232     if (r > 0)
233       _pos += r;
234     return r;
235   }
236
237   ssize_t preadv(const struct iovec *v, int iovcnt, off64_t offset) throw() = 0;
238   ssize_t pwritev(const struct iovec *v, int iovcnt, off64_t offset) throw() = 0;
239
240   off64_t lseek64(off64_t offset, int whence) throw()
241   {
242     off64_t r;
243     switch (whence)
244       {
245       case SEEK_SET: r = offset; break;
246       case SEEK_CUR: r = _pos + offset; break;
247       case SEEK_END: r = size() + offset; break;
248       default: return -EINVAL;
249       };
250
251     if (r < 0)
252       return -EINVAL;
253
254     _pos = r;
255     return _pos;
256   }
257
258   ~Be_file_pos() throw() = 0;
259
260 protected:
261   off64_t pos() const throw() { return _pos; }
262
263 private:
264   off64_t _pos;
265 };
266
267 inline Be_file_pos::~Be_file_pos() throw() {}
268
269 class Be_file_stream : public Be_file
270 {
271 public:
272   ssize_t preadv(const struct iovec *v, int iovcnt, off64_t) throw()
273   { return readv(v, iovcnt); }
274
275   ssize_t pwritev(const struct iovec *v, int iovcnt, off64_t) throw()
276   { return writev(v, iovcnt); }
277
278   ~Be_file_stream() throw () = 0;
279
280 };
281
282 inline Be_file_stream::~Be_file_stream() throw() {}
283
284 /**
285  * \brief Boilerplate class for implementing a L4Re::Vfs::File_system.
286  *
287  * This class already takes care of registering and unregistering the
288  * file system in the global registry and implements the type() method.
289  */
290 class Be_file_system : public File_system
291 {
292 private:
293   char const *const _fstype;
294
295 public:
296
297   /**
298    * \brief Create a file-system object for the given \a fstype.
299    * \param fstype The type that type() shall return.
300    *
301    * This constructor takes care of registering the file system
302    * in the registry of L4Re::Vfs::vfs_ops.
303    */
304   explicit Be_file_system(char const *fstype) throw()
305   : File_system(), _fstype(fstype)
306   {
307     vfs_ops->register_file_system(this);
308   }
309
310   /**
311    * \brief Destroy a file-system object.
312    *
313    * This destructor takes care of removing this file system
314    * from the registry of L4Re::Vfs::vfs_ops.
315    */
316   ~Be_file_system() throw()
317   {
318     vfs_ops->unregister_file_system(this);
319   }
320
321   /**
322    * \brief Return the file-system type.
323    *
324    * Returns the file-system type given as \a fstype in the constructor.
325    */
326   char const *type() const throw() { return _fstype; }
327 };
328
329 /* Make sure filesystems can register before the constructor of libmount
330  * runs */
331 #define L4RE_VFS_FILE_SYSTEM_ATTRIBUTE \
332      __attribute__((init_priority(INIT_PRIO_LATE)))
333
334 }}