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