L4Re - L4 Runtime Environment
vcon_stream_impl.h
1 /*
2  * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3  * economic rights: Technische Universit├Ąt Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  *
9  * As a special exception, you may use this file as part of a free software
10  * library without restriction. Specifically, if other files instantiate
11  * templates or use macros or inline functions from this file, or you compile
12  * this file and link it with other files to produce an executable, this
13  * file does not by itself cause the resulting executable to be covered by
14  * the GNU General Public License. This exception does not however
15  * invalidate any other reasons why the executable file might be covered by
16  * the GNU General Public License.
17  */
18 
19 #include <l4/re/env>
20 #include <l4/sys/factory>
21 
22 #include "vcon_stream.h"
23 #include "vfs_api.h"
24 
25 #include <termios.h>
26 #include <unistd.h>
27 #include <sys/ioctl.h>
28 #include <sys/ttydefaults.h>
29 
30 namespace L4Re { namespace Core {
31 Vcon_stream::Vcon_stream(L4::Cap<L4::Vcon> s) throw()
32 : Be_file_stream(), _s(s), _irq(cap_alloc()->alloc<L4::Semaphore>())
33 {
34  //printf("VCON: irq cap = %lx\n", _irq.cap());
35  int res = l4_error(L4Re::Env::env()->factory()->create(_irq));
36  //printf("VCON: irq create res=%d\n", res);
37 
38  if (res < 0)
39  return; // handle errors!!!
40 
41  res = l4_error(_s->bind(0, _irq));
42  //printf("VCON: bound irq to con res=%d\n", res);
43 }
44 
45 ssize_t
46 Vcon_stream::readv(const struct iovec *iovec, int iovcnt) throw()
47 {
48  ssize_t bytes = 0;
49  for (; iovcnt > 0; --iovcnt, ++iovec)
50  {
51  if (iovec->iov_len == 0)
52  continue;
53 
54  char *buf = (char *)iovec->iov_base;
55  size_t len = iovec->iov_len;
56 
57  while (1)
58  {
59  int ret = _s->read(buf, len);
60 
61  // BS: what is this ??
62  if (ret > (int)len)
63  ret = len;
64 
65  if (ret < 0)
66  return ret;
67  else if (ret == 0)
68  {
69  if (bytes)
70  return bytes;
71 
72  ret = _s->read(buf, len);
73  if (ret < 0)
74  return ret;
75  else if (ret == 0)
76  {
77  _irq->down();
78  continue;
79  }
80  }
81 
82  bytes += ret;
83  len -= ret;
84  buf += ret;
85 
86  if (len == 0)
87  break;
88  }
89  }
90 
91  return bytes;
92 }
93 
94 ssize_t
95 Vcon_stream::writev(const struct iovec *iovec, int iovcnt) throw()
96 {
97  l4_msg_regs_t store;
98  l4_msg_regs_t *mr = l4_utcb_mr();
99 
100  Vfs_config::memcpy(&store, mr, sizeof(store));
101 
102  ssize_t written = 0;
103  while (iovcnt)
104  {
105  size_t sl = iovec->iov_len;
106  char const *b = (char const *)iovec->iov_base;
107 
108  for (; sl > L4_VCON_WRITE_SIZE
110  _s->send(b, L4_VCON_WRITE_SIZE);
111 
112  _s->send(b, sl);
113 
114  written += iovec->iov_len;
115 
116  ++iovec;
117  --iovcnt;
118  }
119  Vfs_config::memcpy(mr, &store, sizeof(store));
120  return written;
121 }
122 
123 int
124 Vcon_stream::fstat64(struct stat64 *buf) const throw()
125 {
126  buf->st_size = 0;
127  buf->st_mode = 0666;
128  buf->st_dev = _s.cap();
129  buf->st_ino = 0;
130  return 0;
131 }
132 
133 int
134 Vcon_stream::ioctl(unsigned long request, va_list args) throw()
135 {
136  switch (request) {
137  case TCGETS:
138  {
139  //vt100_tcgetattr(term, (struct termios *)argp);
140 
141  struct termios *t = va_arg(args, struct termios *);
142 
143  l4_vcon_attr_t l4a;
144  if (!l4_error(_s->get_attr(&l4a)))
145  {
146  t->c_iflag = l4a.i_flags;
147  t->c_oflag = l4a.o_flags; // output flags
148  t->c_cflag = 0; // control flags
149  t->c_lflag = l4a.l_flags; // local flags
150  }
151  else
152  t->c_iflag = t->c_oflag = t->c_cflag = t->c_lflag = 0;
153 #if 0
154  //t->c_lflag |= ECHO; // if term->echo
155  t->c_lflag |= ICANON; // if term->term_mode == VT100MODE_COOKED
156 #endif
157 
158  t->c_cc[VEOF] = CEOF;
159  t->c_cc[VEOL] = _POSIX_VDISABLE;
160  t->c_cc[VEOL2] = _POSIX_VDISABLE;
161  t->c_cc[VERASE] = CERASE;
162  t->c_cc[VWERASE]= CWERASE;
163  t->c_cc[VKILL] = CKILL;
164  t->c_cc[VREPRINT]=CREPRINT;
165  t->c_cc[VINTR] = CINTR;
166  t->c_cc[VQUIT] = _POSIX_VDISABLE;
167  t->c_cc[VSUSP] = CSUSP;
168  t->c_cc[VSTART] = CSTART;
169  t->c_cc[VSTOP] = CSTOP;
170  t->c_cc[VLNEXT] = CLNEXT;
171  t->c_cc[VDISCARD]=CDISCARD;
172  t->c_cc[VMIN] = CMIN;
173  t->c_cc[VTIME] = 0;
174 
175  }
176 
177  return 0;
178 
179  case TCSETS:
180  case TCSETSW:
181  case TCSETSF:
182  {
183  //vt100_tcsetattr(term, (struct termios *)argp);
184  struct termios const *t = va_arg(args, struct termios const *);
185 
186  // XXX: well, we're cheating, get this from the other side!
187 
188  l4_vcon_attr_t l4a;
189  l4a.i_flags = t->c_iflag;
190  l4a.o_flags = t->c_oflag; // output flags
191  l4a.l_flags = t->c_lflag; // local flags
192  _s->set_attr(&l4a);
193  }
194  return 0;
195 
196  default:
197  break;
198  };
199  return -EINVAL;
200 }
201 
202 }}
Encapsulation of the message-register block in the UTCB.
Definition: utcb.h:78
Vcon attribute structure.
Definition: vcon.h:178
l4_umword_t o_flags
output flags
Definition: vcon.h:181
L4Re C++ Interfaces.
Definition: cmd_control:15
Environment interface.
l4_msg_regs_t * l4_utcb_mr(void) L4_NOTHROW L4_PURE
Get the message-register block of a UTCB.
Definition: utcb.h:352
Maximum size that can be written with one l4_vcon_write call.
Definition: vcon.h:98
static Env const * env()
Returns the initial environment for the current task.
Definition: env:100
_Cap_alloc & cap_alloc
Capability allocator.
l4_umword_t l_flags
local flags
Definition: vcon.h:182
long l4_error(l4_msgtag_t tag) L4_NOTHROW
Return error code of a system call return message tag.
Definition: ipc.h:517
Common factory related definitions.
l4_umword_t i_flags
input flags
Definition: vcon.h:180