L4Re Operating System Framework
Interface and Usage Documentation
•All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 * License: see LICENSE.spdx (in this directory or the directories above)
6 */
7
8#include <l4/re/env>
9#include <l4/sys/factory>
10#include <l4/cxx/minmax>
11
12#include "vcon_stream.h"
13
14#include <limits.h>
15#include <termios.h>
16#include <unistd.h>
17#include <sys/ioctl.h>
18#include <sys/ttydefaults.h>
19
20namespace L4Re { namespace Core {
21Vcon_stream::Vcon_stream(L4::Cap<L4::Vcon> s) noexcept
22: Be_file_stream(),
23 _s(s), _irq(L4Re::virt_cap_alloc->alloc<L4::Semaphore>()), _irq_bound(false)
24{
25 // [[maybe_unused]] int res =
26 l4_error(L4Re::Env::env()->factory()->create(_irq));
27 // (void)res; // handle errors!
28}
29
30ssize_t
31Vcon_stream::readv(const struct iovec *iovec, int iovcnt) noexcept
32{
33 if (iovcnt < 0)
34 return -EINVAL;
35
36 if (!_irq_bound)
37 {
38 bool was_bound = __atomic_exchange_n(&_irq_bound, true, __ATOMIC_SEQ_CST);
39 if (!was_bound)
40 if (l4_error(_s->bind(0, _irq)) < 0)
41 return -EIO;
42 }
43
44 ssize_t bytes = 0;
45 for (; iovcnt > 0; --iovcnt, ++iovec)
46 {
47 size_t len = cxx::min<size_t>(iovec->iov_len, SSIZE_MAX - bytes);
48 if (len == 0)
49 continue;
50
51 char *buf = static_cast<char *>(iovec->iov_base);
52
53 while (1)
54 {
55 size_t l = cxx::min<size_t>(L4_VCON_READ_SIZE, len);
56 int ret = _s->read(buf, l);
57
58 if (ret > static_cast<int>(l))
59 ret = l;
60
61 if (ret < 0)
62 return ret;
63 else if (ret == 0)
64 {
65 if (bytes)
66 return bytes;
67
68 ret = _s->read(buf, l);
69 if (ret < 0)
70 return ret;
71 else if (ret == 0)
72 {
73 _irq->down();
74 continue;
75 }
76 }
77
78 bytes += ret;
79 len -= ret;
80 buf += ret;
81
82 if (len == 0)
83 break;
84 }
85 }
86
87 return bytes;
88}
89
90ssize_t
91Vcon_stream::writev(const struct iovec *iovec, int iovcnt) noexcept
92{
93 l4_msg_regs_t store;
95
96 if (iovcnt < 0)
97 return -EINVAL;
98
99 Vfs_config::memcpy(&store, mr, sizeof(store));
100
101 ssize_t written = 0;
102 while (iovcnt)
103 {
104 size_t sl = cxx::min<size_t>(iovec->iov_len, SSIZE_MAX - written);
105 char const *b = static_cast<char const *>(iovec->iov_base);
106
107 for (; sl > L4_VCON_WRITE_SIZE
109 written += L4_VCON_WRITE_SIZE)
110 _s->send(b, L4_VCON_WRITE_SIZE);
111
112 _s->send(b, sl);
113
114 written += sl;
115
116 ++iovec;
117 --iovcnt;
118 }
119 Vfs_config::memcpy(mr, &store, sizeof(store));
120 return written;
121}
122
123int
124Vcon_stream::fstat64(struct stat64 *buf) const noexcept
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
133int
134Vcon_stream::ioctl(unsigned long request, va_list args) noexcept
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 -ENOTTY;
200}
201
202}}
static Env const * env() noexcept
Returns the initial environment for the current task.
Definition env:96
C++ interface for capabilities.
Definition capability.h:224
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:646
l4_msg_regs_t * l4_utcb_mr(void) L4_NOTHROW L4_PURE
Get the message-register block of a UTCB.
Definition utcb.h:358
@ L4_VCON_READ_SIZE
Maximum size that can be read with one l4_vcon_read* call.
Definition vcon.h:100
@ L4_VCON_WRITE_SIZE
Maximum size that can be written with one l4_vcon_write call.
Definition vcon.h:98
L4Re C++ Interfaces.
Definition cmd_control:14
Vcon attribute structure.
Definition vcon.h:188
l4_umword_t i_flags
input flags
Definition vcon.h:189
l4_umword_t o_flags
output flags
Definition vcon.h:190
l4_umword_t l_flags
local flags
Definition vcon.h:191
Encapsulation of the message-register block in the UTCB.
Definition utcb.h:68