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 "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 Ro_file::~Ro_file() throw()
30 {
31  if (_addr)
32  L4Re::Env::env()->rm()->detach(l4_addr_t(_addr), 0);
33 
34  release_ds(_ds);
35 }
36 
37 int
38 Ro_file::fstat64(struct stat64 *buf) const throw()
39 {
40  static int fake = 0;
41 
42  memset(buf, 0, sizeof(*buf));
43  buf->st_size = _size;
44  buf->st_mode = S_IFREG | 0644;
45  buf->st_dev = _ds.cap();
46  buf->st_ino = ++fake;
47  buf->st_blksize = L4_PAGESIZE;
48  buf->st_blocks = l4_round_page(_size);
49  return 0;
50 }
51 
52 ssize_t
53 Ro_file::read_single(const struct iovec *vec, off64_t pos) throw()
54 {
55  off64_t l = vec->iov_len;
56  if (_size - pos < l)
57  l = _size - pos;
58 
59  if (l > 0)
60  {
61  Vfs_config::memcpy(vec->iov_base, _addr + pos, l);
62  return l;
63  }
64 
65  return 0;
66 }
67 
68 ssize_t
69 Ro_file::preadv(const struct iovec *vec, int cnt, off64_t offset) throw()
70 {
71  if (!_addr)
72  {
73  void const *file = (void*)L4_PAGESIZE;
74  long err = L4Re::Env::env()->rm()->attach(&file, _size,
76  _ds, 0);
77 
78  if (err < 0)
79  return err;
80 
81  _addr = (char const *)file;
82  }
83 
84  ssize_t l = 0;
85 
86  while (cnt > 0)
87  {
88  ssize_t r = read_single(vec, offset);
89  offset += r;
90  l += r;
91 
92  if ((size_t)r < vec->iov_len)
93  return l;
94 
95  ++vec;
96  --cnt;
97  }
98  return l;
99 }
100 
101 ssize_t
102 Ro_file::pwritev(const struct iovec *, int, off64_t) throw()
103 {
104  return -EROFS;
105 }
106 
107 int
108 Ro_file::ioctl(unsigned long v, va_list args) throw()
109 {
110  switch (v)
111  {
112  case FIONREAD: // return amount of data still available
113  int *available = va_arg(args, int *);
114  *available = _size - pos();
115  return 0;
116  };
117  return -EINVAL;
118 }
119 
120 }}
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