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
24 #include <termios.h>
25 #include <unistd.h>
26 #include <sys/ioctl.h>
27 #include <sys/ttydefaults.h>
28
29 namespace L4Re { namespace Core {
Vcon_stream(L4::Cap<L4::Vcon> s)30 Vcon_stream::Vcon_stream(L4::Cap<L4::Vcon> s) throw()
31 : Be_file_stream(), _s(s), _irq(L4Re::virt_cap_alloc->alloc<L4::Semaphore>())
32 {
33 //printf("VCON: irq cap = %lx\n", _irq.cap());
34 int res = l4_error(L4Re::Env::env()->factory()->create(_irq));
35 //printf("VCON: irq create res=%d\n", res);
36
37 if (res < 0)
38 return; // handle errors!!!
39
40 res = l4_error(_s->bind(0, _irq));
41 //printf("VCON: bound irq to con res=%d\n", res);
42 }
43
44 ssize_t
readv(const struct iovec * iovec,int iovcnt)45 Vcon_stream::readv(const struct iovec *iovec, int iovcnt) throw()
46 {
47 ssize_t bytes = 0;
48 for (; iovcnt > 0; --iovcnt, ++iovec)
49 {
50 if (iovec->iov_len == 0)
51 continue;
52
53 char *buf = (char *)iovec->iov_base;
54 size_t len = iovec->iov_len;
55
56 while (1)
57 {
58 int ret = _s->read(buf, len);
59
60 // BS: what is this ??
61 if (ret > (int)len)
62 ret = len;
63
64 if (ret < 0)
65 return ret;
66 else if (ret == 0)
67 {
68 if (bytes)
69 return bytes;
70
71 ret = _s->read(buf, len);
72 if (ret < 0)
73 return ret;
74 else if (ret == 0)
75 {
76 _irq->down();
77 continue;
78 }
79 }
80
81 bytes += ret;
82 len -= ret;
83 buf += ret;
84
85 if (len == 0)
86 break;
87 }
88 }
89
90 return bytes;
91 }
92
93 ssize_t
writev(const struct iovec * iovec,int iovcnt)94 Vcon_stream::writev(const struct iovec *iovec, int iovcnt) throw()
95 {
96 l4_msg_regs_t store;
97 l4_msg_regs_t *mr = l4_utcb_mr();
98
99 Vfs_config::memcpy(&store, mr, sizeof(store));
100
101 ssize_t written = 0;
102 while (iovcnt)
103 {
104 size_t sl = iovec->iov_len;
105 char const *b = (char const *)iovec->iov_base;
106
107 for (; sl > L4_VCON_WRITE_SIZE
108 ; sl -= L4_VCON_WRITE_SIZE, b += L4_VCON_WRITE_SIZE)
109 _s->send(b, L4_VCON_WRITE_SIZE);
110
111 _s->send(b, sl);
112
113 written += iovec->iov_len;
114
115 ++iovec;
116 --iovcnt;
117 }
118 Vfs_config::memcpy(mr, &store, sizeof(store));
119 return written;
120 }
121
122 int
fstat64(struct stat64 * buf)123 Vcon_stream::fstat64(struct stat64 *buf) const throw()
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
132 int
ioctl(unsigned long request,va_list args)133 Vcon_stream::ioctl(unsigned long request, va_list args) throw()
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 -EINVAL;
199 }
200
201 }}
202