L4Re - L4 Runtime Environment
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 "ro_file.h"
21 
22 #include <sys/ioctl.h>
23 
24 #include <l4/re/env>
25 
26 namespace L4Re { namespace Core {
27 
28 Ro_file::~Ro_file() throw()
29 {
30  if (_addr)
31  L4Re::Env::env()->rm()->detach(l4_addr_t(_addr), 0);
32 
33  L4Re::virt_cap_alloc->release(_ds);
34 }
35 
36 int
37 Ro_file::fstat64(struct stat64 *buf) const throw()
38 {
39  static int fake = 0;
40 
41  memset(buf, 0, sizeof(*buf));
42  buf->st_size = _size;
43  buf->st_mode = S_IFREG | 0644;
44  buf->st_dev = _ds.cap();
45  buf->st_ino = ++fake;
46  buf->st_blksize = L4_PAGESIZE;
47  buf->st_blocks = l4_round_page(_size);
48  return 0;
49 }
50 
51 ssize_t
52 Ro_file::read_single(const struct iovec *vec, off64_t pos) throw()
53 {
54  off64_t l = vec->iov_len;
55  if (_size - pos < l)
56  l = _size - pos;
57 
58  if (l > 0)
59  {
60  Vfs_config::memcpy(vec->iov_base, _addr + pos, l);
61  return l;
62  }
63 
64  return 0;
65 }
66 
67 ssize_t
68 Ro_file::preadv(const struct iovec *vec, int cnt, off64_t offset) throw()
69 {
70  if (!_addr)
71  {
72  void const *file = (void*)L4_PAGESIZE;
73  long err = L4Re::Env::env()->rm()->attach(&file, _size,
75  _ds, 0);
76 
77  if (err < 0)
78  return err;
79 
80  _addr = (char const *)file;
81  }
82 
83  ssize_t l = 0;
84 
85  while (cnt > 0)
86  {
87  ssize_t r = read_single(vec, offset);
88  offset += r;
89  l += r;
90 
91  if ((size_t)r < vec->iov_len)
92  return l;
93 
94  ++vec;
95  --cnt;
96  }
97  return l;
98 }
99 
100 ssize_t
101 Ro_file::pwritev(const struct iovec *, int, off64_t) throw()
102 {
103  return -EROFS;
104 }
105 
106 int
107 Ro_file::ioctl(unsigned long v, va_list args) throw()
108 {
109  switch (v)
110  {
111  case FIONREAD: // return amount of data still available
112  int *available = va_arg(args, int *);
113  *available = _size - pos();
114  return 0;
115  };
116  return -EINVAL;
117 }
118 
119 }}
l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
Round address up to the next page.
Definition: consts.h:359
L4Re C++ Interfaces.
Definition: cmd_control:15
Search for a suitable address range.
Definition: rm:113
Environment interface.
#define L4_PAGESIZE
Minimal page size (in bytes).
Definition: consts.h:277
static Env const * env()
Returns the initial environment for the current task.
Definition: env:100
Region is read-only.
Definition: rm:88
unsigned long l4_addr_t
Address type.
Definition: l4int.h:45
L4::Cap< Rm > rm() const
Object-capability to the region map.
Definition: env:124