L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
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#include <l4/cxx/minmax>
22
23#include "vcon_stream.h"
24
25#include <termios.h>
26#include <unistd.h>
27#include <sys/ioctl.h>
28#include <sys/ttydefaults.h>
29
30namespace L4Re { namespace Core {
31Vcon_stream::Vcon_stream(L4::Cap<L4::Vcon> s) noexcept
32: Be_file_stream(),
33 _s(s), _irq(L4Re::virt_cap_alloc->alloc<L4::Semaphore>()), _irq_bound(false)
34{
35 // [[maybe_unused]] int res =
36 l4_error(L4Re::Env::env()->factory()->create(_irq));
37 // (void)res; // handle errors!
38}
39
40ssize_t
41Vcon_stream::readv(const struct iovec *iovec, int iovcnt) noexcept
42{
43 if (iovcnt < 0)
44 return -EINVAL;
45
46 if (!_irq_bound)
47 {
48 bool was_bound = __atomic_exchange_n(&_irq_bound, true, __ATOMIC_SEQ_CST);
49 if (!was_bound)
50 if (l4_error(_s->bind(0, _irq)) < 0)
51 return -EIO;
52 }
53
54 ssize_t bytes = 0;
55 for (; iovcnt > 0; --iovcnt, ++iovec)
56 {
57 size_t len = cxx::min<size_t>(iovec->iov_len, SSIZE_MAX - bytes);
58 if (len == 0)
59 continue;
60
61 char *buf = static_cast<char *>(iovec->iov_base);
62
63 while (1)
64 {
65 size_t l = cxx::min<size_t>(L4_VCON_READ_SIZE, len);
66 int ret = _s->read(buf, l);
67
68 if (ret > static_cast<int>(l))
69 ret = l;
70
71 if (ret < 0)
72 return ret;
73 else if (ret == 0)
74 {
75 if (bytes)
76 return bytes;
77
78 ret = _s->read(buf, l);
79 if (ret < 0)
80 return ret;
81 else if (ret == 0)
82 {
83 _irq->down();
84 continue;
85 }
86 }
87
88 bytes += ret;
89 len -= ret;
90 buf += ret;
91
92 if (len == 0)
93 break;
94 }
95 }
96
97 return bytes;
98}
99
100ssize_t
101Vcon_stream::writev(const struct iovec *iovec, int iovcnt) noexcept
102{
103 l4_msg_regs_t store;
105
106 if (iovcnt < 0)
107 return -EINVAL;
108
109 Vfs_config::memcpy(&store, mr, sizeof(store));
110
111 ssize_t written = 0;
112 while (iovcnt)
113 {
114 size_t sl = cxx::min<size_t>(iovec->iov_len, SSIZE_MAX - written);
115 char const *b = static_cast<char const *>(iovec->iov_base);
116
117 for (; sl > L4_VCON_WRITE_SIZE
119 written += L4_VCON_WRITE_SIZE)
120 _s->send(b, L4_VCON_WRITE_SIZE);
121
122 _s->send(b, sl);
123
124 written += sl;
125
126 ++iovec;
127 --iovcnt;
128 }
129 Vfs_config::memcpy(mr, &store, sizeof(store));
130 return written;
131}
132
133int
134Vcon_stream::fstat64(struct stat64 *buf) const noexcept
135{
136 buf->st_size = 0;
137 buf->st_mode = 0666;
138 buf->st_dev = _s.cap();
139 buf->st_ino = 0;
140 return 0;
141}
142
143int
144Vcon_stream::ioctl(unsigned long request, va_list args) noexcept
145{
146 switch (request) {
147 case TCGETS:
148 {
149 //vt100_tcgetattr(term, (struct termios *)argp);
150
151 struct termios *t = va_arg(args, struct termios *);
152
153 l4_vcon_attr_t l4a;
154 if (!l4_error(_s->get_attr(&l4a)))
155 {
156 t->c_iflag = l4a.i_flags;
157 t->c_oflag = l4a.o_flags; // output flags
158 t->c_cflag = 0; // control flags
159 t->c_lflag = l4a.l_flags; // local flags
160 }
161 else
162 t->c_iflag = t->c_oflag = t->c_cflag = t->c_lflag = 0;
163#if 0
164 //t->c_lflag |= ECHO; // if term->echo
165 t->c_lflag |= ICANON; // if term->term_mode == VT100MODE_COOKED
166#endif
167
168 t->c_cc[VEOF] = CEOF;
169 t->c_cc[VEOL] = _POSIX_VDISABLE;
170 t->c_cc[VEOL2] = _POSIX_VDISABLE;
171 t->c_cc[VERASE] = CERASE;
172 t->c_cc[VWERASE] = CWERASE;
173 t->c_cc[VKILL] = CKILL;
174 t->c_cc[VREPRINT] = CREPRINT;
175 t->c_cc[VINTR] = CINTR;
176 t->c_cc[VQUIT] = _POSIX_VDISABLE;
177 t->c_cc[VSUSP] = CSUSP;
178 t->c_cc[VSTART] = CSTART;
179 t->c_cc[VSTOP] = CSTOP;
180 t->c_cc[VLNEXT] = CLNEXT;
181 t->c_cc[VDISCARD] = CDISCARD;
182 t->c_cc[VMIN] = CMIN;
183 t->c_cc[VTIME] = 0;
184
185 }
186
187 return 0;
188
189 case TCSETS:
190 case TCSETSW:
191 case TCSETSF:
192 {
193 //vt100_tcsetattr(term, (struct termios *)argp);
194 struct termios const *t = va_arg(args, struct termios const *);
195
196 // XXX: well, we're cheating, get this from the other side!
197
198 l4_vcon_attr_t l4a;
199 l4a.i_flags = t->c_iflag;
200 l4a.o_flags = t->c_oflag; // output flags
201 l4a.l_flags = t->c_lflag; // local flags
202 _s->set_attr(&l4a);
203 }
204 return 0;
205
206 default:
207 break;
208 };
209 return -ENOTTY;
210}
211
212}}
static Env const * env() noexcept
Returns the initial environment for the current task.
Definition env:103
C++ interface for capabilities.
Definition capability.h:219
Environment interface.
Common factory related definitions.
long l4_error(l4_msgtag_t tag) L4_NOTHROW
Get IPC error code if any or message tag label otherwise for an IPC call.
Definition ipc.h:657
l4_msg_regs_t * l4_utcb_mr(void) L4_NOTHROW L4_PURE
Get the message-register block of a UTCB.
Definition utcb.h:352
@ L4_VCON_READ_SIZE
Maximum size that can be read with one l4_vcon_read* call.
Definition vcon.h:111
@ L4_VCON_WRITE_SIZE
Maximum size that can be written with one l4_vcon_write call.
Definition vcon.h:109
L4Re C++ Interfaces.
Definition l4re.dox:17
Vcon attribute structure.
Definition vcon.h:197
l4_umword_t i_flags
input flags
Definition vcon.h:198
l4_umword_t o_flags
output flags
Definition vcon.h:199
l4_umword_t l_flags
local flags
Definition vcon.h:200
Encapsulation of the message-register block in the UTCB.
Definition utcb.h:79