blob: 18f80f701a2cc3d53ed2b2038c4ee80741979154 [file] [log] [blame]
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "qemu-common.h"
25#include "sockets.h"
26#include "net.h"
27#include "monitor.h"
28#include "console.h"
29#include "sysemu.h"
30#include "qemu-timer.h"
31#include "qemu-char.h"
32#include "block.h"
33#include "hw/usb.h"
34#include "hw/baum.h"
35#include "hw/msmouse.h"
36
37#include <unistd.h>
38#include <fcntl.h>
39#include <signal.h>
40#include <time.h>
41#include <errno.h>
42#include <sys/time.h>
43#include <zlib.h>
44
45#ifndef _WIN32
46#include <sys/times.h>
47#include <sys/wait.h>
48#include <termios.h>
49#include <sys/mman.h>
50#include <sys/ioctl.h>
51#include <sys/resource.h>
52#include <sys/socket.h>
53#include <netinet/in.h>
54#include <net/if.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070055#include <arpa/inet.h>
56#include <dirent.h>
57#include <netdb.h>
58#include <sys/select.h>
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070059#ifdef CONFIG_BSD
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070060#include <sys/stat.h>
David 'Digit' Turner17410ee2011-05-10 10:55:21 +020061#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070062#include <libutil.h>
63#include <dev/ppbus/ppi.h>
64#include <dev/ppbus/ppbconf.h>
David 'Digit' Turner17410ee2011-05-10 10:55:21 +020065#if defined(__GLIBC__)
66#include <pty.h>
67#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070068#elif defined(__DragonFly__)
69#include <libutil.h>
70#include <dev/misc/ppi/ppi.h>
71#include <bus/ppbus/ppbconf.h>
72#else
73#include <util.h>
74#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070075#else
76#ifdef __linux__
77#include <pty.h>
78
79#include <linux/ppdev.h>
80#include <linux/parport.h>
81#endif
82#ifdef __sun__
83#include <sys/stat.h>
84#include <sys/ethernet.h>
85#include <sys/sockio.h>
86#include <netinet/arp.h>
87#include <netinet/in.h>
88#include <netinet/in_systm.h>
89#include <netinet/ip.h>
90#include <netinet/ip_icmp.h> // must come after ip.h
91#include <netinet/udp.h>
92#include <netinet/tcp.h>
93#include <net/if.h>
94#include <syslog.h>
95#include <stropts.h>
96#endif
97#endif
98#endif
99
100#include "qemu_socket.h"
101
David Turner9d118822010-09-10 13:02:07 +0200102#define READ_BUF_LEN 4096
103
104#ifdef CONFIG_ANDROID
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700105#include "charpipe.h"
106#include "modem_driver.h"
107#include "android/gps.h"
108#include "android/hw-kmsg.h"
109#include "android/hw-qemud.h"
David Turner9d118822010-09-10 13:02:07 +0200110#endif /* CONFIG_ANDROID */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700111
112/***********************************************************/
113/* character device */
114
David 'Digit' Turnera5d41202010-05-10 18:37:10 -0700115static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
116 QTAILQ_HEAD_INITIALIZER(chardevs);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700117static int initial_reset_issued;
118
119static void qemu_chr_event(CharDriverState *s, int event)
120{
David Turner9d118822010-09-10 13:02:07 +0200121 /* Keep track if the char device is open */
122 switch (event) {
123 case CHR_EVENT_OPENED:
124 s->opened = 1;
125 break;
126 case CHR_EVENT_CLOSED:
127 s->opened = 0;
128 break;
129 }
130
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700131 if (!s->chr_event)
132 return;
133 s->chr_event(s->handler_opaque, event);
134}
135
David Turner9d118822010-09-10 13:02:07 +0200136static void qemu_chr_generic_open_bh(void *opaque)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700137{
138 CharDriverState *s = opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -0700139 qemu_chr_event(s, CHR_EVENT_OPENED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700140 qemu_bh_delete(s->bh);
141 s->bh = NULL;
142}
143
David Turner9d118822010-09-10 13:02:07 +0200144void qemu_chr_generic_open(CharDriverState *s)
145{
146 if (s->bh == NULL) {
147 s->bh = qemu_bh_new(qemu_chr_generic_open_bh, s);
148 qemu_bh_schedule(s->bh);
149 }
150}
151
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700152void qemu_chr_reset(CharDriverState *s)
153{
154 if (s->bh == NULL && initial_reset_issued) {
David Turner9d118822010-09-10 13:02:07 +0200155 s->bh = qemu_bh_new(qemu_chr_generic_open_bh, s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700156 qemu_bh_schedule(s->bh);
157 }
158}
159
160void qemu_chr_initial_reset(void)
161{
162 CharDriverState *chr;
163
164 initial_reset_issued = 1;
165
David 'Digit' Turnera5d41202010-05-10 18:37:10 -0700166 QTAILQ_FOREACH(chr, &chardevs, next) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700167 qemu_chr_reset(chr);
168 }
169}
170
171int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
172{
173 return s->chr_write(s, buf, len);
174}
175
176int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
177{
178 if (!s->chr_ioctl)
179 return -ENOTSUP;
180 return s->chr_ioctl(s, cmd, arg);
181}
182
183int qemu_chr_can_read(CharDriverState *s)
184{
185 if (!s->chr_can_read)
186 return 0;
187 return s->chr_can_read(s->handler_opaque);
188}
189
190void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
191{
192 s->chr_read(s->handler_opaque, buf, len);
193}
194
David Turner9d118822010-09-10 13:02:07 +0200195int qemu_chr_get_msgfd(CharDriverState *s)
196{
197 return s->get_msgfd ? s->get_msgfd(s) : -1;
198}
199
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700200void qemu_chr_accept_input(CharDriverState *s)
201{
202 if (s->chr_accept_input)
203 s->chr_accept_input(s);
204}
205
206void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
207{
David Turner9d118822010-09-10 13:02:07 +0200208 char buf[READ_BUF_LEN];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700209 va_list ap;
210 va_start(ap, fmt);
211 vsnprintf(buf, sizeof(buf), fmt, ap);
212 qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
213 va_end(ap);
214}
215
216void qemu_chr_send_event(CharDriverState *s, int event)
217{
218 if (s->chr_send_event)
219 s->chr_send_event(s, event);
220}
221
222void qemu_chr_add_handlers(CharDriverState *s,
David Turner4143d8f2010-09-10 11:05:02 +0200223 IOCanReadHandler *fd_can_read,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700224 IOReadHandler *fd_read,
225 IOEventHandler *fd_event,
226 void *opaque)
227{
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200228 if (!opaque && !fd_can_read && !fd_read && !fd_event) {
229 /* chr driver being released. */
230 ++s->avail_connections;
231 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700232 s->chr_can_read = fd_can_read;
233 s->chr_read = fd_read;
234 s->chr_event = fd_event;
235 s->handler_opaque = opaque;
236 if (s->chr_update_read_handler)
237 s->chr_update_read_handler(s);
David Turner9d118822010-09-10 13:02:07 +0200238
239 /* We're connecting to an already opened device, so let's make sure we
240 also get the open event */
241 if (s->opened) {
242 qemu_chr_generic_open(s);
243 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700244}
245
246static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
247{
248 return len;
249}
250
251static CharDriverState *qemu_chr_open_null(void)
252{
253 CharDriverState *chr;
254
255 chr = qemu_mallocz(sizeof(CharDriverState));
256 chr->chr_write = null_chr_write;
257 return chr;
258}
259
260/* MUX driver for serial I/O splitting */
261#define MAX_MUX 4
262#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
263#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
264typedef struct {
David Turner4143d8f2010-09-10 11:05:02 +0200265 IOCanReadHandler *chr_can_read[MAX_MUX];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700266 IOReadHandler *chr_read[MAX_MUX];
267 IOEventHandler *chr_event[MAX_MUX];
268 void *ext_opaque[MAX_MUX];
269 CharDriverState *drv;
David Turner9d118822010-09-10 13:02:07 +0200270 int focus;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700271 int mux_cnt;
272 int term_got_escape;
273 int max_size;
274 /* Intermediate input buffer allows to catch escape sequences even if the
275 currently active device is not accepting any input - but only until it
276 is full as well. */
277 unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
278 int prod[MAX_MUX];
279 int cons[MAX_MUX];
280 int timestamps;
281 int linestart;
282 int64_t timestamps_start;
283} MuxDriver;
284
285
286static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
287{
288 MuxDriver *d = chr->opaque;
289 int ret;
290 if (!d->timestamps) {
291 ret = d->drv->chr_write(d->drv, buf, len);
292 } else {
293 int i;
294
295 ret = 0;
296 for (i = 0; i < len; i++) {
297 if (d->linestart) {
298 char buf1[64];
299 int64_t ti;
300 int secs;
301
David 'Digit' Turner5973c772011-05-10 07:06:00 +0200302 ti = qemu_get_clock_ms(rt_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700303 if (d->timestamps_start == -1)
304 d->timestamps_start = ti;
305 ti -= d->timestamps_start;
306 secs = ti / 1000;
307 snprintf(buf1, sizeof(buf1),
308 "[%02d:%02d:%02d.%03d] ",
309 secs / 3600,
310 (secs / 60) % 60,
311 secs % 60,
312 (int)(ti % 1000));
313 d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
314 d->linestart = 0;
315 }
316 ret += d->drv->chr_write(d->drv, buf+i, 1);
317 if (buf[i] == '\n') {
318 d->linestart = 1;
319 }
320 }
321 }
322 return ret;
323}
324
325static const char * const mux_help[] = {
326 "% h print this help\n\r",
327 "% x exit emulator\n\r",
328 "% s save disk data back to file (if -snapshot)\n\r",
329 "% t toggle console timestamps\n\r"
330 "% b send break (magic sysrq)\n\r",
331 "% c switch between console and monitor\n\r",
332 "% % sends %\n\r",
333 NULL
334};
335
336int term_escape_char = 0x01; /* ctrl-a is used for escape */
337static void mux_print_help(CharDriverState *chr)
338{
339 int i, j;
340 char ebuf[15] = "Escape-Char";
341 char cbuf[50] = "\n\r";
342
343 if (term_escape_char > 0 && term_escape_char < 26) {
344 snprintf(cbuf, sizeof(cbuf), "\n\r");
345 snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
346 } else {
347 snprintf(cbuf, sizeof(cbuf),
348 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
349 term_escape_char);
350 }
351 chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
352 for (i = 0; mux_help[i] != NULL; i++) {
353 for (j=0; mux_help[i][j] != '\0'; j++) {
354 if (mux_help[i][j] == '%')
355 chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
356 else
357 chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
358 }
359 }
360}
361
362static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event)
363{
364 if (d->chr_event[mux_nr])
365 d->chr_event[mux_nr](d->ext_opaque[mux_nr], event);
366}
367
368static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
369{
370 if (d->term_got_escape) {
371 d->term_got_escape = 0;
372 if (ch == term_escape_char)
373 goto send_char;
374 switch(ch) {
375 case '?':
376 case 'h':
377 mux_print_help(chr);
378 break;
379 case 'x':
380 {
381 const char *term = "QEMU: Terminated\n\r";
382 chr->chr_write(chr,(uint8_t *)term,strlen(term));
383 exit(0);
384 break;
385 }
386 case 's':
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100387 bdrv_commit_all();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700388 break;
389 case 'b':
390 qemu_chr_event(chr, CHR_EVENT_BREAK);
391 break;
392 case 'c':
393 /* Switch to the next registered device */
David Turner9d118822010-09-10 13:02:07 +0200394 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
395 d->focus++;
396 if (d->focus >= d->mux_cnt)
397 d->focus = 0;
398 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700399 break;
400 case 't':
401 d->timestamps = !d->timestamps;
402 d->timestamps_start = -1;
403 d->linestart = 0;
404 break;
405 }
406 } else if (ch == term_escape_char) {
407 d->term_got_escape = 1;
408 } else {
409 send_char:
410 return 1;
411 }
412 return 0;
413}
414
415static void mux_chr_accept_input(CharDriverState *chr)
416{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700417 MuxDriver *d = chr->opaque;
David Turner9d118822010-09-10 13:02:07 +0200418 int m = d->focus;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700419
420 while (d->prod[m] != d->cons[m] &&
421 d->chr_can_read[m] &&
422 d->chr_can_read[m](d->ext_opaque[m])) {
423 d->chr_read[m](d->ext_opaque[m],
424 &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
425 }
426}
427
428static int mux_chr_can_read(void *opaque)
429{
430 CharDriverState *chr = opaque;
431 MuxDriver *d = chr->opaque;
David Turner9d118822010-09-10 13:02:07 +0200432 int m = d->focus;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700433
434 if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
435 return 1;
436 if (d->chr_can_read[m])
437 return d->chr_can_read[m](d->ext_opaque[m]);
438 return 0;
439}
440
441static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
442{
443 CharDriverState *chr = opaque;
444 MuxDriver *d = chr->opaque;
David Turner9d118822010-09-10 13:02:07 +0200445 int m = d->focus;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700446 int i;
447
448 mux_chr_accept_input (opaque);
449
450 for(i = 0; i < size; i++)
451 if (mux_proc_byte(chr, d, buf[i])) {
452 if (d->prod[m] == d->cons[m] &&
453 d->chr_can_read[m] &&
454 d->chr_can_read[m](d->ext_opaque[m]))
455 d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
456 else
457 d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
458 }
459}
460
461static void mux_chr_event(void *opaque, int event)
462{
463 CharDriverState *chr = opaque;
464 MuxDriver *d = chr->opaque;
465 int i;
466
467 /* Send the event to all registered listeners */
468 for (i = 0; i < d->mux_cnt; i++)
469 mux_chr_send_event(d, i, event);
470}
471
472static void mux_chr_update_read_handler(CharDriverState *chr)
473{
474 MuxDriver *d = chr->opaque;
475
476 if (d->mux_cnt >= MAX_MUX) {
477 fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
478 return;
479 }
480 d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
481 d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
482 d->chr_read[d->mux_cnt] = chr->chr_read;
483 d->chr_event[d->mux_cnt] = chr->chr_event;
484 /* Fix up the real driver with mux routines */
485 if (d->mux_cnt == 0) {
486 qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
487 mux_chr_event, chr);
488 }
David Turner9d118822010-09-10 13:02:07 +0200489 if (d->focus != -1) {
490 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
491 }
492 d->focus = d->mux_cnt;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700493 d->mux_cnt++;
David Turner9d118822010-09-10 13:02:07 +0200494 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700495}
496
497static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
498{
499 CharDriverState *chr;
500 MuxDriver *d;
501
502 chr = qemu_mallocz(sizeof(CharDriverState));
503 d = qemu_mallocz(sizeof(MuxDriver));
504
505 chr->opaque = d;
506 d->drv = drv;
David Turner9d118822010-09-10 13:02:07 +0200507 d->focus = -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700508 chr->chr_write = mux_chr_write;
509 chr->chr_update_read_handler = mux_chr_update_read_handler;
510 chr->chr_accept_input = mux_chr_accept_input;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200511 /* Frontend guest-open / -close notification is not support with muxes */
512 chr->chr_guest_open = NULL;
513 chr->chr_guest_close = NULL;
David Turner9d118822010-09-10 13:02:07 +0200514
515 /* Muxes are always open on creation */
516 qemu_chr_generic_open(chr);
517
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700518 return chr;
519}
520
521
522#ifdef _WIN32
523int send_all(int fd, const void *buf, int len1)
524{
525#if 1
526 return socket_send(fd, buf, len1);
527#else
528 int ret, len;
529
530 len = len1;
531 while (len > 0) {
532 ret = send(fd, buf, len, 0);
533 if (ret < 0) {
534 errno = WSAGetLastError();
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -0700535 if (errno != WSAEWOULDBLOCK && errno != WSAEAGAIN) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700536 return -1;
537 }
538 } else if (ret == 0) {
539 break;
540 } else {
541 buf += ret;
542 len -= ret;
543 }
544 }
545 return len1 - len;
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +0200546#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700547}
548
549#else
550
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200551int send_all(int fd, const void *_buf, int len1)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700552{
553 int ret, len;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200554 const uint8_t *buf = _buf;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700555
556 len = len1;
557 while (len > 0) {
558 ret = write(fd, buf, len);
559 if (ret < 0) {
560 if (errno != EINTR && errno != EAGAIN)
561 return -1;
562 } else if (ret == 0) {
563 break;
564 } else {
565 buf += ret;
566 len -= ret;
567 }
568 }
569 return len1 - len;
570}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700571#endif /* !_WIN32 */
572
573#ifndef _WIN32
574
575typedef struct {
576 int fd_in, fd_out;
577 int max_size;
578} FDCharDriver;
579
580#define STDIO_MAX_CLIENTS 1
581static int stdio_nb_clients = 0;
582
583static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
584{
585 FDCharDriver *s = chr->opaque;
586 return send_all(s->fd_out, buf, len);
587}
588
589static int fd_chr_read_poll(void *opaque)
590{
591 CharDriverState *chr = opaque;
592 FDCharDriver *s = chr->opaque;
593
594 s->max_size = qemu_chr_can_read(chr);
595 return s->max_size;
596}
597
598static void fd_chr_read(void *opaque)
599{
600 CharDriverState *chr = opaque;
601 FDCharDriver *s = chr->opaque;
602 int size, len;
David Turner9d118822010-09-10 13:02:07 +0200603 uint8_t buf[READ_BUF_LEN];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700604
605 len = sizeof(buf);
606 if (len > s->max_size)
607 len = s->max_size;
608 if (len == 0)
609 return;
610 size = read(s->fd_in, buf, len);
611 if (size == 0) {
612 /* FD has been closed. Remove it from the active list. */
613 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
David Turner9d118822010-09-10 13:02:07 +0200614 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700615 return;
616 }
617 if (size > 0) {
618 qemu_chr_read(chr, buf, size);
619 }
620}
621
622static void fd_chr_update_read_handler(CharDriverState *chr)
623{
624 FDCharDriver *s = chr->opaque;
625
626 if (s->fd_in >= 0) {
627 if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
628 } else {
629 qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
630 fd_chr_read, NULL, chr);
631 }
632 }
633}
634
635static void fd_chr_close(struct CharDriverState *chr)
636{
637 FDCharDriver *s = chr->opaque;
638
639 if (s->fd_in >= 0) {
640 if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
641 } else {
642 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
643 }
644 }
645
646 qemu_free(s);
David Turner9d118822010-09-10 13:02:07 +0200647 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700648}
649
650/* open a character device to a unix fd */
651static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
652{
653 CharDriverState *chr;
654 FDCharDriver *s;
655
656 chr = qemu_mallocz(sizeof(CharDriverState));
657 s = qemu_mallocz(sizeof(FDCharDriver));
658 s->fd_in = fd_in;
659 s->fd_out = fd_out;
660 chr->opaque = s;
661 chr->chr_write = fd_chr_write;
662 chr->chr_update_read_handler = fd_chr_update_read_handler;
663 chr->chr_close = fd_chr_close;
664
David Turner9d118822010-09-10 13:02:07 +0200665 qemu_chr_generic_open(chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700666
667 return chr;
668}
669
670static CharDriverState *qemu_chr_open_file_out(const char *file_out)
671{
672 int fd_out;
673
674 TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
675 if (fd_out < 0)
676 return NULL;
677 return qemu_chr_open_fd(-1, fd_out);
678}
679
680static CharDriverState *qemu_chr_open_pipe(const char *filename)
681{
682 int fd_in, fd_out;
683 char filename_in[256], filename_out[256];
684
685 snprintf(filename_in, 256, "%s.in", filename);
686 snprintf(filename_out, 256, "%s.out", filename);
687 TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
688 TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
689 if (fd_in < 0 || fd_out < 0) {
690 if (fd_in >= 0)
691 close(fd_in);
692 if (fd_out >= 0)
693 close(fd_out);
694 TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
695 if (fd_in < 0)
696 return NULL;
697 }
698 return qemu_chr_open_fd(fd_in, fd_out);
699}
700
David 'Digit' Turner162f35e2009-09-18 23:05:39 -0700701static CharDriverState *qemu_chr_open_fdpair(const char *fd_pair)
702{
703 int fd_in, fd_out;
704 char *endptr;
705
706 /* fd_pair should contain two decimal fd values, separated by
707 * a colon. */
708 endptr = NULL;
709 fd_in = strtol(fd_pair, &endptr, 10);
710 if (endptr == NULL || endptr == fd_pair || *endptr != ':')
711 return NULL;
712 endptr++; // skip colon
713 fd_pair = endptr;
714 endptr = NULL;
715 fd_out = strtol(fd_pair, &endptr, 10);
716 if (endptr == NULL || endptr == fd_pair || *endptr != '\0')
717 return NULL;
718
719 return qemu_chr_open_fd(fd_in, fd_out);
720}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700721
722/* for STDIO, we handle the case where several clients use it
723 (nographic mode) */
724
725#define TERM_FIFO_MAX_SIZE 1
726
727static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
728static int term_fifo_size;
729
730static int stdio_read_poll(void *opaque)
731{
732 CharDriverState *chr = opaque;
733
734 /* try to flush the queue if needed */
735 if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
736 qemu_chr_read(chr, term_fifo, 1);
737 term_fifo_size = 0;
738 }
739 /* see if we can absorb more chars */
740 if (term_fifo_size == 0)
741 return 1;
742 else
743 return 0;
744}
745
746static void stdio_read(void *opaque)
747{
748 int size;
749 uint8_t buf[1];
750 CharDriverState *chr = opaque;
751
752 size = read(0, buf, 1);
753 if (size == 0) {
754 /* stdin has been closed. Remove it from the active list. */
755 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
David Turner9d118822010-09-10 13:02:07 +0200756 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700757 return;
758 }
759 if (size > 0) {
760 if (qemu_chr_can_read(chr) > 0) {
761 qemu_chr_read(chr, buf, 1);
762 } else if (term_fifo_size == 0) {
763 term_fifo[term_fifo_size++] = buf[0];
764 }
765 }
766}
767
768/* init terminal so that we can grab keys */
769static struct termios oldtty;
770static int old_fd0_flags;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200771static bool stdio_allow_signal;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700772
773static void term_exit(void)
774{
775 tcsetattr (0, TCSANOW, &oldtty);
776 fcntl(0, F_SETFL, old_fd0_flags);
777}
778
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200779static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700780{
781 struct termios tty;
782
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200783 tty = oldtty;
784 if (!echo) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700785 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
786 |INLCR|IGNCR|ICRNL|IXON);
787 tty.c_oflag |= OPOST;
788 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700789 tty.c_cflag &= ~(CSIZE|PARENB);
790 tty.c_cflag |= CS8;
791 tty.c_cc[VMIN] = 1;
792 tty.c_cc[VTIME] = 0;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200793 }
794 /* if graphical mode, we allow Ctrl-C handling */
795 if (!stdio_allow_signal)
796 tty.c_lflag &= ~ISIG;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700797
798 tcsetattr (0, TCSANOW, &tty);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700799}
800
801static void qemu_chr_close_stdio(struct CharDriverState *chr)
802{
803 term_exit();
804 stdio_nb_clients--;
805 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
806 fd_chr_close(chr);
807}
808
809static CharDriverState *qemu_chr_open_stdio(void)
810{
811 CharDriverState *chr;
812
813 if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
814 return NULL;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200815 if (stdio_nb_clients == 0) {
816 old_fd0_flags = fcntl(0, F_GETFL);
817 tcgetattr (0, &oldtty);
818 fcntl(0, F_SETFL, O_NONBLOCK);
819 atexit(term_exit);
820 }
821
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700822 chr = qemu_chr_open_fd(0, 1);
823 chr->chr_close = qemu_chr_close_stdio;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200824 chr->chr_set_echo = qemu_chr_set_echo_stdio;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700825 qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
826 stdio_nb_clients++;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +0200827 stdio_allow_signal = display_type != DT_NOGRAPHIC;
828 qemu_chr_set_echo(chr, false);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700829
830 return chr;
831}
832
833#ifdef __sun__
834/* Once Solaris has openpty(), this is going to be removed. */
835static int openpty(int *amaster, int *aslave, char *name,
836 struct termios *termp, struct winsize *winp)
837{
838 const char *slave;
839 int mfd = -1, sfd = -1;
840
841 *amaster = *aslave = -1;
842
843 mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
844 if (mfd < 0)
845 goto err;
846
847 if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
848 goto err;
849
850 if ((slave = ptsname(mfd)) == NULL)
851 goto err;
852
853 if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
854 goto err;
855
856 if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
857 (termp != NULL && tcgetattr(sfd, termp) < 0))
858 goto err;
859
860 if (amaster)
861 *amaster = mfd;
862 if (aslave)
863 *aslave = sfd;
864 if (winp)
865 ioctl(sfd, TIOCSWINSZ, winp);
866
867 return 0;
868
869err:
870 if (sfd != -1)
871 close(sfd);
872 close(mfd);
873 return -1;
874}
875
876static void cfmakeraw (struct termios *termios_p)
877{
878 termios_p->c_iflag &=
879 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
880 termios_p->c_oflag &= ~OPOST;
881 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
882 termios_p->c_cflag &= ~(CSIZE|PARENB);
883 termios_p->c_cflag |= CS8;
884
885 termios_p->c_cc[VMIN] = 0;
886 termios_p->c_cc[VTIME] = 0;
887}
888#endif
889
David 'Digit' Turnerdc468202010-10-27 02:34:46 +0200890#ifndef _WIN32
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700891
892typedef struct {
893 int fd;
894 int connected;
895 int polling;
896 int read_bytes;
897 QEMUTimer *timer;
898} PtyCharDriver;
899
900static void pty_chr_update_read_handler(CharDriverState *chr);
901static void pty_chr_state(CharDriverState *chr, int connected);
902
903static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
904{
905 PtyCharDriver *s = chr->opaque;
906
907 if (!s->connected) {
908 /* guest sends data, check for (re-)connect */
909 pty_chr_update_read_handler(chr);
910 return 0;
911 }
912 return send_all(s->fd, buf, len);
913}
914
915static int pty_chr_read_poll(void *opaque)
916{
917 CharDriverState *chr = opaque;
918 PtyCharDriver *s = chr->opaque;
919
920 s->read_bytes = qemu_chr_can_read(chr);
921 return s->read_bytes;
922}
923
924static void pty_chr_read(void *opaque)
925{
926 CharDriverState *chr = opaque;
927 PtyCharDriver *s = chr->opaque;
928 int size, len;
David Turner9d118822010-09-10 13:02:07 +0200929 uint8_t buf[READ_BUF_LEN];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700930
931 len = sizeof(buf);
932 if (len > s->read_bytes)
933 len = s->read_bytes;
934 if (len == 0)
935 return;
936 size = read(s->fd, buf, len);
937 if ((size == -1 && errno == EIO) ||
938 (size == 0)) {
939 pty_chr_state(chr, 0);
940 return;
941 }
942 if (size > 0) {
943 pty_chr_state(chr, 1);
944 qemu_chr_read(chr, buf, size);
945 }
946}
947
948static void pty_chr_update_read_handler(CharDriverState *chr)
949{
950 PtyCharDriver *s = chr->opaque;
951
952 qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
953 pty_chr_read, NULL, chr);
954 s->polling = 1;
955 /*
956 * Short timeout here: just need wait long enougth that qemu makes
957 * it through the poll loop once. When reconnected we want a
958 * short timeout so we notice it almost instantly. Otherwise
959 * read() gives us -EIO instantly, making pty_chr_state() reset the
960 * timeout to the normal (much longer) poll interval before the
961 * timer triggers.
962 */
David 'Digit' Turner5973c772011-05-10 07:06:00 +0200963 qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 10);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700964}
965
966static void pty_chr_state(CharDriverState *chr, int connected)
967{
968 PtyCharDriver *s = chr->opaque;
969
970 if (!connected) {
971 qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
972 s->connected = 0;
973 s->polling = 0;
974 /* (re-)connect poll interval for idle guests: once per second.
975 * We check more frequently in case the guests sends data to
976 * the virtual device linked to our pty. */
David 'Digit' Turner5973c772011-05-10 07:06:00 +0200977 qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 1000);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700978 } else {
979 if (!s->connected)
David Turner9d118822010-09-10 13:02:07 +0200980 qemu_chr_generic_open(chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700981 s->connected = 1;
982 }
983}
984
985static void pty_chr_timer(void *opaque)
986{
987 struct CharDriverState *chr = opaque;
988 PtyCharDriver *s = chr->opaque;
989
990 if (s->connected)
991 return;
992 if (s->polling) {
993 /* If we arrive here without polling being cleared due
994 * read returning -EIO, then we are (re-)connected */
995 pty_chr_state(chr, 1);
996 return;
997 }
998
999 /* Next poll ... */
1000 pty_chr_update_read_handler(chr);
1001}
1002
1003static void pty_chr_close(struct CharDriverState *chr)
1004{
1005 PtyCharDriver *s = chr->opaque;
1006
1007 qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
1008 close(s->fd);
1009 qemu_del_timer(s->timer);
1010 qemu_free_timer(s->timer);
1011 qemu_free(s);
David Turner9d118822010-09-10 13:02:07 +02001012 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001013}
1014
1015static CharDriverState *qemu_chr_open_pty(void)
1016{
1017 CharDriverState *chr;
1018 PtyCharDriver *s;
1019 struct termios tty;
1020 int slave_fd, len;
1021#if defined(__OpenBSD__) || defined(__DragonFly__)
1022 char pty_name[PATH_MAX];
1023#define q_ptsname(x) pty_name
1024#else
1025 char *pty_name = NULL;
1026#define q_ptsname(x) ptsname(x)
1027 extern char* ptsname(int);
1028#endif
1029
1030 chr = qemu_mallocz(sizeof(CharDriverState));
1031 s = qemu_mallocz(sizeof(PtyCharDriver));
1032
1033 if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
1034 return NULL;
1035 }
1036
1037 /* Set raw attributes on the pty. */
1038 tcgetattr(slave_fd, &tty);
1039 cfmakeraw(&tty);
1040 tcsetattr(slave_fd, TCSAFLUSH, &tty);
1041 close(slave_fd);
1042
1043 len = strlen(q_ptsname(s->fd)) + 5;
1044 chr->filename = qemu_malloc(len);
1045 snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd));
1046 fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
1047
1048 chr->opaque = s;
1049 chr->chr_write = pty_chr_write;
1050 chr->chr_update_read_handler = pty_chr_update_read_handler;
1051 chr->chr_close = pty_chr_close;
1052
David 'Digit' Turner5973c772011-05-10 07:06:00 +02001053 s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001054
1055 return chr;
1056}
1057
1058static void tty_serial_init(int fd, int speed,
1059 int parity, int data_bits, int stop_bits)
1060{
1061 struct termios tty;
1062 speed_t spd;
1063
1064#if 0
1065 printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
1066 speed, parity, data_bits, stop_bits);
1067#endif
1068 tcgetattr (fd, &tty);
1069
David Turner9d118822010-09-10 13:02:07 +02001070#define check_speed(val) if (speed <= val) { spd = B##val; break; }
1071 speed = speed * 10 / 11;
1072 do {
1073 check_speed(50);
1074 check_speed(75);
1075 check_speed(110);
1076 check_speed(134);
1077 check_speed(150);
1078 check_speed(200);
1079 check_speed(300);
1080 check_speed(600);
1081 check_speed(1200);
1082 check_speed(1800);
1083 check_speed(2400);
1084 check_speed(4800);
1085 check_speed(9600);
1086 check_speed(19200);
1087 check_speed(38400);
1088 /* Non-Posix values follow. They may be unsupported on some systems. */
1089 check_speed(57600);
1090 check_speed(115200);
1091#ifdef B230400
1092 check_speed(230400);
1093#endif
1094#ifdef B460800
1095 check_speed(460800);
1096#endif
1097#ifdef B500000
1098 check_speed(500000);
1099#endif
1100#ifdef B576000
1101 check_speed(576000);
1102#endif
1103#ifdef B921600
1104 check_speed(921600);
1105#endif
1106#ifdef B1000000
1107 check_speed(1000000);
1108#endif
1109#ifdef B1152000
1110 check_speed(1152000);
1111#endif
1112#ifdef B1500000
1113 check_speed(1500000);
1114#endif
1115#ifdef B2000000
1116 check_speed(2000000);
1117#endif
1118#ifdef B2500000
1119 check_speed(2500000);
1120#endif
1121#ifdef B3000000
1122 check_speed(3000000);
1123#endif
1124#ifdef B3500000
1125 check_speed(3500000);
1126#endif
1127#ifdef B4000000
1128 check_speed(4000000);
1129#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001130 spd = B115200;
David Turner9d118822010-09-10 13:02:07 +02001131 } while (0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001132
1133 cfsetispeed(&tty, spd);
1134 cfsetospeed(&tty, spd);
1135
1136 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1137 |INLCR|IGNCR|ICRNL|IXON);
1138 tty.c_oflag |= OPOST;
1139 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
1140 tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
1141 switch(data_bits) {
1142 default:
1143 case 8:
1144 tty.c_cflag |= CS8;
1145 break;
1146 case 7:
1147 tty.c_cflag |= CS7;
1148 break;
1149 case 6:
1150 tty.c_cflag |= CS6;
1151 break;
1152 case 5:
1153 tty.c_cflag |= CS5;
1154 break;
1155 }
1156 switch(parity) {
1157 default:
1158 case 'N':
1159 break;
1160 case 'E':
1161 tty.c_cflag |= PARENB;
1162 break;
1163 case 'O':
1164 tty.c_cflag |= PARENB | PARODD;
1165 break;
1166 }
1167 if (stop_bits == 2)
1168 tty.c_cflag |= CSTOPB;
1169
1170 tcsetattr (fd, TCSANOW, &tty);
1171}
1172
1173static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
1174{
1175 FDCharDriver *s = chr->opaque;
1176
1177 switch(cmd) {
1178 case CHR_IOCTL_SERIAL_SET_PARAMS:
1179 {
1180 QEMUSerialSetParams *ssp = arg;
1181 tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
1182 ssp->data_bits, ssp->stop_bits);
1183 }
1184 break;
1185 case CHR_IOCTL_SERIAL_SET_BREAK:
1186 {
1187 int enable = *(int *)arg;
1188 if (enable)
1189 tcsendbreak(s->fd_in, 1);
1190 }
1191 break;
1192 case CHR_IOCTL_SERIAL_GET_TIOCM:
1193 {
1194 int sarg = 0;
1195 int *targ = (int *)arg;
1196 ioctl(s->fd_in, TIOCMGET, &sarg);
1197 *targ = 0;
1198 if (sarg & TIOCM_CTS)
1199 *targ |= CHR_TIOCM_CTS;
1200 if (sarg & TIOCM_CAR)
1201 *targ |= CHR_TIOCM_CAR;
1202 if (sarg & TIOCM_DSR)
1203 *targ |= CHR_TIOCM_DSR;
1204 if (sarg & TIOCM_RI)
1205 *targ |= CHR_TIOCM_RI;
1206 if (sarg & TIOCM_DTR)
1207 *targ |= CHR_TIOCM_DTR;
1208 if (sarg & TIOCM_RTS)
1209 *targ |= CHR_TIOCM_RTS;
1210 }
1211 break;
1212 case CHR_IOCTL_SERIAL_SET_TIOCM:
1213 {
1214 int sarg = *(int *)arg;
1215 int targ = 0;
1216 ioctl(s->fd_in, TIOCMGET, &targ);
1217 targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
1218 | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
1219 if (sarg & CHR_TIOCM_CTS)
1220 targ |= TIOCM_CTS;
1221 if (sarg & CHR_TIOCM_CAR)
1222 targ |= TIOCM_CAR;
1223 if (sarg & CHR_TIOCM_DSR)
1224 targ |= TIOCM_DSR;
1225 if (sarg & CHR_TIOCM_RI)
1226 targ |= TIOCM_RI;
1227 if (sarg & CHR_TIOCM_DTR)
1228 targ |= TIOCM_DTR;
1229 if (sarg & CHR_TIOCM_RTS)
1230 targ |= TIOCM_RTS;
1231 ioctl(s->fd_in, TIOCMSET, &targ);
1232 }
1233 break;
1234 default:
1235 return -ENOTSUP;
1236 }
1237 return 0;
1238}
1239
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001240static void qemu_chr_close_tty(CharDriverState *chr)
1241{
1242 FDCharDriver *s = chr->opaque;
1243 int fd = -1;
1244
1245 if (s) {
1246 fd = s->fd_in;
1247 }
1248
1249 fd_chr_close(chr);
1250
1251 if (fd >= 0) {
1252 close(fd);
1253 }
1254}
1255
1256
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001257static CharDriverState *qemu_chr_open_tty(const char *filename)
1258{
1259 CharDriverState *chr;
1260 int fd;
1261
1262 TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001263 if (fd < 0) {
1264 return NULL;
1265 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001266 tty_serial_init(fd, 115200, 'N', 8, 1);
1267 chr = qemu_chr_open_fd(fd, fd);
1268 if (!chr) {
1269 close(fd);
1270 return NULL;
1271 }
1272 chr->chr_ioctl = tty_serial_ioctl;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001273 chr->chr_close = qemu_chr_close_tty;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001274 return chr;
1275}
David 'Digit' Turnerdc468202010-10-27 02:34:46 +02001276#else /* _WIN32 */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001277static CharDriverState *qemu_chr_open_pty(void)
1278{
1279 return NULL;
1280}
David 'Digit' Turnerdc468202010-10-27 02:34:46 +02001281#endif /* _WIN32 */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001282
1283#if defined(__linux__)
1284typedef struct {
1285 int fd;
1286 int mode;
1287} ParallelCharDriver;
1288
1289static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
1290{
1291 if (s->mode != mode) {
1292 int m = mode;
1293 if (ioctl(s->fd, PPSETMODE, &m) < 0)
1294 return 0;
1295 s->mode = mode;
1296 }
1297 return 1;
1298}
1299
1300static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1301{
1302 ParallelCharDriver *drv = chr->opaque;
1303 int fd = drv->fd;
1304 uint8_t b;
1305
1306 switch(cmd) {
1307 case CHR_IOCTL_PP_READ_DATA:
1308 if (ioctl(fd, PPRDATA, &b) < 0)
1309 return -ENOTSUP;
1310 *(uint8_t *)arg = b;
1311 break;
1312 case CHR_IOCTL_PP_WRITE_DATA:
1313 b = *(uint8_t *)arg;
1314 if (ioctl(fd, PPWDATA, &b) < 0)
1315 return -ENOTSUP;
1316 break;
1317 case CHR_IOCTL_PP_READ_CONTROL:
1318 if (ioctl(fd, PPRCONTROL, &b) < 0)
1319 return -ENOTSUP;
1320 /* Linux gives only the lowest bits, and no way to know data
1321 direction! For better compatibility set the fixed upper
1322 bits. */
1323 *(uint8_t *)arg = b | 0xc0;
1324 break;
1325 case CHR_IOCTL_PP_WRITE_CONTROL:
1326 b = *(uint8_t *)arg;
1327 if (ioctl(fd, PPWCONTROL, &b) < 0)
1328 return -ENOTSUP;
1329 break;
1330 case CHR_IOCTL_PP_READ_STATUS:
1331 if (ioctl(fd, PPRSTATUS, &b) < 0)
1332 return -ENOTSUP;
1333 *(uint8_t *)arg = b;
1334 break;
1335 case CHR_IOCTL_PP_DATA_DIR:
1336 if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
1337 return -ENOTSUP;
1338 break;
1339 case CHR_IOCTL_PP_EPP_READ_ADDR:
1340 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1341 struct ParallelIOArg *parg = arg;
1342 int n = read(fd, parg->buffer, parg->count);
1343 if (n != parg->count) {
1344 return -EIO;
1345 }
1346 }
1347 break;
1348 case CHR_IOCTL_PP_EPP_READ:
1349 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1350 struct ParallelIOArg *parg = arg;
1351 int n = read(fd, parg->buffer, parg->count);
1352 if (n != parg->count) {
1353 return -EIO;
1354 }
1355 }
1356 break;
1357 case CHR_IOCTL_PP_EPP_WRITE_ADDR:
1358 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1359 struct ParallelIOArg *parg = arg;
1360 int n = write(fd, parg->buffer, parg->count);
1361 if (n != parg->count) {
1362 return -EIO;
1363 }
1364 }
1365 break;
1366 case CHR_IOCTL_PP_EPP_WRITE:
1367 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1368 struct ParallelIOArg *parg = arg;
1369 int n = write(fd, parg->buffer, parg->count);
1370 if (n != parg->count) {
1371 return -EIO;
1372 }
1373 }
1374 break;
1375 default:
1376 return -ENOTSUP;
1377 }
1378 return 0;
1379}
1380
1381static void pp_close(CharDriverState *chr)
1382{
1383 ParallelCharDriver *drv = chr->opaque;
1384 int fd = drv->fd;
1385
1386 pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
1387 ioctl(fd, PPRELEASE);
1388 close(fd);
1389 qemu_free(drv);
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001390 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001391}
1392
1393static CharDriverState *qemu_chr_open_pp(const char *filename)
1394{
1395 CharDriverState *chr;
1396 ParallelCharDriver *drv;
1397 int fd;
1398
1399 TFR(fd = open(filename, O_RDWR));
1400 if (fd < 0)
1401 return NULL;
1402
1403 if (ioctl(fd, PPCLAIM) < 0) {
1404 close(fd);
1405 return NULL;
1406 }
1407
1408 drv = qemu_mallocz(sizeof(ParallelCharDriver));
1409 drv->fd = fd;
1410 drv->mode = IEEE1284_MODE_COMPAT;
1411
1412 chr = qemu_mallocz(sizeof(CharDriverState));
1413 chr->chr_write = null_chr_write;
1414 chr->chr_ioctl = pp_ioctl;
1415 chr->chr_close = pp_close;
1416 chr->opaque = drv;
1417
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001418 qemu_chr_generic_open(chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001419
1420 return chr;
1421}
1422#endif /* __linux__ */
1423
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001424#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001425static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1426{
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001427 int fd = (int)(intptr_t)chr->opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001428 uint8_t b;
1429
1430 switch(cmd) {
1431 case CHR_IOCTL_PP_READ_DATA:
1432 if (ioctl(fd, PPIGDATA, &b) < 0)
1433 return -ENOTSUP;
1434 *(uint8_t *)arg = b;
1435 break;
1436 case CHR_IOCTL_PP_WRITE_DATA:
1437 b = *(uint8_t *)arg;
1438 if (ioctl(fd, PPISDATA, &b) < 0)
1439 return -ENOTSUP;
1440 break;
1441 case CHR_IOCTL_PP_READ_CONTROL:
1442 if (ioctl(fd, PPIGCTRL, &b) < 0)
1443 return -ENOTSUP;
1444 *(uint8_t *)arg = b;
1445 break;
1446 case CHR_IOCTL_PP_WRITE_CONTROL:
1447 b = *(uint8_t *)arg;
1448 if (ioctl(fd, PPISCTRL, &b) < 0)
1449 return -ENOTSUP;
1450 break;
1451 case CHR_IOCTL_PP_READ_STATUS:
1452 if (ioctl(fd, PPIGSTATUS, &b) < 0)
1453 return -ENOTSUP;
1454 *(uint8_t *)arg = b;
1455 break;
1456 default:
1457 return -ENOTSUP;
1458 }
1459 return 0;
1460}
1461
1462static CharDriverState *qemu_chr_open_pp(const char *filename)
1463{
1464 CharDriverState *chr;
1465 int fd;
1466
1467 fd = open(filename, O_RDWR);
1468 if (fd < 0)
1469 return NULL;
1470
1471 chr = qemu_mallocz(sizeof(CharDriverState));
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001472 chr->opaque = (void *)(intptr_t)fd;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001473 chr->chr_write = null_chr_write;
1474 chr->chr_ioctl = pp_ioctl;
1475 return chr;
1476}
1477#endif
1478
1479#else /* _WIN32 */
1480
1481typedef struct {
1482 int max_size;
1483 HANDLE hcom, hrecv, hsend;
1484 OVERLAPPED orecv, osend;
1485 BOOL fpipe;
1486 DWORD len;
1487} WinCharState;
1488
1489#define NSENDBUF 2048
1490#define NRECVBUF 2048
1491#define MAXCONNECT 1
1492#define NTIMEOUT 5000
1493
1494static int win_chr_poll(void *opaque);
1495static int win_chr_pipe_poll(void *opaque);
1496
1497static void win_chr_close(CharDriverState *chr)
1498{
1499 WinCharState *s = chr->opaque;
1500
1501 if (s->hsend) {
1502 CloseHandle(s->hsend);
1503 s->hsend = NULL;
1504 }
1505 if (s->hrecv) {
1506 CloseHandle(s->hrecv);
1507 s->hrecv = NULL;
1508 }
1509 if (s->hcom) {
1510 CloseHandle(s->hcom);
1511 s->hcom = NULL;
1512 }
1513 if (s->fpipe)
1514 qemu_del_polling_cb(win_chr_pipe_poll, chr);
1515 else
1516 qemu_del_polling_cb(win_chr_poll, chr);
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001517
1518 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001519}
1520
1521static int win_chr_init(CharDriverState *chr, const char *filename)
1522{
1523 WinCharState *s = chr->opaque;
1524 COMMCONFIG comcfg;
1525 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
1526 COMSTAT comstat;
1527 DWORD size;
1528 DWORD err;
1529
1530 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1531 if (!s->hsend) {
1532 fprintf(stderr, "Failed CreateEvent\n");
1533 goto fail;
1534 }
1535 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1536 if (!s->hrecv) {
1537 fprintf(stderr, "Failed CreateEvent\n");
1538 goto fail;
1539 }
1540
1541 s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1542 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
1543 if (s->hcom == INVALID_HANDLE_VALUE) {
1544 fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
1545 s->hcom = NULL;
1546 goto fail;
1547 }
1548
1549 if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
1550 fprintf(stderr, "Failed SetupComm\n");
1551 goto fail;
1552 }
1553
1554 ZeroMemory(&comcfg, sizeof(COMMCONFIG));
1555 size = sizeof(COMMCONFIG);
1556 GetDefaultCommConfig(filename, &comcfg, &size);
1557 comcfg.dcb.DCBlength = sizeof(DCB);
1558 CommConfigDialog(filename, NULL, &comcfg);
1559
1560 if (!SetCommState(s->hcom, &comcfg.dcb)) {
1561 fprintf(stderr, "Failed SetCommState\n");
1562 goto fail;
1563 }
1564
1565 if (!SetCommMask(s->hcom, EV_ERR)) {
1566 fprintf(stderr, "Failed SetCommMask\n");
1567 goto fail;
1568 }
1569
1570 cto.ReadIntervalTimeout = MAXDWORD;
1571 if (!SetCommTimeouts(s->hcom, &cto)) {
1572 fprintf(stderr, "Failed SetCommTimeouts\n");
1573 goto fail;
1574 }
1575
1576 if (!ClearCommError(s->hcom, &err, &comstat)) {
1577 fprintf(stderr, "Failed ClearCommError\n");
1578 goto fail;
1579 }
1580 qemu_add_polling_cb(win_chr_poll, chr);
1581 return 0;
1582
1583 fail:
1584 win_chr_close(chr);
1585 return -1;
1586}
1587
1588static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
1589{
1590 WinCharState *s = chr->opaque;
1591 DWORD len, ret, size, err;
1592
1593 len = len1;
1594 ZeroMemory(&s->osend, sizeof(s->osend));
1595 s->osend.hEvent = s->hsend;
1596 while (len > 0) {
1597 if (s->hsend)
1598 ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
1599 else
1600 ret = WriteFile(s->hcom, buf, len, &size, NULL);
1601 if (!ret) {
1602 err = GetLastError();
1603 if (err == ERROR_IO_PENDING) {
1604 ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
1605 if (ret) {
1606 buf += size;
1607 len -= size;
1608 } else {
1609 break;
1610 }
1611 } else {
1612 break;
1613 }
1614 } else {
1615 buf += size;
1616 len -= size;
1617 }
1618 }
1619 return len1 - len;
1620}
1621
1622static int win_chr_read_poll(CharDriverState *chr)
1623{
1624 WinCharState *s = chr->opaque;
1625
1626 s->max_size = qemu_chr_can_read(chr);
1627 return s->max_size;
1628}
1629
1630static void win_chr_readfile(CharDriverState *chr)
1631{
1632 WinCharState *s = chr->opaque;
1633 int ret, err;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001634 uint8_t buf[READ_BUF_LEN];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001635 DWORD size;
1636
1637 ZeroMemory(&s->orecv, sizeof(s->orecv));
1638 s->orecv.hEvent = s->hrecv;
1639 ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
1640 if (!ret) {
1641 err = GetLastError();
1642 if (err == ERROR_IO_PENDING) {
1643 ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
1644 }
1645 }
1646
1647 if (size > 0) {
1648 qemu_chr_read(chr, buf, size);
1649 }
1650}
1651
1652static void win_chr_read(CharDriverState *chr)
1653{
1654 WinCharState *s = chr->opaque;
1655
1656 if (s->len > s->max_size)
1657 s->len = s->max_size;
1658 if (s->len == 0)
1659 return;
1660
1661 win_chr_readfile(chr);
1662}
1663
1664static int win_chr_poll(void *opaque)
1665{
1666 CharDriverState *chr = opaque;
1667 WinCharState *s = chr->opaque;
1668 COMSTAT status;
1669 DWORD comerr;
1670
1671 ClearCommError(s->hcom, &comerr, &status);
1672 if (status.cbInQue > 0) {
1673 s->len = status.cbInQue;
1674 win_chr_read_poll(chr);
1675 win_chr_read(chr);
1676 return 1;
1677 }
1678 return 0;
1679}
1680
1681static CharDriverState *qemu_chr_open_win(const char *filename)
1682{
1683 CharDriverState *chr;
1684 WinCharState *s;
1685
1686 chr = qemu_mallocz(sizeof(CharDriverState));
1687 s = qemu_mallocz(sizeof(WinCharState));
1688 chr->opaque = s;
1689 chr->chr_write = win_chr_write;
1690 chr->chr_close = win_chr_close;
1691
1692 if (win_chr_init(chr, filename) < 0) {
1693 free(s);
1694 free(chr);
1695 return NULL;
1696 }
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001697 qemu_chr_generic_open(chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001698 return chr;
1699}
1700
1701static int win_chr_pipe_poll(void *opaque)
1702{
1703 CharDriverState *chr = opaque;
1704 WinCharState *s = chr->opaque;
1705 DWORD size;
1706
1707 PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
1708 if (size > 0) {
1709 s->len = size;
1710 win_chr_read_poll(chr);
1711 win_chr_read(chr);
1712 return 1;
1713 }
1714 return 0;
1715}
1716
1717static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
1718{
1719 WinCharState *s = chr->opaque;
1720 OVERLAPPED ov;
1721 int ret;
1722 DWORD size;
1723 char openname[256];
1724
1725 s->fpipe = TRUE;
1726
1727 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1728 if (!s->hsend) {
1729 fprintf(stderr, "Failed CreateEvent\n");
1730 goto fail;
1731 }
1732 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1733 if (!s->hrecv) {
1734 fprintf(stderr, "Failed CreateEvent\n");
1735 goto fail;
1736 }
1737
1738 snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
1739 s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1740 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
1741 PIPE_WAIT,
1742 MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
1743 if (s->hcom == INVALID_HANDLE_VALUE) {
1744 fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
1745 s->hcom = NULL;
1746 goto fail;
1747 }
1748
1749 ZeroMemory(&ov, sizeof(ov));
1750 ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1751 ret = ConnectNamedPipe(s->hcom, &ov);
1752 if (ret) {
1753 fprintf(stderr, "Failed ConnectNamedPipe\n");
1754 goto fail;
1755 }
1756
1757 ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
1758 if (!ret) {
1759 fprintf(stderr, "Failed GetOverlappedResult\n");
1760 if (ov.hEvent) {
1761 CloseHandle(ov.hEvent);
1762 ov.hEvent = NULL;
1763 }
1764 goto fail;
1765 }
1766
1767 if (ov.hEvent) {
1768 CloseHandle(ov.hEvent);
1769 ov.hEvent = NULL;
1770 }
1771 qemu_add_polling_cb(win_chr_pipe_poll, chr);
1772 return 0;
1773
1774 fail:
1775 win_chr_close(chr);
1776 return -1;
1777}
1778
1779
1780static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
1781{
1782 CharDriverState *chr;
1783 WinCharState *s;
1784
1785 chr = qemu_mallocz(sizeof(CharDriverState));
1786 s = qemu_mallocz(sizeof(WinCharState));
1787 chr->opaque = s;
1788 chr->chr_write = win_chr_write;
1789 chr->chr_close = win_chr_close;
1790
1791 if (win_chr_pipe_init(chr, filename) < 0) {
1792 free(s);
1793 free(chr);
1794 return NULL;
1795 }
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001796 qemu_chr_generic_open(chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001797 return chr;
1798}
1799
1800static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
1801{
1802 CharDriverState *chr;
1803 WinCharState *s;
1804
1805 chr = qemu_mallocz(sizeof(CharDriverState));
1806 s = qemu_mallocz(sizeof(WinCharState));
1807 s->hcom = fd_out;
1808 chr->opaque = s;
1809 chr->chr_write = win_chr_write;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001810 qemu_chr_generic_open(chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001811 return chr;
1812}
1813
1814static CharDriverState *qemu_chr_open_win_con(const char *filename)
1815{
1816 return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
1817}
1818
1819static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
1820{
1821 HANDLE fd_out;
1822
1823 fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
1824 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1825 if (fd_out == INVALID_HANDLE_VALUE)
1826 return NULL;
1827
1828 return qemu_chr_open_win_file(fd_out);
1829}
1830#endif /* !_WIN32 */
1831
1832/***********************************************************/
1833/* UDP Net console */
1834
1835typedef struct {
1836 int fd;
1837 SockAddress daddr;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02001838 uint8_t buf[READ_BUF_LEN];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001839 int bufcnt;
1840 int bufptr;
1841 int max_size;
1842} NetCharDriver;
1843
1844static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1845{
1846 NetCharDriver *s = chr->opaque;
1847
1848 return socket_sendto(s->fd, (const void *)buf, len, &s->daddr);
1849}
1850
1851static int udp_chr_read_poll(void *opaque)
1852{
1853 CharDriverState *chr = opaque;
1854 NetCharDriver *s = chr->opaque;
1855
1856 s->max_size = qemu_chr_can_read(chr);
1857
1858 /* If there were any stray characters in the queue process them
1859 * first
1860 */
1861 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
1862 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
1863 s->bufptr++;
1864 s->max_size = qemu_chr_can_read(chr);
1865 }
1866 return s->max_size;
1867}
1868
1869static void udp_chr_read(void *opaque)
1870{
1871 CharDriverState *chr = opaque;
1872 NetCharDriver *s = chr->opaque;
1873
1874 if (s->max_size == 0)
1875 return;
1876 s->bufcnt = socket_recv(s->fd, (void *)s->buf, sizeof(s->buf));
1877 s->bufptr = s->bufcnt;
1878 if (s->bufcnt <= 0)
1879 return;
1880
1881 s->bufptr = 0;
1882 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
1883 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
1884 s->bufptr++;
1885 s->max_size = qemu_chr_can_read(chr);
1886 }
1887}
1888
1889static void udp_chr_update_read_handler(CharDriverState *chr)
1890{
1891 NetCharDriver *s = chr->opaque;
1892
1893 if (s->fd >= 0) {
1894 qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
1895 udp_chr_read, NULL, chr);
1896 }
1897}
1898
1899static void udp_chr_close(CharDriverState *chr)
1900{
1901 NetCharDriver *s = chr->opaque;
1902 if (s->fd >= 0) {
1903 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1904 socket_close(s->fd);
1905 }
1906 qemu_free(s);
1907}
1908
1909static CharDriverState *qemu_chr_open_udp(const char *def)
1910{
1911 CharDriverState *chr = NULL;
1912 NetCharDriver *s = NULL;
1913 int fd = -1;
1914 SockAddress saddr;
1915
1916 chr = qemu_mallocz(sizeof(CharDriverState));
1917 s = qemu_mallocz(sizeof(NetCharDriver));
1918
1919 fd = socket_create_inet(SOCKET_DGRAM);
1920 if (fd < 0) {
1921 perror("socket(PF_INET, SOCK_DGRAM)");
1922 goto return_err;
1923 }
1924
1925 if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
1926 printf("Could not parse: %s\n", def);
1927 goto return_err;
1928 }
1929
1930 if (socket_bind(fd, &saddr) < 0) {
1931 perror("bind");
1932 goto return_err;
1933 }
1934
1935 s->fd = fd;
1936 s->bufcnt = 0;
1937 s->bufptr = 0;
1938 chr->opaque = s;
1939 chr->chr_write = udp_chr_write;
1940 chr->chr_update_read_handler = udp_chr_update_read_handler;
1941 chr->chr_close = udp_chr_close;
1942 return chr;
1943
1944return_err:
1945 if (chr)
1946 free(chr);
1947 if (s)
1948 free(s);
1949 if (fd >= 0)
1950 closesocket(fd);
1951 return NULL;
1952}
1953
1954/***********************************************************/
1955/* TCP Net console */
1956
1957typedef struct {
1958 int fd, listen_fd;
1959 int connected;
1960 int max_size;
1961 int do_telnetopt;
1962 int do_nodelay;
1963 int is_unix;
David Turner9d118822010-09-10 13:02:07 +02001964 int msgfd;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001965} TCPCharDriver;
1966
1967static void tcp_chr_accept(void *opaque);
1968
1969static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1970{
1971 TCPCharDriver *s = chr->opaque;
1972 if (s->connected) {
1973 return send_all(s->fd, buf, len);
1974 } else {
1975 /* XXX: indicate an error ? */
1976 return len;
1977 }
1978}
1979
1980static int tcp_chr_read_poll(void *opaque)
1981{
1982 CharDriverState *chr = opaque;
1983 TCPCharDriver *s = chr->opaque;
1984 if (!s->connected)
1985 return 0;
1986 s->max_size = qemu_chr_can_read(chr);
1987 return s->max_size;
1988}
1989
1990#define IAC 255
1991#define IAC_BREAK 243
1992static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
1993 TCPCharDriver *s,
1994 uint8_t *buf, int *size)
1995{
1996 /* Handle any telnet client's basic IAC options to satisfy char by
1997 * char mode with no echo. All IAC options will be removed from
1998 * the buf and the do_telnetopt variable will be used to track the
1999 * state of the width of the IAC information.
2000 *
2001 * IAC commands come in sets of 3 bytes with the exception of the
2002 * "IAC BREAK" command and the double IAC.
2003 */
2004
2005 int i;
2006 int j = 0;
2007
2008 for (i = 0; i < *size; i++) {
2009 if (s->do_telnetopt > 1) {
2010 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
2011 /* Double IAC means send an IAC */
2012 if (j != i)
2013 buf[j] = buf[i];
2014 j++;
2015 s->do_telnetopt = 1;
2016 } else {
2017 if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
2018 /* Handle IAC break commands by sending a serial break */
2019 qemu_chr_event(chr, CHR_EVENT_BREAK);
2020 s->do_telnetopt++;
2021 }
2022 s->do_telnetopt++;
2023 }
2024 if (s->do_telnetopt >= 4) {
2025 s->do_telnetopt = 1;
2026 }
2027 } else {
2028 if ((unsigned char)buf[i] == IAC) {
2029 s->do_telnetopt = 2;
2030 } else {
2031 if (j != i)
2032 buf[j] = buf[i];
2033 j++;
2034 }
2035 }
2036 }
2037 *size = j;
2038}
2039
David Turner9d118822010-09-10 13:02:07 +02002040static int tcp_get_msgfd(CharDriverState *chr)
2041{
2042 TCPCharDriver *s = chr->opaque;
2043 int fd = s->msgfd;
2044 s->msgfd = -1;
2045 return fd;
2046}
2047
2048#ifndef _WIN32
2049static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
2050{
2051 TCPCharDriver *s = chr->opaque;
2052 struct cmsghdr *cmsg;
2053
2054 for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
2055 int fd;
2056
2057 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
2058 cmsg->cmsg_level != SOL_SOCKET ||
2059 cmsg->cmsg_type != SCM_RIGHTS)
2060 continue;
2061
2062 fd = *((int *)CMSG_DATA(cmsg));
2063 if (fd < 0)
2064 continue;
2065
2066 if (s->msgfd != -1)
2067 close(s->msgfd);
2068 s->msgfd = fd;
2069 }
2070}
2071
2072static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2073{
2074 TCPCharDriver *s = chr->opaque;
2075 struct msghdr msg = { NULL, };
2076 struct iovec iov[1];
2077 union {
2078 struct cmsghdr cmsg;
2079 char control[CMSG_SPACE(sizeof(int))];
2080 } msg_control;
2081 ssize_t ret;
2082
2083 iov[0].iov_base = buf;
2084 iov[0].iov_len = len;
2085
2086 msg.msg_iov = iov;
2087 msg.msg_iovlen = 1;
2088 msg.msg_control = &msg_control;
2089 msg.msg_controllen = sizeof(msg_control);
2090
2091 ret = recvmsg(s->fd, &msg, 0);
2092 if (ret > 0 && s->is_unix)
2093 unix_process_msgfd(chr, &msg);
2094
2095 return ret;
2096}
2097#else
2098static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2099{
2100 TCPCharDriver *s = chr->opaque;
2101 return recv(s->fd, buf, len, 0);
2102}
2103#endif
2104
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002105static void tcp_chr_read(void *opaque)
2106{
2107 CharDriverState *chr = opaque;
2108 TCPCharDriver *s = chr->opaque;
David Turner9d118822010-09-10 13:02:07 +02002109 uint8_t buf[READ_BUF_LEN];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002110 int len, size;
2111
2112 if (!s->connected || s->max_size <= 0)
2113 return;
2114 len = sizeof(buf);
2115 if (len > s->max_size)
2116 len = s->max_size;
David Turner9d118822010-09-10 13:02:07 +02002117 size = tcp_chr_recv(chr, (void *)buf, len);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002118 if (size == 0) {
2119 /* connection closed */
2120 s->connected = 0;
2121 if (s->listen_fd >= 0) {
2122 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2123 }
2124 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
2125 socket_close(s->fd);
2126 s->fd = -1;
David Turner9d118822010-09-10 13:02:07 +02002127 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002128 } else if (size > 0) {
2129 if (s->do_telnetopt)
2130 tcp_chr_process_IAC_bytes(chr, s, buf, &size);
2131 if (size > 0)
2132 qemu_chr_read(chr, buf, size);
2133 }
2134}
2135
David Turner9d118822010-09-10 13:02:07 +02002136#ifndef _WIN32
2137CharDriverState *qemu_chr_open_eventfd(int eventfd)
2138{
2139 return qemu_chr_open_fd(eventfd, eventfd);
2140}
2141#endif
2142
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002143static void tcp_chr_connect(void *opaque)
2144{
2145 CharDriverState *chr = opaque;
2146 TCPCharDriver *s = chr->opaque;
2147
2148 s->connected = 1;
2149 qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
2150 tcp_chr_read, NULL, chr);
David Turner9d118822010-09-10 13:02:07 +02002151 qemu_chr_generic_open(chr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002152}
2153
2154#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
2155static void tcp_chr_telnet_init(int fd)
2156{
2157 char buf[3];
2158 /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
2159 IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
2160 socket_send(fd, (char *)buf, 3);
2161 IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
2162 socket_send(fd, (char *)buf, 3);
2163 IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
2164 socket_send(fd, (char *)buf, 3);
2165 IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
2166 socket_send(fd, (char *)buf, 3);
2167}
2168
2169static void tcp_chr_accept(void *opaque)
2170{
2171 CharDriverState *chr = opaque;
2172 TCPCharDriver *s = chr->opaque;
2173 int fd;
2174
2175 for(;;) {
2176 fd = socket_accept(s->listen_fd, NULL);
2177 if (fd < 0) {
2178 return;
2179 } else if (fd >= 0) {
2180 if (s->do_telnetopt)
2181 tcp_chr_telnet_init(fd);
2182 break;
2183 }
2184 }
2185 socket_set_nonblock(fd);
2186 if (s->do_nodelay)
2187 socket_set_nodelay(fd);
2188 s->fd = fd;
2189 qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
2190 tcp_chr_connect(chr);
2191}
2192
2193static void tcp_chr_close(CharDriverState *chr)
2194{
2195 TCPCharDriver *s = chr->opaque;
2196 if (s->fd >= 0) {
2197 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
2198 closesocket(s->fd);
2199 }
2200 if (s->listen_fd >= 0) {
2201 qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
2202 closesocket(s->listen_fd);
2203 }
2204 qemu_free(s);
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02002205 qemu_chr_event(chr, CHR_EVENT_CLOSED);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002206}
2207
2208static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2209 int is_telnet,
2210 int is_unix)
2211{
2212 CharDriverState *chr = NULL;
2213 TCPCharDriver *s = NULL;
2214 int fd = -1, offset = 0;
2215 int is_listen = 0;
2216 int is_waitconnect = 1;
2217 int do_nodelay = 0;
2218 const char *ptr;
2219
2220 ptr = host_str;
2221 while((ptr = strchr(ptr,','))) {
2222 ptr++;
2223 if (!strncmp(ptr,"server",6)) {
2224 is_listen = 1;
2225 } else if (!strncmp(ptr,"nowait",6)) {
2226 is_waitconnect = 0;
2227 } else if (!strncmp(ptr,"nodelay",6)) {
2228 do_nodelay = 1;
2229 } else if (!strncmp(ptr,"to=",3)) {
2230 /* nothing, inet_listen() parses this one */;
2231 } else if (!strncmp(ptr,"ipv4",4)) {
2232 /* nothing, inet_connect() and inet_listen() parse this one */;
2233 } else if (!strncmp(ptr,"ipv6",4)) {
2234 /* nothing, inet_connect() and inet_listen() parse this one */;
2235 } else {
2236 printf("Unknown option: %s\n", ptr);
2237 goto fail;
2238 }
2239 }
2240 if (!is_listen)
2241 is_waitconnect = 0;
2242
2243 chr = qemu_mallocz(sizeof(CharDriverState));
2244 s = qemu_mallocz(sizeof(TCPCharDriver));
2245
2246 if (is_listen) {
2247 chr->filename = qemu_malloc(256);
2248 if (is_unix) {
2249 pstrcpy(chr->filename, 256, "unix:");
2250 } else if (is_telnet) {
2251 pstrcpy(chr->filename, 256, "telnet:");
2252 } else {
2253 pstrcpy(chr->filename, 256, "tcp:");
2254 }
2255 offset = strlen(chr->filename);
2256 }
2257 if (is_unix) {
2258 if (is_listen) {
2259 fd = unix_listen(host_str, chr->filename + offset, 256 - offset);
2260 } else {
2261 fd = unix_connect(host_str);
2262 }
2263 } else {
David 'Digit' Turnere92bc562010-09-07 06:21:25 -07002264#ifdef CONFIG_ANDROID
2265 if (!strncmp(host_str,"socket=",7)) {
2266 char *end;
2267 long val = strtol(host_str+7, &end, 10);
2268 if (val <= 0 || end == host_str+7) {
2269 printf("Invalid socket number: '%s'\n", host_str+7);
2270 goto fail;
2271 }
2272 fd = (int) val;
2273 } else
2274#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002275 if (is_listen) {
2276 fd = inet_listen(host_str, chr->filename + offset, 256 - offset,
2277 SOCKET_STREAM, 0);
2278 } else {
2279 fd = inet_connect(host_str, SOCKET_STREAM);
2280 }
2281 }
2282 if (fd < 0)
2283 goto fail;
2284
2285 if (!is_waitconnect)
2286 socket_set_nonblock(fd);
2287
2288 s->connected = 0;
2289 s->fd = -1;
2290 s->listen_fd = -1;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02002291 s->msgfd = -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002292 s->is_unix = is_unix;
2293 s->do_nodelay = do_nodelay && !is_unix;
2294
2295 chr->opaque = s;
2296 chr->chr_write = tcp_chr_write;
2297 chr->chr_close = tcp_chr_close;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02002298 chr->get_msgfd = tcp_get_msgfd;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002299
2300 if (is_listen) {
2301 s->listen_fd = fd;
2302 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2303 if (is_telnet)
2304 s->do_telnetopt = 1;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02002305
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002306 } else {
2307 s->connected = 1;
2308 s->fd = fd;
2309 socket_set_nodelay(fd);
2310 tcp_chr_connect(chr);
2311 }
2312
2313 if (is_listen && is_waitconnect) {
2314 printf("QEMU waiting for connection on: %s\n",
2315 chr->filename ? chr->filename : host_str);
2316 tcp_chr_accept(chr);
2317 socket_set_nonblock(s->listen_fd);
2318 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002319 return chr;
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02002320
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002321 fail:
2322 if (fd >= 0)
2323 closesocket(fd);
2324 qemu_free(s);
2325 qemu_free(chr);
2326 return NULL;
2327}
2328
2329CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
2330{
2331 const char *p;
2332 CharDriverState *chr;
2333
2334 if (!strcmp(filename, "vc")) {
David Turnerf52506f2010-09-10 16:11:22 +02002335 chr = text_console_init_compat(label, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002336 } else
2337 if (strstart(filename, "vc:", &p)) {
David Turnerf52506f2010-09-10 16:11:22 +02002338 chr = text_console_init_compat(label, p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002339 } else
2340 if (!strcmp(filename, "null")) {
2341 chr = qemu_chr_open_null();
2342 } else
2343 if (strstart(filename, "tcp:", &p)) {
2344 chr = qemu_chr_open_tcp(p, 0, 0);
2345 } else
2346 if (strstart(filename, "telnet:", &p)) {
2347 chr = qemu_chr_open_tcp(p, 1, 0);
2348 } else
2349 if (strstart(filename, "udp:", &p)) {
2350 chr = qemu_chr_open_udp(p);
2351 } else
2352 if (strstart(filename, "mon:", &p)) {
2353 chr = qemu_chr_open(label, p, NULL);
2354 if (chr) {
2355 chr = qemu_chr_open_mux(chr);
2356 monitor_init(chr, MONITOR_USE_READLINE);
2357 } else {
2358 printf("Unable to open driver: %s\n", p);
2359 }
2360 } else if (!strcmp(filename, "msmouse")) {
2361 chr = qemu_chr_open_msmouse();
2362 } else
2363#ifndef _WIN32
2364 if (strstart(filename, "unix:", &p)) {
2365 chr = qemu_chr_open_tcp(p, 0, 1);
2366 } else if (strstart(filename, "file:", &p)) {
2367 chr = qemu_chr_open_file_out(p);
2368 } else if (strstart(filename, "pipe:", &p)) {
2369 chr = qemu_chr_open_pipe(p);
David 'Digit' Turner162f35e2009-09-18 23:05:39 -07002370 } else if (strstart(filename, "fdpair:", &p)) {
2371 chr = qemu_chr_open_fdpair(p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002372 } else if (!strcmp(filename, "pty")) {
2373 chr = qemu_chr_open_pty();
2374 } else if (!strcmp(filename, "stdio")) {
2375 chr = qemu_chr_open_stdio();
2376 } else
2377#if defined(__linux__)
2378 if (strstart(filename, "/dev/parport", NULL)) {
2379 chr = qemu_chr_open_pp(filename);
2380 } else
2381#elif defined(__FreeBSD__) || defined(__DragonFly__)
2382 if (strstart(filename, "/dev/ppi", NULL)) {
2383 chr = qemu_chr_open_pp(filename);
2384 } else
2385#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002386 if (strstart(filename, "/dev/", NULL)) {
2387 chr = qemu_chr_open_tty(filename);
2388 } else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002389#else /* !_WIN32 */
2390 if (strstart(filename, "COM", NULL)) {
2391 chr = qemu_chr_open_win(filename);
2392 } else
2393 if (strstart(filename, "pipe:", &p)) {
2394 chr = qemu_chr_open_win_pipe(p);
2395 } else
2396 if (strstart(filename, "con:", NULL)) {
2397 chr = qemu_chr_open_win_con(filename);
2398 } else
2399 if (strstart(filename, "file:", &p)) {
2400 chr = qemu_chr_open_win_file_out(p);
2401 } else
2402#endif
2403 if (!strcmp(filename, "android-modem")) {
2404 CharDriverState* cs;
2405 qemu_chr_open_charpipe( &cs, &android_modem_cs );
2406 return cs;
2407 } else if (!strcmp(filename, "android-gps")) {
2408 CharDriverState* cs;
2409 qemu_chr_open_charpipe( &cs, &android_gps_cs );
2410 return cs;
2411 } else if (!strcmp(filename, "android-kmsg")) {
2412 return android_kmsg_get_cs();
2413 } else if (!strcmp(filename, "android-qemud")) {
2414 return android_qemud_get_cs();
2415 } else
2416#ifdef CONFIG_BRLAPI
2417 if (!strcmp(filename, "braille")) {
2418 chr = chr_baum_init();
2419 } else
2420#endif
2421 {
2422 chr = NULL;
2423 }
2424
2425 if (chr) {
2426 if (!chr->filename)
2427 chr->filename = qemu_strdup(filename);
2428 chr->init = init;
2429 chr->label = qemu_strdup(label);
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002430 QTAILQ_INSERT_TAIL(&chardevs, chr, next);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002431 }
2432 return chr;
2433}
2434
David 'Digit' Turner17410ee2011-05-10 10:55:21 +02002435void qemu_chr_set_echo(struct CharDriverState *chr, bool echo)
2436{
2437 if (chr->chr_set_echo) {
2438 chr->chr_set_echo(chr, echo);
2439 }
2440}
2441
2442void qemu_chr_guest_open(struct CharDriverState *chr)
2443{
2444 if (chr->chr_guest_open) {
2445 chr->chr_guest_open(chr);
2446 }
2447}
2448
2449void qemu_chr_guest_close(struct CharDriverState *chr)
2450{
2451 if (chr->chr_guest_close) {
2452 chr->chr_guest_close(chr);
2453 }
2454}
2455
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002456void qemu_chr_close(CharDriverState *chr)
2457{
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002458 QTAILQ_REMOVE(&chardevs, chr, next);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002459 if (chr->chr_close)
2460 chr->chr_close(chr);
2461 qemu_free(chr->filename);
2462 qemu_free(chr->label);
2463 qemu_free(chr);
2464}
2465
2466void qemu_chr_info(Monitor *mon)
2467{
2468 CharDriverState *chr;
2469
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002470 QTAILQ_FOREACH(chr, &chardevs, next) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002471 monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename);
2472 }
2473}
David Turner9d118822010-09-10 13:02:07 +02002474
2475CharDriverState *qemu_chr_find(const char *name)
2476{
2477 CharDriverState *chr;
2478
2479 QTAILQ_FOREACH(chr, &chardevs, next) {
2480 if (strcmp(chr->label, name) != 0)
2481 continue;
2482 return chr;
2483 }
2484 return NULL;
2485}