]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re_vfs/include/impl/ro_file_impl.h
7f900174f5c54fe80b4e77a76df5f118940d2ac0
[l4.git] / l4 / pkg / l4re_vfs / include / impl / ro_file_impl.h
1 /*
2  * (c) 2010 Technische Universität Dresden
3  * This file is part of TUD:OS and distributed under the terms of the
4  * GNU General Public License 2.
5  * Please see the COPYING-GPL-2 file for details.
6  *
7  * As a special exception, you may use this file as part of a free software
8  * library without restriction.  Specifically, if other files instantiate
9  * templates or use macros or inline functions from this file, or you compile
10  * this file and link it with other files to produce an executable, this
11  * file does not by itself cause the resulting executable to be covered by
12  * the GNU General Public License.  This exception does not however
13  * invalidate any other reasons why the executable file might be covered by
14  * the GNU General Public License.
15  */
16
17 #include "ds_util.h"
18 #include "ro_file.h"
19
20 #include <l4/re/env>
21
22 namespace L4Re { namespace Core {
23
24
25 Simple_store<Ro_file> Ro_file::store;
26
27
28 void *
29 Ro_file::operator new(size_t s) throw()
30 {
31   if (s != sizeof(Ro_file))
32     return 0;
33
34   return store.alloc();
35 }
36
37 void
38 Ro_file::operator delete(void *b) throw()
39 {
40   store.free(b);
41 }
42
43
44 Ro_file::~Ro_file() throw()
45 {
46   if (_addr)
47     L4Re::Env::env()->rm()->detach(l4_addr_t(_addr), 0);
48
49   release_ds(_ds);
50 }
51
52 int
53 Ro_file::fstat64(struct stat64 *buf) const throw()
54 {
55   static int fake = 0;
56
57   memset(buf, 0, sizeof(*buf));
58   buf->st_size = _size;
59   buf->st_mode = S_IFREG | 0644;
60   buf->st_dev = _ds.cap();
61   buf->st_ino = ++fake;
62   buf->st_blksize = L4_PAGESIZE;
63   buf->st_blocks = l4_round_page(_size);
64   return 0;
65 }
66
67 ssize_t
68 Ro_file::read(const struct iovec *vec) throw()
69 {
70   off64_t l = vec->iov_len;
71   if (_size - _f_pos < l)
72     l = _size - _f_pos;
73
74   if (l > 0)
75     {
76       Vfs_config::memcpy(vec->iov_base, _addr + _f_pos, l);
77       _f_pos += l;
78       return l;
79     }
80
81   return 0;
82 }
83
84 ssize_t
85 Ro_file::readv(const struct iovec *vec, int cnt) throw()
86 {
87   if (!_addr)
88     {
89       void const *file = (void*)L4_PAGESIZE;
90       long err = L4Re::Env::env()->rm()->attach(&file, _size,
91           Rm::Search_addr | Rm::Read_only, _ds, 0);
92
93       if (err < 0)
94         return err;
95
96       _addr = (char const *)file;
97     }
98
99   ssize_t l = 0;
100
101   while (cnt > 0)
102     {
103       ssize_t r = read(vec);
104       l += r;
105
106       if ((size_t)r < vec->iov_len)
107         return l;
108
109       ++vec;
110       --cnt;
111     }
112   return l;
113 }
114
115 ssize_t
116 Ro_file::writev(const struct iovec*, int iovcnt) throw()
117 {
118   (void)iovcnt;
119   return -EBADF;
120 }
121
122 off64_t
123 Ro_file::lseek64(off64_t offset, int whence) throw()
124 {
125   off64_t r;
126   switch (whence)
127     {
128     case SEEK_SET: r = offset; break;
129     case SEEK_CUR: r = _f_pos + offset; break;
130     case SEEK_END: r = _size + offset; break;
131     default: return -EINVAL;
132     };
133
134   if (r < 0)
135     return -EINVAL;
136
137   _f_pos = r;
138
139   return _f_pos;
140 }
141
142 }}