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