|
|
1.1 root 1: /*
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 "net.h"
1.1.1.4 root 26: #include "monitor.h"
1.1 root 27: #include "console.h"
28: #include "sysemu.h"
29: #include "qemu-timer.h"
30: #include "qemu-char.h"
31: #include "hw/usb.h"
32: #include "hw/baum.h"
33: #include "hw/msmouse.h"
1.1.1.12 root 34: #include "qmp-commands.h"
1.1 root 35:
36: #include <unistd.h>
37: #include <fcntl.h>
38: #include <time.h>
39: #include <errno.h>
40: #include <sys/time.h>
41: #include <zlib.h>
42:
43: #ifndef _WIN32
44: #include <sys/times.h>
45: #include <sys/wait.h>
46: #include <termios.h>
47: #include <sys/mman.h>
48: #include <sys/ioctl.h>
49: #include <sys/resource.h>
50: #include <sys/socket.h>
51: #include <netinet/in.h>
52: #include <net/if.h>
53: #include <arpa/inet.h>
54: #include <dirent.h>
55: #include <netdb.h>
56: #include <sys/select.h>
1.1.1.5 root 57: #ifdef CONFIG_BSD
1.1 root 58: #include <sys/stat.h>
1.1.1.5 root 59: #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1.1 root 60: #include <libutil.h>
61: #include <dev/ppbus/ppi.h>
62: #include <dev/ppbus/ppbconf.h>
1.1.1.5 root 63: #if defined(__GLIBC__)
64: #include <pty.h>
65: #endif
1.1.1.4 root 66: #elif defined(__DragonFly__)
67: #include <libutil.h>
68: #include <dev/misc/ppi/ppi.h>
69: #include <bus/ppbus/ppbconf.h>
1.1 root 70: #else
71: #include <util.h>
72: #endif
73: #else
74: #ifdef __linux__
75: #include <pty.h>
76:
77: #include <linux/ppdev.h>
78: #include <linux/parport.h>
79: #endif
80: #ifdef __sun__
81: #include <sys/stat.h>
82: #include <sys/ethernet.h>
83: #include <sys/sockio.h>
84: #include <netinet/arp.h>
85: #include <netinet/in.h>
86: #include <netinet/in_systm.h>
87: #include <netinet/ip.h>
88: #include <netinet/ip_icmp.h> // must come after ip.h
89: #include <netinet/udp.h>
90: #include <netinet/tcp.h>
91: #include <net/if.h>
92: #include <syslog.h>
93: #include <stropts.h>
94: #endif
95: #endif
96: #endif
97:
98: #include "qemu_socket.h"
1.1.1.9 root 99: #include "ui/qemu-spice.h"
1.1 root 100:
1.1.1.5 root 101: #define READ_BUF_LEN 4096
102:
1.1 root 103: /***********************************************************/
104: /* character device */
105:
1.1.1.5 root 106: static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
107: QTAILQ_HEAD_INITIALIZER(chardevs);
1.1.1.2 root 108:
1.1.1.12 root 109: void qemu_chr_be_event(CharDriverState *s, int event)
1.1 root 110: {
1.1.1.8 root 111: /* Keep track if the char device is open */
112: switch (event) {
113: case CHR_EVENT_OPENED:
114: s->opened = 1;
115: break;
116: case CHR_EVENT_CLOSED:
117: s->opened = 0;
118: break;
119: }
120:
1.1 root 121: if (!s->chr_event)
122: return;
123: s->chr_event(s->handler_opaque, event);
124: }
125:
1.1.1.5 root 126: static void qemu_chr_generic_open_bh(void *opaque)
1.1 root 127: {
128: CharDriverState *s = opaque;
1.1.1.12 root 129: qemu_chr_be_event(s, CHR_EVENT_OPENED);
1.1 root 130: qemu_bh_delete(s->bh);
131: s->bh = NULL;
132: }
133:
1.1.1.5 root 134: void qemu_chr_generic_open(CharDriverState *s)
1.1 root 135: {
1.1.1.5 root 136: if (s->bh == NULL) {
137: s->bh = qemu_bh_new(qemu_chr_generic_open_bh, s);
1.1 root 138: qemu_bh_schedule(s->bh);
139: }
140: }
141:
1.1.1.12 root 142: int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
1.1 root 143: {
144: return s->chr_write(s, buf, len);
145: }
146:
1.1.1.12 root 147: int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
1.1 root 148: {
149: if (!s->chr_ioctl)
150: return -ENOTSUP;
151: return s->chr_ioctl(s, cmd, arg);
152: }
153:
1.1.1.12 root 154: int qemu_chr_be_can_write(CharDriverState *s)
1.1 root 155: {
156: if (!s->chr_can_read)
157: return 0;
158: return s->chr_can_read(s->handler_opaque);
159: }
160:
1.1.1.12 root 161: void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
1.1 root 162: {
1.1.1.13! root 163: if (s->chr_read) {
! 164: s->chr_read(s->handler_opaque, buf, len);
! 165: }
1.1 root 166: }
167:
1.1.1.12 root 168: int qemu_chr_fe_get_msgfd(CharDriverState *s)
1.1.1.4 root 169: {
170: return s->get_msgfd ? s->get_msgfd(s) : -1;
171: }
172:
1.1.1.11 root 173: int qemu_chr_add_client(CharDriverState *s, int fd)
174: {
175: return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
176: }
177:
1.1 root 178: void qemu_chr_accept_input(CharDriverState *s)
179: {
180: if (s->chr_accept_input)
181: s->chr_accept_input(s);
1.1.1.13! root 182: qemu_notify_event();
1.1 root 183: }
184:
1.1.1.12 root 185: void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
1.1 root 186: {
1.1.1.5 root 187: char buf[READ_BUF_LEN];
1.1 root 188: va_list ap;
189: va_start(ap, fmt);
190: vsnprintf(buf, sizeof(buf), fmt, ap);
1.1.1.12 root 191: qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
1.1 root 192: va_end(ap);
193: }
194:
195: void qemu_chr_add_handlers(CharDriverState *s,
1.1.1.8 root 196: IOCanReadHandler *fd_can_read,
1.1 root 197: IOReadHandler *fd_read,
198: IOEventHandler *fd_event,
199: void *opaque)
200: {
1.1.1.11 root 201: if (!opaque && !fd_can_read && !fd_read && !fd_event) {
202: /* chr driver being released. */
203: ++s->avail_connections;
204: }
1.1 root 205: s->chr_can_read = fd_can_read;
206: s->chr_read = fd_read;
207: s->chr_event = fd_event;
208: s->handler_opaque = opaque;
209: if (s->chr_update_read_handler)
210: s->chr_update_read_handler(s);
1.1.1.8 root 211:
212: /* We're connecting to an already opened device, so let's make sure we
213: also get the open event */
214: if (s->opened) {
215: qemu_chr_generic_open(s);
216: }
1.1 root 217: }
218:
219: static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
220: {
221: return len;
222: }
223:
1.1.1.13! root 224: static CharDriverState *qemu_chr_open_null(QemuOpts *opts)
1.1 root 225: {
226: CharDriverState *chr;
227:
1.1.1.12 root 228: chr = g_malloc0(sizeof(CharDriverState));
1.1 root 229: chr->chr_write = null_chr_write;
1.1.1.13! root 230: return chr;
1.1 root 231: }
232:
233: /* MUX driver for serial I/O splitting */
234: #define MAX_MUX 4
235: #define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
236: #define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
237: typedef struct {
1.1.1.8 root 238: IOCanReadHandler *chr_can_read[MAX_MUX];
1.1 root 239: IOReadHandler *chr_read[MAX_MUX];
240: IOEventHandler *chr_event[MAX_MUX];
241: void *ext_opaque[MAX_MUX];
242: CharDriverState *drv;
1.1.1.5 root 243: int focus;
1.1 root 244: int mux_cnt;
245: int term_got_escape;
246: int max_size;
1.1.1.2 root 247: /* Intermediate input buffer allows to catch escape sequences even if the
248: currently active device is not accepting any input - but only until it
249: is full as well. */
250: unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
251: int prod[MAX_MUX];
252: int cons[MAX_MUX];
1.1.1.4 root 253: int timestamps;
254: int linestart;
255: int64_t timestamps_start;
1.1 root 256: } MuxDriver;
257:
258:
259: static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
260: {
261: MuxDriver *d = chr->opaque;
262: int ret;
1.1.1.4 root 263: if (!d->timestamps) {
1.1 root 264: ret = d->drv->chr_write(d->drv, buf, len);
265: } else {
266: int i;
267:
268: ret = 0;
1.1.1.4 root 269: for (i = 0; i < len; i++) {
270: if (d->linestart) {
1.1 root 271: char buf1[64];
272: int64_t ti;
273: int secs;
274:
1.1.1.11 root 275: ti = qemu_get_clock_ms(rt_clock);
1.1.1.4 root 276: if (d->timestamps_start == -1)
277: d->timestamps_start = ti;
278: ti -= d->timestamps_start;
1.1 root 279: secs = ti / 1000;
280: snprintf(buf1, sizeof(buf1),
281: "[%02d:%02d:%02d.%03d] ",
282: secs / 3600,
283: (secs / 60) % 60,
284: secs % 60,
285: (int)(ti % 1000));
286: d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
1.1.1.4 root 287: d->linestart = 0;
288: }
289: ret += d->drv->chr_write(d->drv, buf+i, 1);
290: if (buf[i] == '\n') {
291: d->linestart = 1;
1.1 root 292: }
293: }
294: }
295: return ret;
296: }
297:
298: static const char * const mux_help[] = {
299: "% h print this help\n\r",
300: "% x exit emulator\n\r",
301: "% s save disk data back to file (if -snapshot)\n\r",
302: "% t toggle console timestamps\n\r"
303: "% b send break (magic sysrq)\n\r",
304: "% c switch between console and monitor\n\r",
305: "% % sends %\n\r",
306: NULL
307: };
308:
309: int term_escape_char = 0x01; /* ctrl-a is used for escape */
310: static void mux_print_help(CharDriverState *chr)
311: {
312: int i, j;
313: char ebuf[15] = "Escape-Char";
314: char cbuf[50] = "\n\r";
315:
316: if (term_escape_char > 0 && term_escape_char < 26) {
317: snprintf(cbuf, sizeof(cbuf), "\n\r");
318: snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
319: } else {
320: snprintf(cbuf, sizeof(cbuf),
321: "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
322: term_escape_char);
323: }
324: chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
325: for (i = 0; mux_help[i] != NULL; i++) {
326: for (j=0; mux_help[i][j] != '\0'; j++) {
327: if (mux_help[i][j] == '%')
328: chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
329: else
330: chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
331: }
332: }
333: }
334:
1.1.1.4 root 335: static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event)
336: {
337: if (d->chr_event[mux_nr])
338: d->chr_event[mux_nr](d->ext_opaque[mux_nr], event);
339: }
340:
1.1 root 341: static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
342: {
343: if (d->term_got_escape) {
344: d->term_got_escape = 0;
345: if (ch == term_escape_char)
346: goto send_char;
347: switch(ch) {
348: case '?':
349: case 'h':
350: mux_print_help(chr);
351: break;
352: case 'x':
353: {
354: const char *term = "QEMU: Terminated\n\r";
355: chr->chr_write(chr,(uint8_t *)term,strlen(term));
356: exit(0);
357: break;
358: }
359: case 's':
1.1.1.8 root 360: bdrv_commit_all();
1.1 root 361: break;
362: case 'b':
1.1.1.12 root 363: qemu_chr_be_event(chr, CHR_EVENT_BREAK);
1.1 root 364: break;
365: case 'c':
366: /* Switch to the next registered device */
1.1.1.5 root 367: mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
368: d->focus++;
369: if (d->focus >= d->mux_cnt)
370: d->focus = 0;
371: mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
1.1.1.4 root 372: break;
373: case 't':
374: d->timestamps = !d->timestamps;
375: d->timestamps_start = -1;
376: d->linestart = 0;
1.1 root 377: break;
378: }
379: } else if (ch == term_escape_char) {
380: d->term_got_escape = 1;
381: } else {
382: send_char:
383: return 1;
384: }
385: return 0;
386: }
387:
388: static void mux_chr_accept_input(CharDriverState *chr)
389: {
390: MuxDriver *d = chr->opaque;
1.1.1.5 root 391: int m = d->focus;
1.1 root 392:
1.1.1.2 root 393: while (d->prod[m] != d->cons[m] &&
1.1 root 394: d->chr_can_read[m] &&
395: d->chr_can_read[m](d->ext_opaque[m])) {
396: d->chr_read[m](d->ext_opaque[m],
1.1.1.2 root 397: &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
1.1 root 398: }
399: }
400:
401: static int mux_chr_can_read(void *opaque)
402: {
403: CharDriverState *chr = opaque;
404: MuxDriver *d = chr->opaque;
1.1.1.5 root 405: int m = d->focus;
1.1 root 406:
1.1.1.2 root 407: if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
1.1 root 408: return 1;
1.1.1.2 root 409: if (d->chr_can_read[m])
410: return d->chr_can_read[m](d->ext_opaque[m]);
1.1 root 411: return 0;
412: }
413:
414: static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
415: {
416: CharDriverState *chr = opaque;
417: MuxDriver *d = chr->opaque;
1.1.1.5 root 418: int m = d->focus;
1.1 root 419: int i;
420:
421: mux_chr_accept_input (opaque);
422:
423: for(i = 0; i < size; i++)
424: if (mux_proc_byte(chr, d, buf[i])) {
1.1.1.2 root 425: if (d->prod[m] == d->cons[m] &&
1.1 root 426: d->chr_can_read[m] &&
427: d->chr_can_read[m](d->ext_opaque[m]))
428: d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
429: else
1.1.1.2 root 430: d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
1.1 root 431: }
432: }
433:
434: static void mux_chr_event(void *opaque, int event)
435: {
436: CharDriverState *chr = opaque;
437: MuxDriver *d = chr->opaque;
438: int i;
439:
440: /* Send the event to all registered listeners */
441: for (i = 0; i < d->mux_cnt; i++)
1.1.1.4 root 442: mux_chr_send_event(d, i, event);
1.1 root 443: }
444:
445: static void mux_chr_update_read_handler(CharDriverState *chr)
446: {
447: MuxDriver *d = chr->opaque;
448:
449: if (d->mux_cnt >= MAX_MUX) {
450: fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
451: return;
452: }
453: d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
454: d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
455: d->chr_read[d->mux_cnt] = chr->chr_read;
456: d->chr_event[d->mux_cnt] = chr->chr_event;
457: /* Fix up the real driver with mux routines */
458: if (d->mux_cnt == 0) {
459: qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
460: mux_chr_event, chr);
461: }
1.1.1.5 root 462: if (d->focus != -1) {
463: mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
464: }
465: d->focus = d->mux_cnt;
1.1 root 466: d->mux_cnt++;
1.1.1.5 root 467: mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
1.1 root 468: }
469:
470: static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
471: {
472: CharDriverState *chr;
473: MuxDriver *d;
474:
1.1.1.12 root 475: chr = g_malloc0(sizeof(CharDriverState));
476: d = g_malloc0(sizeof(MuxDriver));
1.1 root 477:
478: chr->opaque = d;
479: d->drv = drv;
1.1.1.5 root 480: d->focus = -1;
1.1 root 481: chr->chr_write = mux_chr_write;
482: chr->chr_update_read_handler = mux_chr_update_read_handler;
483: chr->chr_accept_input = mux_chr_accept_input;
1.1.1.11 root 484: /* Frontend guest-open / -close notification is not support with muxes */
485: chr->chr_guest_open = NULL;
486: chr->chr_guest_close = NULL;
1.1.1.8 root 487:
488: /* Muxes are always open on creation */
489: qemu_chr_generic_open(chr);
490:
1.1 root 491: return chr;
492: }
493:
494:
495: #ifdef _WIN32
496: int send_all(int fd, const void *buf, int len1)
497: {
498: int ret, len;
499:
500: len = len1;
501: while (len > 0) {
502: ret = send(fd, buf, len, 0);
503: if (ret < 0) {
504: errno = WSAGetLastError();
505: if (errno != WSAEWOULDBLOCK) {
506: return -1;
507: }
508: } else if (ret == 0) {
509: break;
510: } else {
511: buf += ret;
512: len -= ret;
513: }
514: }
515: return len1 - len;
516: }
517:
518: #else
519:
1.1.1.9 root 520: int send_all(int fd, const void *_buf, int len1)
1.1 root 521: {
522: int ret, len;
1.1.1.9 root 523: const uint8_t *buf = _buf;
1.1 root 524:
525: len = len1;
526: while (len > 0) {
527: ret = write(fd, buf, len);
528: if (ret < 0) {
529: if (errno != EINTR && errno != EAGAIN)
530: return -1;
531: } else if (ret == 0) {
532: break;
533: } else {
534: buf += ret;
535: len -= ret;
536: }
537: }
538: return len1 - len;
539: }
540: #endif /* !_WIN32 */
541:
1.1.1.12 root 542: #define STDIO_MAX_CLIENTS 1
543: static int stdio_nb_clients;
544:
1.1 root 545: #ifndef _WIN32
546:
547: typedef struct {
548: int fd_in, fd_out;
549: int max_size;
550: } FDCharDriver;
551:
552:
553: static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
554: {
555: FDCharDriver *s = chr->opaque;
556: return send_all(s->fd_out, buf, len);
557: }
558:
559: static int fd_chr_read_poll(void *opaque)
560: {
561: CharDriverState *chr = opaque;
562: FDCharDriver *s = chr->opaque;
563:
1.1.1.12 root 564: s->max_size = qemu_chr_be_can_write(chr);
1.1 root 565: return s->max_size;
566: }
567:
568: static void fd_chr_read(void *opaque)
569: {
570: CharDriverState *chr = opaque;
571: FDCharDriver *s = chr->opaque;
572: int size, len;
1.1.1.5 root 573: uint8_t buf[READ_BUF_LEN];
1.1 root 574:
575: len = sizeof(buf);
576: if (len > s->max_size)
577: len = s->max_size;
578: if (len == 0)
579: return;
580: size = read(s->fd_in, buf, len);
581: if (size == 0) {
582: /* FD has been closed. Remove it from the active list. */
583: qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
1.1.1.12 root 584: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 585: return;
586: }
587: if (size > 0) {
1.1.1.12 root 588: qemu_chr_be_write(chr, buf, size);
1.1 root 589: }
590: }
591:
592: static void fd_chr_update_read_handler(CharDriverState *chr)
593: {
594: FDCharDriver *s = chr->opaque;
595:
596: if (s->fd_in >= 0) {
1.1.1.4 root 597: if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
1.1 root 598: } else {
599: qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
600: fd_chr_read, NULL, chr);
601: }
602: }
603: }
604:
605: static void fd_chr_close(struct CharDriverState *chr)
606: {
607: FDCharDriver *s = chr->opaque;
608:
609: if (s->fd_in >= 0) {
1.1.1.4 root 610: if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
1.1 root 611: } else {
612: qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
613: }
614: }
615:
1.1.1.12 root 616: g_free(s);
617: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 618: }
619:
620: /* open a character device to a unix fd */
621: static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
622: {
623: CharDriverState *chr;
624: FDCharDriver *s;
625:
1.1.1.12 root 626: chr = g_malloc0(sizeof(CharDriverState));
627: s = g_malloc0(sizeof(FDCharDriver));
1.1 root 628: s->fd_in = fd_in;
629: s->fd_out = fd_out;
630: chr->opaque = s;
631: chr->chr_write = fd_chr_write;
632: chr->chr_update_read_handler = fd_chr_update_read_handler;
633: chr->chr_close = fd_chr_close;
634:
1.1.1.5 root 635: qemu_chr_generic_open(chr);
1.1 root 636:
637: return chr;
638: }
639:
1.1.1.13! root 640: static CharDriverState *qemu_chr_open_file_out(QemuOpts *opts)
1.1 root 641: {
642: int fd_out;
643:
1.1.1.5 root 644: TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"),
645: O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
1.1.1.11 root 646: if (fd_out < 0) {
1.1.1.13! root 647: return NULL;
1.1.1.11 root 648: }
1.1.1.13! root 649: return qemu_chr_open_fd(-1, fd_out);
1.1 root 650: }
651:
1.1.1.13! root 652: static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts)
1.1 root 653: {
654: int fd_in, fd_out;
655: char filename_in[256], filename_out[256];
1.1.1.5 root 656: const char *filename = qemu_opt_get(opts, "path");
657:
658: if (filename == NULL) {
659: fprintf(stderr, "chardev: pipe: no filename given\n");
1.1.1.13! root 660: return NULL;
1.1.1.5 root 661: }
1.1 root 662:
663: snprintf(filename_in, 256, "%s.in", filename);
664: snprintf(filename_out, 256, "%s.out", filename);
1.1.1.5 root 665: TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
666: TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
1.1 root 667: if (fd_in < 0 || fd_out < 0) {
668: if (fd_in >= 0)
669: close(fd_in);
670: if (fd_out >= 0)
671: close(fd_out);
1.1.1.11 root 672: TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
673: if (fd_in < 0) {
1.1.1.13! root 674: return NULL;
1.1.1.11 root 675: }
1.1 root 676: }
1.1.1.13! root 677: return qemu_chr_open_fd(fd_in, fd_out);
1.1 root 678: }
679:
680:
681: /* for STDIO, we handle the case where several clients use it
682: (nographic mode) */
683:
684: #define TERM_FIFO_MAX_SIZE 1
685:
686: static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
687: static int term_fifo_size;
688:
689: static int stdio_read_poll(void *opaque)
690: {
691: CharDriverState *chr = opaque;
692:
693: /* try to flush the queue if needed */
1.1.1.12 root 694: if (term_fifo_size != 0 && qemu_chr_be_can_write(chr) > 0) {
695: qemu_chr_be_write(chr, term_fifo, 1);
1.1 root 696: term_fifo_size = 0;
697: }
698: /* see if we can absorb more chars */
699: if (term_fifo_size == 0)
700: return 1;
701: else
702: return 0;
703: }
704:
705: static void stdio_read(void *opaque)
706: {
707: int size;
708: uint8_t buf[1];
709: CharDriverState *chr = opaque;
710:
711: size = read(0, buf, 1);
712: if (size == 0) {
713: /* stdin has been closed. Remove it from the active list. */
714: qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
1.1.1.12 root 715: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 716: return;
717: }
718: if (size > 0) {
1.1.1.12 root 719: if (qemu_chr_be_can_write(chr) > 0) {
720: qemu_chr_be_write(chr, buf, 1);
1.1 root 721: } else if (term_fifo_size == 0) {
722: term_fifo[term_fifo_size++] = buf[0];
723: }
724: }
725: }
726:
727: /* init terminal so that we can grab keys */
728: static struct termios oldtty;
729: static int old_fd0_flags;
1.1.1.9 root 730: static bool stdio_allow_signal;
1.1 root 731:
732: static void term_exit(void)
733: {
734: tcsetattr (0, TCSANOW, &oldtty);
735: fcntl(0, F_SETFL, old_fd0_flags);
736: }
737:
1.1.1.9 root 738: static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
1.1 root 739: {
740: struct termios tty;
741:
1.1.1.9 root 742: tty = oldtty;
743: if (!echo) {
744: tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1.1 root 745: |INLCR|IGNCR|ICRNL|IXON);
1.1.1.9 root 746: tty.c_oflag |= OPOST;
747: tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
748: tty.c_cflag &= ~(CSIZE|PARENB);
749: tty.c_cflag |= CS8;
750: tty.c_cc[VMIN] = 1;
751: tty.c_cc[VTIME] = 0;
752: }
1.1 root 753: /* if graphical mode, we allow Ctrl-C handling */
1.1.1.9 root 754: if (!stdio_allow_signal)
1.1 root 755: tty.c_lflag &= ~ISIG;
756:
757: tcsetattr (0, TCSANOW, &tty);
758: }
759:
760: static void qemu_chr_close_stdio(struct CharDriverState *chr)
761: {
762: term_exit();
763: stdio_nb_clients--;
764: qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
765: fd_chr_close(chr);
766: }
767:
1.1.1.13! root 768: static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts)
1.1 root 769: {
770: CharDriverState *chr;
771:
1.1.1.11 root 772: if (stdio_nb_clients >= STDIO_MAX_CLIENTS) {
1.1.1.13! root 773: return NULL;
1.1.1.11 root 774: }
1.1.1.9 root 775: if (stdio_nb_clients == 0) {
776: old_fd0_flags = fcntl(0, F_GETFL);
777: tcgetattr (0, &oldtty);
778: fcntl(0, F_SETFL, O_NONBLOCK);
779: atexit(term_exit);
780: }
781:
1.1 root 782: chr = qemu_chr_open_fd(0, 1);
783: chr->chr_close = qemu_chr_close_stdio;
1.1.1.9 root 784: chr->chr_set_echo = qemu_chr_set_echo_stdio;
1.1 root 785: qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
786: stdio_nb_clients++;
1.1.1.9 root 787: stdio_allow_signal = qemu_opt_get_bool(opts, "signal",
788: display_type != DT_NOGRAPHIC);
1.1.1.12 root 789: qemu_chr_fe_set_echo(chr, false);
1.1 root 790:
1.1.1.13! root 791: return chr;
1.1 root 792: }
793:
794: #ifdef __sun__
795: /* Once Solaris has openpty(), this is going to be removed. */
1.1.1.4 root 796: static int openpty(int *amaster, int *aslave, char *name,
797: struct termios *termp, struct winsize *winp)
1.1 root 798: {
799: const char *slave;
800: int mfd = -1, sfd = -1;
801:
802: *amaster = *aslave = -1;
803:
804: mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
805: if (mfd < 0)
806: goto err;
807:
808: if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
809: goto err;
810:
811: if ((slave = ptsname(mfd)) == NULL)
812: goto err;
813:
814: if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
815: goto err;
816:
817: if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
818: (termp != NULL && tcgetattr(sfd, termp) < 0))
819: goto err;
820:
821: if (amaster)
822: *amaster = mfd;
823: if (aslave)
824: *aslave = sfd;
825: if (winp)
826: ioctl(sfd, TIOCSWINSZ, winp);
827:
828: return 0;
829:
830: err:
831: if (sfd != -1)
832: close(sfd);
833: close(mfd);
834: return -1;
835: }
836:
1.1.1.4 root 837: static void cfmakeraw (struct termios *termios_p)
1.1 root 838: {
839: termios_p->c_iflag &=
840: ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
841: termios_p->c_oflag &= ~OPOST;
842: termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
843: termios_p->c_cflag &= ~(CSIZE|PARENB);
844: termios_p->c_cflag |= CS8;
845:
846: termios_p->c_cc[VMIN] = 0;
847: termios_p->c_cc[VTIME] = 0;
848: }
849: #endif
850:
851: #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
1.1.1.5 root 852: || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
853: || defined(__GLIBC__)
1.1 root 854:
855: typedef struct {
856: int fd;
857: int connected;
858: int polling;
859: int read_bytes;
860: QEMUTimer *timer;
861: } PtyCharDriver;
862:
863: static void pty_chr_update_read_handler(CharDriverState *chr);
864: static void pty_chr_state(CharDriverState *chr, int connected);
865:
866: static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
867: {
868: PtyCharDriver *s = chr->opaque;
869:
870: if (!s->connected) {
871: /* guest sends data, check for (re-)connect */
872: pty_chr_update_read_handler(chr);
873: return 0;
874: }
875: return send_all(s->fd, buf, len);
876: }
877:
878: static int pty_chr_read_poll(void *opaque)
879: {
880: CharDriverState *chr = opaque;
881: PtyCharDriver *s = chr->opaque;
882:
1.1.1.12 root 883: s->read_bytes = qemu_chr_be_can_write(chr);
1.1 root 884: return s->read_bytes;
885: }
886:
887: static void pty_chr_read(void *opaque)
888: {
889: CharDriverState *chr = opaque;
890: PtyCharDriver *s = chr->opaque;
891: int size, len;
1.1.1.5 root 892: uint8_t buf[READ_BUF_LEN];
1.1 root 893:
894: len = sizeof(buf);
895: if (len > s->read_bytes)
896: len = s->read_bytes;
897: if (len == 0)
898: return;
899: size = read(s->fd, buf, len);
900: if ((size == -1 && errno == EIO) ||
901: (size == 0)) {
902: pty_chr_state(chr, 0);
903: return;
904: }
905: if (size > 0) {
906: pty_chr_state(chr, 1);
1.1.1.12 root 907: qemu_chr_be_write(chr, buf, size);
1.1 root 908: }
909: }
910:
911: static void pty_chr_update_read_handler(CharDriverState *chr)
912: {
913: PtyCharDriver *s = chr->opaque;
914:
915: qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
916: pty_chr_read, NULL, chr);
917: s->polling = 1;
918: /*
919: * Short timeout here: just need wait long enougth that qemu makes
920: * it through the poll loop once. When reconnected we want a
921: * short timeout so we notice it almost instantly. Otherwise
922: * read() gives us -EIO instantly, making pty_chr_state() reset the
923: * timeout to the normal (much longer) poll interval before the
924: * timer triggers.
925: */
1.1.1.11 root 926: qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 10);
1.1 root 927: }
928:
929: static void pty_chr_state(CharDriverState *chr, int connected)
930: {
931: PtyCharDriver *s = chr->opaque;
932:
933: if (!connected) {
934: qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
935: s->connected = 0;
936: s->polling = 0;
937: /* (re-)connect poll interval for idle guests: once per second.
938: * We check more frequently in case the guests sends data to
939: * the virtual device linked to our pty. */
1.1.1.11 root 940: qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 1000);
1.1 root 941: } else {
942: if (!s->connected)
1.1.1.5 root 943: qemu_chr_generic_open(chr);
1.1 root 944: s->connected = 1;
945: }
946: }
947:
948: static void pty_chr_timer(void *opaque)
949: {
950: struct CharDriverState *chr = opaque;
951: PtyCharDriver *s = chr->opaque;
952:
953: if (s->connected)
954: return;
955: if (s->polling) {
956: /* If we arrive here without polling being cleared due
957: * read returning -EIO, then we are (re-)connected */
958: pty_chr_state(chr, 1);
959: return;
960: }
961:
962: /* Next poll ... */
963: pty_chr_update_read_handler(chr);
964: }
965:
966: static void pty_chr_close(struct CharDriverState *chr)
967: {
968: PtyCharDriver *s = chr->opaque;
969:
970: qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
971: close(s->fd);
1.1.1.3 root 972: qemu_del_timer(s->timer);
973: qemu_free_timer(s->timer);
1.1.1.12 root 974: g_free(s);
975: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 976: }
977:
1.1.1.13! root 978: static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)
1.1 root 979: {
980: CharDriverState *chr;
981: PtyCharDriver *s;
982: struct termios tty;
1.1.1.12 root 983: int master_fd, slave_fd, len;
1.1.1.4 root 984: #if defined(__OpenBSD__) || defined(__DragonFly__)
1.1 root 985: char pty_name[PATH_MAX];
986: #define q_ptsname(x) pty_name
987: #else
988: char *pty_name = NULL;
989: #define q_ptsname(x) ptsname(x)
990: #endif
991:
1.1.1.12 root 992: if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) {
1.1.1.13! root 993: return NULL;
1.1 root 994: }
995:
996: /* Set raw attributes on the pty. */
997: tcgetattr(slave_fd, &tty);
998: cfmakeraw(&tty);
999: tcsetattr(slave_fd, TCSAFLUSH, &tty);
1000: close(slave_fd);
1001:
1.1.1.12 root 1002: chr = g_malloc0(sizeof(CharDriverState));
1003:
1004: len = strlen(q_ptsname(master_fd)) + 5;
1005: chr->filename = g_malloc(len);
1006: snprintf(chr->filename, len, "pty:%s", q_ptsname(master_fd));
1007: qemu_opt_set(opts, "path", q_ptsname(master_fd));
1008: fprintf(stderr, "char device redirected to %s\n", q_ptsname(master_fd));
1.1 root 1009:
1.1.1.12 root 1010: s = g_malloc0(sizeof(PtyCharDriver));
1.1 root 1011: chr->opaque = s;
1012: chr->chr_write = pty_chr_write;
1013: chr->chr_update_read_handler = pty_chr_update_read_handler;
1014: chr->chr_close = pty_chr_close;
1015:
1.1.1.12 root 1016: s->fd = master_fd;
1.1.1.11 root 1017: s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);
1.1 root 1018:
1.1.1.13! root 1019: return chr;
1.1 root 1020: }
1021:
1022: static void tty_serial_init(int fd, int speed,
1023: int parity, int data_bits, int stop_bits)
1024: {
1025: struct termios tty;
1026: speed_t spd;
1027:
1028: #if 0
1029: printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
1030: speed, parity, data_bits, stop_bits);
1031: #endif
1032: tcgetattr (fd, &tty);
1033:
1.1.1.5 root 1034: #define check_speed(val) if (speed <= val) { spd = B##val; break; }
1035: speed = speed * 10 / 11;
1036: do {
1037: check_speed(50);
1038: check_speed(75);
1039: check_speed(110);
1040: check_speed(134);
1041: check_speed(150);
1042: check_speed(200);
1043: check_speed(300);
1044: check_speed(600);
1045: check_speed(1200);
1046: check_speed(1800);
1047: check_speed(2400);
1048: check_speed(4800);
1049: check_speed(9600);
1050: check_speed(19200);
1051: check_speed(38400);
1052: /* Non-Posix values follow. They may be unsupported on some systems. */
1053: check_speed(57600);
1054: check_speed(115200);
1055: #ifdef B230400
1056: check_speed(230400);
1057: #endif
1058: #ifdef B460800
1059: check_speed(460800);
1060: #endif
1061: #ifdef B500000
1062: check_speed(500000);
1063: #endif
1064: #ifdef B576000
1065: check_speed(576000);
1066: #endif
1067: #ifdef B921600
1068: check_speed(921600);
1069: #endif
1070: #ifdef B1000000
1071: check_speed(1000000);
1072: #endif
1073: #ifdef B1152000
1074: check_speed(1152000);
1075: #endif
1076: #ifdef B1500000
1077: check_speed(1500000);
1078: #endif
1079: #ifdef B2000000
1080: check_speed(2000000);
1081: #endif
1082: #ifdef B2500000
1083: check_speed(2500000);
1084: #endif
1085: #ifdef B3000000
1086: check_speed(3000000);
1087: #endif
1088: #ifdef B3500000
1089: check_speed(3500000);
1090: #endif
1091: #ifdef B4000000
1092: check_speed(4000000);
1093: #endif
1.1 root 1094: spd = B115200;
1.1.1.5 root 1095: } while (0);
1.1 root 1096:
1097: cfsetispeed(&tty, spd);
1098: cfsetospeed(&tty, spd);
1099:
1100: tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1101: |INLCR|IGNCR|ICRNL|IXON);
1102: tty.c_oflag |= OPOST;
1103: tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
1104: tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
1105: switch(data_bits) {
1106: default:
1107: case 8:
1108: tty.c_cflag |= CS8;
1109: break;
1110: case 7:
1111: tty.c_cflag |= CS7;
1112: break;
1113: case 6:
1114: tty.c_cflag |= CS6;
1115: break;
1116: case 5:
1117: tty.c_cflag |= CS5;
1118: break;
1119: }
1120: switch(parity) {
1121: default:
1122: case 'N':
1123: break;
1124: case 'E':
1125: tty.c_cflag |= PARENB;
1126: break;
1127: case 'O':
1128: tty.c_cflag |= PARENB | PARODD;
1129: break;
1130: }
1131: if (stop_bits == 2)
1132: tty.c_cflag |= CSTOPB;
1133:
1134: tcsetattr (fd, TCSANOW, &tty);
1135: }
1136:
1137: static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
1138: {
1139: FDCharDriver *s = chr->opaque;
1140:
1141: switch(cmd) {
1142: case CHR_IOCTL_SERIAL_SET_PARAMS:
1143: {
1144: QEMUSerialSetParams *ssp = arg;
1145: tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
1146: ssp->data_bits, ssp->stop_bits);
1147: }
1148: break;
1149: case CHR_IOCTL_SERIAL_SET_BREAK:
1150: {
1151: int enable = *(int *)arg;
1152: if (enable)
1153: tcsendbreak(s->fd_in, 1);
1154: }
1155: break;
1156: case CHR_IOCTL_SERIAL_GET_TIOCM:
1157: {
1158: int sarg = 0;
1159: int *targ = (int *)arg;
1160: ioctl(s->fd_in, TIOCMGET, &sarg);
1161: *targ = 0;
1162: if (sarg & TIOCM_CTS)
1163: *targ |= CHR_TIOCM_CTS;
1164: if (sarg & TIOCM_CAR)
1165: *targ |= CHR_TIOCM_CAR;
1166: if (sarg & TIOCM_DSR)
1167: *targ |= CHR_TIOCM_DSR;
1168: if (sarg & TIOCM_RI)
1169: *targ |= CHR_TIOCM_RI;
1170: if (sarg & TIOCM_DTR)
1171: *targ |= CHR_TIOCM_DTR;
1172: if (sarg & TIOCM_RTS)
1173: *targ |= CHR_TIOCM_RTS;
1174: }
1175: break;
1176: case CHR_IOCTL_SERIAL_SET_TIOCM:
1177: {
1178: int sarg = *(int *)arg;
1179: int targ = 0;
1180: ioctl(s->fd_in, TIOCMGET, &targ);
1181: targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
1182: | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
1183: if (sarg & CHR_TIOCM_CTS)
1184: targ |= TIOCM_CTS;
1185: if (sarg & CHR_TIOCM_CAR)
1186: targ |= TIOCM_CAR;
1187: if (sarg & CHR_TIOCM_DSR)
1188: targ |= TIOCM_DSR;
1189: if (sarg & CHR_TIOCM_RI)
1190: targ |= TIOCM_RI;
1191: if (sarg & CHR_TIOCM_DTR)
1192: targ |= TIOCM_DTR;
1193: if (sarg & CHR_TIOCM_RTS)
1194: targ |= TIOCM_RTS;
1195: ioctl(s->fd_in, TIOCMSET, &targ);
1196: }
1197: break;
1198: default:
1199: return -ENOTSUP;
1200: }
1201: return 0;
1202: }
1203:
1.1.1.8 root 1204: static void qemu_chr_close_tty(CharDriverState *chr)
1205: {
1206: FDCharDriver *s = chr->opaque;
1207: int fd = -1;
1208:
1209: if (s) {
1210: fd = s->fd_in;
1211: }
1212:
1213: fd_chr_close(chr);
1214:
1215: if (fd >= 0) {
1216: close(fd);
1217: }
1218: }
1219:
1.1.1.13! root 1220: static CharDriverState *qemu_chr_open_tty(QemuOpts *opts)
1.1 root 1221: {
1.1.1.5 root 1222: const char *filename = qemu_opt_get(opts, "path");
1.1 root 1223: CharDriverState *chr;
1224: int fd;
1225:
1.1.1.11 root 1226: TFR(fd = qemu_open(filename, O_RDWR | O_NONBLOCK));
1.1.1.6 root 1227: if (fd < 0) {
1.1.1.13! root 1228: return NULL;
1.1.1.6 root 1229: }
1.1 root 1230: tty_serial_init(fd, 115200, 'N', 8, 1);
1231: chr = qemu_chr_open_fd(fd, fd);
1232: chr->chr_ioctl = tty_serial_ioctl;
1.1.1.8 root 1233: chr->chr_close = qemu_chr_close_tty;
1.1.1.13! root 1234: return chr;
1.1 root 1235: }
1236: #else /* ! __linux__ && ! __sun__ */
1.1.1.13! root 1237: static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)
1.1 root 1238: {
1.1.1.13! root 1239: return NULL;
1.1 root 1240: }
1241: #endif /* __linux__ || __sun__ */
1242:
1243: #if defined(__linux__)
1244: typedef struct {
1245: int fd;
1246: int mode;
1247: } ParallelCharDriver;
1248:
1249: static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
1250: {
1251: if (s->mode != mode) {
1252: int m = mode;
1253: if (ioctl(s->fd, PPSETMODE, &m) < 0)
1254: return 0;
1255: s->mode = mode;
1256: }
1257: return 1;
1258: }
1259:
1260: static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1261: {
1262: ParallelCharDriver *drv = chr->opaque;
1263: int fd = drv->fd;
1264: uint8_t b;
1265:
1266: switch(cmd) {
1267: case CHR_IOCTL_PP_READ_DATA:
1268: if (ioctl(fd, PPRDATA, &b) < 0)
1269: return -ENOTSUP;
1270: *(uint8_t *)arg = b;
1271: break;
1272: case CHR_IOCTL_PP_WRITE_DATA:
1273: b = *(uint8_t *)arg;
1274: if (ioctl(fd, PPWDATA, &b) < 0)
1275: return -ENOTSUP;
1276: break;
1277: case CHR_IOCTL_PP_READ_CONTROL:
1278: if (ioctl(fd, PPRCONTROL, &b) < 0)
1279: return -ENOTSUP;
1280: /* Linux gives only the lowest bits, and no way to know data
1281: direction! For better compatibility set the fixed upper
1282: bits. */
1283: *(uint8_t *)arg = b | 0xc0;
1284: break;
1285: case CHR_IOCTL_PP_WRITE_CONTROL:
1286: b = *(uint8_t *)arg;
1287: if (ioctl(fd, PPWCONTROL, &b) < 0)
1288: return -ENOTSUP;
1289: break;
1290: case CHR_IOCTL_PP_READ_STATUS:
1291: if (ioctl(fd, PPRSTATUS, &b) < 0)
1292: return -ENOTSUP;
1293: *(uint8_t *)arg = b;
1294: break;
1295: case CHR_IOCTL_PP_DATA_DIR:
1296: if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
1297: return -ENOTSUP;
1298: break;
1299: case CHR_IOCTL_PP_EPP_READ_ADDR:
1300: if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1301: struct ParallelIOArg *parg = arg;
1302: int n = read(fd, parg->buffer, parg->count);
1303: if (n != parg->count) {
1304: return -EIO;
1305: }
1306: }
1307: break;
1308: case CHR_IOCTL_PP_EPP_READ:
1309: if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1310: struct ParallelIOArg *parg = arg;
1311: int n = read(fd, parg->buffer, parg->count);
1312: if (n != parg->count) {
1313: return -EIO;
1314: }
1315: }
1316: break;
1317: case CHR_IOCTL_PP_EPP_WRITE_ADDR:
1318: if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1319: struct ParallelIOArg *parg = arg;
1320: int n = write(fd, parg->buffer, parg->count);
1321: if (n != parg->count) {
1322: return -EIO;
1323: }
1324: }
1325: break;
1326: case CHR_IOCTL_PP_EPP_WRITE:
1327: if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1328: struct ParallelIOArg *parg = arg;
1329: int n = write(fd, parg->buffer, parg->count);
1330: if (n != parg->count) {
1331: return -EIO;
1332: }
1333: }
1334: break;
1335: default:
1336: return -ENOTSUP;
1337: }
1338: return 0;
1339: }
1340:
1341: static void pp_close(CharDriverState *chr)
1342: {
1343: ParallelCharDriver *drv = chr->opaque;
1344: int fd = drv->fd;
1345:
1346: pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
1347: ioctl(fd, PPRELEASE);
1348: close(fd);
1.1.1.12 root 1349: g_free(drv);
1350: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 1351: }
1352:
1.1.1.13! root 1353: static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
1.1 root 1354: {
1.1.1.5 root 1355: const char *filename = qemu_opt_get(opts, "path");
1.1 root 1356: CharDriverState *chr;
1357: ParallelCharDriver *drv;
1358: int fd;
1359:
1.1.1.13! root 1360: TFR(fd = qemu_open(filename, O_RDWR));
1.1.1.11 root 1361: if (fd < 0) {
1.1.1.13! root 1362: return NULL;
1.1.1.11 root 1363: }
1.1 root 1364:
1365: if (ioctl(fd, PPCLAIM) < 0) {
1366: close(fd);
1.1.1.13! root 1367: return NULL;
1.1 root 1368: }
1369:
1.1.1.12 root 1370: drv = g_malloc0(sizeof(ParallelCharDriver));
1.1 root 1371: drv->fd = fd;
1372: drv->mode = IEEE1284_MODE_COMPAT;
1373:
1.1.1.12 root 1374: chr = g_malloc0(sizeof(CharDriverState));
1.1 root 1375: chr->chr_write = null_chr_write;
1376: chr->chr_ioctl = pp_ioctl;
1377: chr->chr_close = pp_close;
1378: chr->opaque = drv;
1379:
1.1.1.5 root 1380: qemu_chr_generic_open(chr);
1.1 root 1381:
1.1.1.13! root 1382: return chr;
1.1 root 1383: }
1384: #endif /* __linux__ */
1385:
1.1.1.5 root 1386: #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1.1 root 1387: static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1388: {
1.1.1.11 root 1389: int fd = (int)(intptr_t)chr->opaque;
1.1 root 1390: uint8_t b;
1391:
1392: switch(cmd) {
1393: case CHR_IOCTL_PP_READ_DATA:
1394: if (ioctl(fd, PPIGDATA, &b) < 0)
1395: return -ENOTSUP;
1396: *(uint8_t *)arg = b;
1397: break;
1398: case CHR_IOCTL_PP_WRITE_DATA:
1399: b = *(uint8_t *)arg;
1400: if (ioctl(fd, PPISDATA, &b) < 0)
1401: return -ENOTSUP;
1402: break;
1403: case CHR_IOCTL_PP_READ_CONTROL:
1404: if (ioctl(fd, PPIGCTRL, &b) < 0)
1405: return -ENOTSUP;
1406: *(uint8_t *)arg = b;
1407: break;
1408: case CHR_IOCTL_PP_WRITE_CONTROL:
1409: b = *(uint8_t *)arg;
1410: if (ioctl(fd, PPISCTRL, &b) < 0)
1411: return -ENOTSUP;
1412: break;
1413: case CHR_IOCTL_PP_READ_STATUS:
1414: if (ioctl(fd, PPIGSTATUS, &b) < 0)
1415: return -ENOTSUP;
1416: *(uint8_t *)arg = b;
1417: break;
1418: default:
1419: return -ENOTSUP;
1420: }
1421: return 0;
1422: }
1423:
1.1.1.13! root 1424: static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
1.1 root 1425: {
1.1.1.5 root 1426: const char *filename = qemu_opt_get(opts, "path");
1.1 root 1427: CharDriverState *chr;
1428: int fd;
1429:
1.1.1.11 root 1430: fd = qemu_open(filename, O_RDWR);
1431: if (fd < 0) {
1.1.1.13! root 1432: return NULL;
1.1.1.11 root 1433: }
1.1 root 1434:
1.1.1.12 root 1435: chr = g_malloc0(sizeof(CharDriverState));
1.1.1.11 root 1436: chr->opaque = (void *)(intptr_t)fd;
1.1 root 1437: chr->chr_write = null_chr_write;
1438: chr->chr_ioctl = pp_ioctl;
1.1.1.13! root 1439: return chr;
1.1 root 1440: }
1441: #endif
1442:
1443: #else /* _WIN32 */
1444:
1.1.1.12 root 1445: static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
1446:
1.1 root 1447: typedef struct {
1448: int max_size;
1449: HANDLE hcom, hrecv, hsend;
1450: OVERLAPPED orecv, osend;
1451: BOOL fpipe;
1452: DWORD len;
1453: } WinCharState;
1454:
1.1.1.12 root 1455: typedef struct {
1456: HANDLE hStdIn;
1457: HANDLE hInputReadyEvent;
1458: HANDLE hInputDoneEvent;
1459: HANDLE hInputThread;
1460: uint8_t win_stdio_buf;
1461: } WinStdioCharState;
1462:
1.1 root 1463: #define NSENDBUF 2048
1464: #define NRECVBUF 2048
1465: #define MAXCONNECT 1
1466: #define NTIMEOUT 5000
1467:
1468: static int win_chr_poll(void *opaque);
1469: static int win_chr_pipe_poll(void *opaque);
1470:
1471: static void win_chr_close(CharDriverState *chr)
1472: {
1473: WinCharState *s = chr->opaque;
1474:
1475: if (s->hsend) {
1476: CloseHandle(s->hsend);
1477: s->hsend = NULL;
1478: }
1479: if (s->hrecv) {
1480: CloseHandle(s->hrecv);
1481: s->hrecv = NULL;
1482: }
1483: if (s->hcom) {
1484: CloseHandle(s->hcom);
1485: s->hcom = NULL;
1486: }
1487: if (s->fpipe)
1488: qemu_del_polling_cb(win_chr_pipe_poll, chr);
1489: else
1490: qemu_del_polling_cb(win_chr_poll, chr);
1.1.1.5 root 1491:
1.1.1.12 root 1492: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 1493: }
1494:
1495: static int win_chr_init(CharDriverState *chr, const char *filename)
1496: {
1497: WinCharState *s = chr->opaque;
1498: COMMCONFIG comcfg;
1499: COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
1500: COMSTAT comstat;
1501: DWORD size;
1502: DWORD err;
1503:
1504: s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1505: if (!s->hsend) {
1506: fprintf(stderr, "Failed CreateEvent\n");
1507: goto fail;
1508: }
1509: s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1510: if (!s->hrecv) {
1511: fprintf(stderr, "Failed CreateEvent\n");
1512: goto fail;
1513: }
1514:
1515: s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1516: OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
1517: if (s->hcom == INVALID_HANDLE_VALUE) {
1518: fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
1519: s->hcom = NULL;
1520: goto fail;
1521: }
1522:
1523: if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
1524: fprintf(stderr, "Failed SetupComm\n");
1525: goto fail;
1526: }
1527:
1528: ZeroMemory(&comcfg, sizeof(COMMCONFIG));
1529: size = sizeof(COMMCONFIG);
1530: GetDefaultCommConfig(filename, &comcfg, &size);
1531: comcfg.dcb.DCBlength = sizeof(DCB);
1532: CommConfigDialog(filename, NULL, &comcfg);
1533:
1534: if (!SetCommState(s->hcom, &comcfg.dcb)) {
1535: fprintf(stderr, "Failed SetCommState\n");
1536: goto fail;
1537: }
1538:
1539: if (!SetCommMask(s->hcom, EV_ERR)) {
1540: fprintf(stderr, "Failed SetCommMask\n");
1541: goto fail;
1542: }
1543:
1544: cto.ReadIntervalTimeout = MAXDWORD;
1545: if (!SetCommTimeouts(s->hcom, &cto)) {
1546: fprintf(stderr, "Failed SetCommTimeouts\n");
1547: goto fail;
1548: }
1549:
1550: if (!ClearCommError(s->hcom, &err, &comstat)) {
1551: fprintf(stderr, "Failed ClearCommError\n");
1552: goto fail;
1553: }
1554: qemu_add_polling_cb(win_chr_poll, chr);
1555: return 0;
1556:
1557: fail:
1558: win_chr_close(chr);
1559: return -1;
1560: }
1561:
1562: static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
1563: {
1564: WinCharState *s = chr->opaque;
1565: DWORD len, ret, size, err;
1566:
1567: len = len1;
1568: ZeroMemory(&s->osend, sizeof(s->osend));
1569: s->osend.hEvent = s->hsend;
1570: while (len > 0) {
1571: if (s->hsend)
1572: ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
1573: else
1574: ret = WriteFile(s->hcom, buf, len, &size, NULL);
1575: if (!ret) {
1576: err = GetLastError();
1577: if (err == ERROR_IO_PENDING) {
1578: ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
1579: if (ret) {
1580: buf += size;
1581: len -= size;
1582: } else {
1583: break;
1584: }
1585: } else {
1586: break;
1587: }
1588: } else {
1589: buf += size;
1590: len -= size;
1591: }
1592: }
1593: return len1 - len;
1594: }
1595:
1596: static int win_chr_read_poll(CharDriverState *chr)
1597: {
1598: WinCharState *s = chr->opaque;
1599:
1.1.1.12 root 1600: s->max_size = qemu_chr_be_can_write(chr);
1.1 root 1601: return s->max_size;
1602: }
1603:
1604: static void win_chr_readfile(CharDriverState *chr)
1605: {
1606: WinCharState *s = chr->opaque;
1607: int ret, err;
1.1.1.5 root 1608: uint8_t buf[READ_BUF_LEN];
1.1 root 1609: DWORD size;
1610:
1611: ZeroMemory(&s->orecv, sizeof(s->orecv));
1612: s->orecv.hEvent = s->hrecv;
1613: ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
1614: if (!ret) {
1615: err = GetLastError();
1616: if (err == ERROR_IO_PENDING) {
1617: ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
1618: }
1619: }
1620:
1621: if (size > 0) {
1.1.1.12 root 1622: qemu_chr_be_write(chr, buf, size);
1.1 root 1623: }
1624: }
1625:
1626: static void win_chr_read(CharDriverState *chr)
1627: {
1628: WinCharState *s = chr->opaque;
1629:
1630: if (s->len > s->max_size)
1631: s->len = s->max_size;
1632: if (s->len == 0)
1633: return;
1634:
1635: win_chr_readfile(chr);
1636: }
1637:
1638: static int win_chr_poll(void *opaque)
1639: {
1640: CharDriverState *chr = opaque;
1641: WinCharState *s = chr->opaque;
1642: COMSTAT status;
1643: DWORD comerr;
1644:
1645: ClearCommError(s->hcom, &comerr, &status);
1646: if (status.cbInQue > 0) {
1647: s->len = status.cbInQue;
1648: win_chr_read_poll(chr);
1649: win_chr_read(chr);
1650: return 1;
1651: }
1652: return 0;
1653: }
1654:
1.1.1.13! root 1655: static CharDriverState *qemu_chr_open_win(QemuOpts *opts)
1.1 root 1656: {
1.1.1.5 root 1657: const char *filename = qemu_opt_get(opts, "path");
1.1 root 1658: CharDriverState *chr;
1659: WinCharState *s;
1660:
1.1.1.12 root 1661: chr = g_malloc0(sizeof(CharDriverState));
1662: s = g_malloc0(sizeof(WinCharState));
1.1 root 1663: chr->opaque = s;
1664: chr->chr_write = win_chr_write;
1665: chr->chr_close = win_chr_close;
1666:
1667: if (win_chr_init(chr, filename) < 0) {
1.1.1.12 root 1668: g_free(s);
1669: g_free(chr);
1.1.1.13! root 1670: return NULL;
1.1 root 1671: }
1.1.1.5 root 1672: qemu_chr_generic_open(chr);
1.1.1.13! root 1673: return chr;
1.1 root 1674: }
1675:
1676: static int win_chr_pipe_poll(void *opaque)
1677: {
1678: CharDriverState *chr = opaque;
1679: WinCharState *s = chr->opaque;
1680: DWORD size;
1681:
1682: PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
1683: if (size > 0) {
1684: s->len = size;
1685: win_chr_read_poll(chr);
1686: win_chr_read(chr);
1687: return 1;
1688: }
1689: return 0;
1690: }
1691:
1692: static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
1693: {
1694: WinCharState *s = chr->opaque;
1695: OVERLAPPED ov;
1696: int ret;
1697: DWORD size;
1698: char openname[256];
1699:
1700: s->fpipe = TRUE;
1701:
1702: s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1703: if (!s->hsend) {
1704: fprintf(stderr, "Failed CreateEvent\n");
1705: goto fail;
1706: }
1707: s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1708: if (!s->hrecv) {
1709: fprintf(stderr, "Failed CreateEvent\n");
1710: goto fail;
1711: }
1712:
1713: snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
1714: s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1715: PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
1716: PIPE_WAIT,
1717: MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
1718: if (s->hcom == INVALID_HANDLE_VALUE) {
1719: fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
1720: s->hcom = NULL;
1721: goto fail;
1722: }
1723:
1724: ZeroMemory(&ov, sizeof(ov));
1725: ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1726: ret = ConnectNamedPipe(s->hcom, &ov);
1727: if (ret) {
1728: fprintf(stderr, "Failed ConnectNamedPipe\n");
1729: goto fail;
1730: }
1731:
1732: ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
1733: if (!ret) {
1734: fprintf(stderr, "Failed GetOverlappedResult\n");
1735: if (ov.hEvent) {
1736: CloseHandle(ov.hEvent);
1737: ov.hEvent = NULL;
1738: }
1739: goto fail;
1740: }
1741:
1742: if (ov.hEvent) {
1743: CloseHandle(ov.hEvent);
1744: ov.hEvent = NULL;
1745: }
1746: qemu_add_polling_cb(win_chr_pipe_poll, chr);
1747: return 0;
1748:
1749: fail:
1750: win_chr_close(chr);
1751: return -1;
1752: }
1753:
1754:
1.1.1.13! root 1755: static CharDriverState *qemu_chr_open_win_pipe(QemuOpts *opts)
1.1 root 1756: {
1.1.1.5 root 1757: const char *filename = qemu_opt_get(opts, "path");
1.1 root 1758: CharDriverState *chr;
1759: WinCharState *s;
1760:
1.1.1.12 root 1761: chr = g_malloc0(sizeof(CharDriverState));
1762: s = g_malloc0(sizeof(WinCharState));
1.1 root 1763: chr->opaque = s;
1764: chr->chr_write = win_chr_write;
1765: chr->chr_close = win_chr_close;
1766:
1767: if (win_chr_pipe_init(chr, filename) < 0) {
1.1.1.12 root 1768: g_free(s);
1769: g_free(chr);
1.1.1.13! root 1770: return NULL;
1.1 root 1771: }
1.1.1.5 root 1772: qemu_chr_generic_open(chr);
1.1.1.13! root 1773: return chr;
1.1 root 1774: }
1775:
1.1.1.13! root 1776: static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
1.1 root 1777: {
1778: CharDriverState *chr;
1779: WinCharState *s;
1780:
1.1.1.12 root 1781: chr = g_malloc0(sizeof(CharDriverState));
1782: s = g_malloc0(sizeof(WinCharState));
1.1 root 1783: s->hcom = fd_out;
1784: chr->opaque = s;
1785: chr->chr_write = win_chr_write;
1.1.1.5 root 1786: qemu_chr_generic_open(chr);
1.1.1.13! root 1787: return chr;
1.1 root 1788: }
1789:
1.1.1.13! root 1790: static CharDriverState *qemu_chr_open_win_con(QemuOpts *opts)
1.1 root 1791: {
1.1.1.13! root 1792: return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
1.1 root 1793: }
1794:
1.1.1.13! root 1795: static CharDriverState *qemu_chr_open_win_file_out(QemuOpts *opts)
1.1 root 1796: {
1.1.1.5 root 1797: const char *file_out = qemu_opt_get(opts, "path");
1.1 root 1798: HANDLE fd_out;
1799:
1800: fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
1801: OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1.1.1.11 root 1802: if (fd_out == INVALID_HANDLE_VALUE) {
1.1.1.13! root 1803: return NULL;
1.1.1.11 root 1804: }
1.1 root 1805:
1.1.1.13! root 1806: return qemu_chr_open_win_file(fd_out);
1.1 root 1807: }
1.1.1.12 root 1808:
1809: static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
1810: {
1811: HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
1812: DWORD dwSize;
1813: int len1;
1814:
1815: len1 = len;
1816:
1817: while (len1 > 0) {
1818: if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
1819: break;
1820: }
1821: buf += dwSize;
1822: len1 -= dwSize;
1823: }
1824:
1825: return len - len1;
1826: }
1827:
1828: static void win_stdio_wait_func(void *opaque)
1829: {
1830: CharDriverState *chr = opaque;
1831: WinStdioCharState *stdio = chr->opaque;
1832: INPUT_RECORD buf[4];
1833: int ret;
1834: DWORD dwSize;
1835: int i;
1836:
1837: ret = ReadConsoleInput(stdio->hStdIn, buf, sizeof(buf) / sizeof(*buf),
1838: &dwSize);
1839:
1840: if (!ret) {
1841: /* Avoid error storm */
1842: qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
1843: return;
1844: }
1845:
1846: for (i = 0; i < dwSize; i++) {
1847: KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;
1848:
1849: if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
1850: int j;
1851: if (kev->uChar.AsciiChar != 0) {
1852: for (j = 0; j < kev->wRepeatCount; j++) {
1853: if (qemu_chr_be_can_write(chr)) {
1854: uint8_t c = kev->uChar.AsciiChar;
1855: qemu_chr_be_write(chr, &c, 1);
1856: }
1857: }
1858: }
1859: }
1860: }
1861: }
1862:
1863: static DWORD WINAPI win_stdio_thread(LPVOID param)
1864: {
1865: CharDriverState *chr = param;
1866: WinStdioCharState *stdio = chr->opaque;
1867: int ret;
1868: DWORD dwSize;
1869:
1870: while (1) {
1871:
1872: /* Wait for one byte */
1873: ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);
1874:
1875: /* Exit in case of error, continue if nothing read */
1876: if (!ret) {
1877: break;
1878: }
1879: if (!dwSize) {
1880: continue;
1881: }
1882:
1883: /* Some terminal emulator returns \r\n for Enter, just pass \n */
1884: if (stdio->win_stdio_buf == '\r') {
1885: continue;
1886: }
1887:
1888: /* Signal the main thread and wait until the byte was eaten */
1889: if (!SetEvent(stdio->hInputReadyEvent)) {
1890: break;
1891: }
1892: if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
1893: != WAIT_OBJECT_0) {
1894: break;
1895: }
1896: }
1897:
1898: qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
1899: return 0;
1900: }
1901:
1902: static void win_stdio_thread_wait_func(void *opaque)
1903: {
1904: CharDriverState *chr = opaque;
1905: WinStdioCharState *stdio = chr->opaque;
1906:
1907: if (qemu_chr_be_can_write(chr)) {
1908: qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
1909: }
1910:
1911: SetEvent(stdio->hInputDoneEvent);
1912: }
1913:
1914: static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo)
1915: {
1916: WinStdioCharState *stdio = chr->opaque;
1917: DWORD dwMode = 0;
1918:
1919: GetConsoleMode(stdio->hStdIn, &dwMode);
1920:
1921: if (echo) {
1922: SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
1923: } else {
1924: SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
1925: }
1926: }
1927:
1928: static void win_stdio_close(CharDriverState *chr)
1929: {
1930: WinStdioCharState *stdio = chr->opaque;
1931:
1932: if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
1933: CloseHandle(stdio->hInputReadyEvent);
1934: }
1935: if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
1936: CloseHandle(stdio->hInputDoneEvent);
1937: }
1938: if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
1939: TerminateThread(stdio->hInputThread, 0);
1940: }
1941:
1942: g_free(chr->opaque);
1943: g_free(chr);
1944: stdio_nb_clients--;
1945: }
1946:
1.1.1.13! root 1947: static CharDriverState *qemu_chr_open_win_stdio(QemuOpts *opts)
1.1.1.12 root 1948: {
1949: CharDriverState *chr;
1950: WinStdioCharState *stdio;
1951: DWORD dwMode;
1952: int is_console = 0;
1953:
1954: if (stdio_nb_clients >= STDIO_MAX_CLIENTS
1955: || ((display_type != DT_NOGRAPHIC) && (stdio_nb_clients != 0))) {
1.1.1.13! root 1956: return NULL;
1.1.1.12 root 1957: }
1958:
1959: chr = g_malloc0(sizeof(CharDriverState));
1960: stdio = g_malloc0(sizeof(WinStdioCharState));
1961:
1962: stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
1963: if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
1964: fprintf(stderr, "cannot open stdio: invalid handle\n");
1965: exit(1);
1966: }
1967:
1968: is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
1969:
1970: chr->opaque = stdio;
1971: chr->chr_write = win_stdio_write;
1972: chr->chr_close = win_stdio_close;
1973:
1974: if (stdio_nb_clients == 0) {
1975: if (is_console) {
1976: if (qemu_add_wait_object(stdio->hStdIn,
1977: win_stdio_wait_func, chr)) {
1978: fprintf(stderr, "qemu_add_wait_object: failed\n");
1979: }
1980: } else {
1981: DWORD dwId;
1982:
1983: stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1984: stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1985: stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread,
1986: chr, 0, &dwId);
1987:
1988: if (stdio->hInputThread == INVALID_HANDLE_VALUE
1989: || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
1990: || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
1991: fprintf(stderr, "cannot create stdio thread or event\n");
1992: exit(1);
1993: }
1994: if (qemu_add_wait_object(stdio->hInputReadyEvent,
1995: win_stdio_thread_wait_func, chr)) {
1996: fprintf(stderr, "qemu_add_wait_object: failed\n");
1997: }
1998: }
1999: }
2000:
2001: dwMode |= ENABLE_LINE_INPUT;
2002:
2003: stdio_clients[stdio_nb_clients++] = chr;
2004: if (stdio_nb_clients == 1 && is_console) {
2005: /* set the terminal in raw mode */
2006: /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
2007: dwMode |= ENABLE_PROCESSED_INPUT;
2008: }
2009:
2010: SetConsoleMode(stdio->hStdIn, dwMode);
2011:
2012: chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
2013: qemu_chr_fe_set_echo(chr, false);
2014:
1.1.1.13! root 2015: return chr;
1.1.1.12 root 2016: }
1.1 root 2017: #endif /* !_WIN32 */
2018:
2019: /***********************************************************/
2020: /* UDP Net console */
2021:
2022: typedef struct {
2023: int fd;
1.1.1.5 root 2024: uint8_t buf[READ_BUF_LEN];
1.1 root 2025: int bufcnt;
2026: int bufptr;
2027: int max_size;
2028: } NetCharDriver;
2029:
2030: static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2031: {
2032: NetCharDriver *s = chr->opaque;
2033:
1.1.1.5 root 2034: return send(s->fd, (const void *)buf, len, 0);
1.1 root 2035: }
2036:
2037: static int udp_chr_read_poll(void *opaque)
2038: {
2039: CharDriverState *chr = opaque;
2040: NetCharDriver *s = chr->opaque;
2041:
1.1.1.12 root 2042: s->max_size = qemu_chr_be_can_write(chr);
1.1 root 2043:
2044: /* If there were any stray characters in the queue process them
2045: * first
2046: */
2047: while (s->max_size > 0 && s->bufptr < s->bufcnt) {
1.1.1.12 root 2048: qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
1.1 root 2049: s->bufptr++;
1.1.1.12 root 2050: s->max_size = qemu_chr_be_can_write(chr);
1.1 root 2051: }
2052: return s->max_size;
2053: }
2054:
2055: static void udp_chr_read(void *opaque)
2056: {
2057: CharDriverState *chr = opaque;
2058: NetCharDriver *s = chr->opaque;
2059:
2060: if (s->max_size == 0)
2061: return;
1.1.1.11 root 2062: s->bufcnt = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
1.1 root 2063: s->bufptr = s->bufcnt;
2064: if (s->bufcnt <= 0)
2065: return;
2066:
2067: s->bufptr = 0;
2068: while (s->max_size > 0 && s->bufptr < s->bufcnt) {
1.1.1.12 root 2069: qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
1.1 root 2070: s->bufptr++;
1.1.1.12 root 2071: s->max_size = qemu_chr_be_can_write(chr);
1.1 root 2072: }
2073: }
2074:
2075: static void udp_chr_update_read_handler(CharDriverState *chr)
2076: {
2077: NetCharDriver *s = chr->opaque;
2078:
2079: if (s->fd >= 0) {
2080: qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
2081: udp_chr_read, NULL, chr);
2082: }
2083: }
2084:
1.1.1.3 root 2085: static void udp_chr_close(CharDriverState *chr)
2086: {
2087: NetCharDriver *s = chr->opaque;
2088: if (s->fd >= 0) {
1.1.1.12 root 2089: qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
1.1.1.3 root 2090: closesocket(s->fd);
2091: }
1.1.1.12 root 2092: g_free(s);
2093: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1.1.3 root 2094: }
2095:
1.1.1.13! root 2096: static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
1.1 root 2097: {
2098: CharDriverState *chr = NULL;
2099: NetCharDriver *s = NULL;
2100: int fd = -1;
2101:
1.1.1.12 root 2102: chr = g_malloc0(sizeof(CharDriverState));
2103: s = g_malloc0(sizeof(NetCharDriver));
1.1 root 2104:
1.1.1.5 root 2105: fd = inet_dgram_opts(opts);
1.1 root 2106: if (fd < 0) {
1.1.1.5 root 2107: fprintf(stderr, "inet_dgram_opts failed\n");
1.1 root 2108: goto return_err;
2109: }
2110:
2111: s->fd = fd;
2112: s->bufcnt = 0;
2113: s->bufptr = 0;
2114: chr->opaque = s;
2115: chr->chr_write = udp_chr_write;
2116: chr->chr_update_read_handler = udp_chr_update_read_handler;
1.1.1.3 root 2117: chr->chr_close = udp_chr_close;
1.1.1.13! root 2118: return chr;
1.1 root 2119:
2120: return_err:
1.1.1.12 root 2121: g_free(chr);
2122: g_free(s);
1.1.1.11 root 2123: if (fd >= 0) {
1.1 root 2124: closesocket(fd);
1.1.1.11 root 2125: }
1.1.1.13! root 2126: return NULL;
1.1 root 2127: }
2128:
2129: /***********************************************************/
2130: /* TCP Net console */
2131:
2132: typedef struct {
2133: int fd, listen_fd;
2134: int connected;
2135: int max_size;
2136: int do_telnetopt;
2137: int do_nodelay;
2138: int is_unix;
1.1.1.4 root 2139: int msgfd;
1.1 root 2140: } TCPCharDriver;
2141:
2142: static void tcp_chr_accept(void *opaque);
2143:
2144: static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2145: {
2146: TCPCharDriver *s = chr->opaque;
2147: if (s->connected) {
2148: return send_all(s->fd, buf, len);
2149: } else {
2150: /* XXX: indicate an error ? */
2151: return len;
2152: }
2153: }
2154:
2155: static int tcp_chr_read_poll(void *opaque)
2156: {
2157: CharDriverState *chr = opaque;
2158: TCPCharDriver *s = chr->opaque;
2159: if (!s->connected)
2160: return 0;
1.1.1.12 root 2161: s->max_size = qemu_chr_be_can_write(chr);
1.1 root 2162: return s->max_size;
2163: }
2164:
2165: #define IAC 255
2166: #define IAC_BREAK 243
2167: static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
2168: TCPCharDriver *s,
2169: uint8_t *buf, int *size)
2170: {
2171: /* Handle any telnet client's basic IAC options to satisfy char by
2172: * char mode with no echo. All IAC options will be removed from
2173: * the buf and the do_telnetopt variable will be used to track the
2174: * state of the width of the IAC information.
2175: *
2176: * IAC commands come in sets of 3 bytes with the exception of the
2177: * "IAC BREAK" command and the double IAC.
2178: */
2179:
2180: int i;
2181: int j = 0;
2182:
2183: for (i = 0; i < *size; i++) {
2184: if (s->do_telnetopt > 1) {
2185: if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
2186: /* Double IAC means send an IAC */
2187: if (j != i)
2188: buf[j] = buf[i];
2189: j++;
2190: s->do_telnetopt = 1;
2191: } else {
2192: if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
2193: /* Handle IAC break commands by sending a serial break */
1.1.1.12 root 2194: qemu_chr_be_event(chr, CHR_EVENT_BREAK);
1.1 root 2195: s->do_telnetopt++;
2196: }
2197: s->do_telnetopt++;
2198: }
2199: if (s->do_telnetopt >= 4) {
2200: s->do_telnetopt = 1;
2201: }
2202: } else {
2203: if ((unsigned char)buf[i] == IAC) {
2204: s->do_telnetopt = 2;
2205: } else {
2206: if (j != i)
2207: buf[j] = buf[i];
2208: j++;
2209: }
2210: }
2211: }
2212: *size = j;
2213: }
2214:
1.1.1.4 root 2215: static int tcp_get_msgfd(CharDriverState *chr)
2216: {
2217: TCPCharDriver *s = chr->opaque;
1.1.1.8 root 2218: int fd = s->msgfd;
2219: s->msgfd = -1;
2220: return fd;
1.1.1.4 root 2221: }
2222:
1.1.1.5 root 2223: #ifndef _WIN32
1.1.1.4 root 2224: static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
2225: {
2226: TCPCharDriver *s = chr->opaque;
2227: struct cmsghdr *cmsg;
2228:
2229: for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
2230: int fd;
2231:
2232: if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
2233: cmsg->cmsg_level != SOL_SOCKET ||
2234: cmsg->cmsg_type != SCM_RIGHTS)
2235: continue;
2236:
2237: fd = *((int *)CMSG_DATA(cmsg));
2238: if (fd < 0)
2239: continue;
2240:
2241: if (s->msgfd != -1)
2242: close(s->msgfd);
2243: s->msgfd = fd;
2244: }
2245: }
2246:
2247: static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2248: {
2249: TCPCharDriver *s = chr->opaque;
2250: struct msghdr msg = { NULL, };
2251: struct iovec iov[1];
2252: union {
2253: struct cmsghdr cmsg;
2254: char control[CMSG_SPACE(sizeof(int))];
2255: } msg_control;
2256: ssize_t ret;
2257:
2258: iov[0].iov_base = buf;
2259: iov[0].iov_len = len;
2260:
2261: msg.msg_iov = iov;
2262: msg.msg_iovlen = 1;
2263: msg.msg_control = &msg_control;
2264: msg.msg_controllen = sizeof(msg_control);
2265:
2266: ret = recvmsg(s->fd, &msg, 0);
2267: if (ret > 0 && s->is_unix)
2268: unix_process_msgfd(chr, &msg);
2269:
2270: return ret;
2271: }
2272: #else
2273: static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2274: {
2275: TCPCharDriver *s = chr->opaque;
1.1.1.11 root 2276: return qemu_recv(s->fd, buf, len, 0);
1.1.1.4 root 2277: }
2278: #endif
2279:
1.1 root 2280: static void tcp_chr_read(void *opaque)
2281: {
2282: CharDriverState *chr = opaque;
2283: TCPCharDriver *s = chr->opaque;
1.1.1.5 root 2284: uint8_t buf[READ_BUF_LEN];
1.1 root 2285: int len, size;
2286:
2287: if (!s->connected || s->max_size <= 0)
2288: return;
2289: len = sizeof(buf);
2290: if (len > s->max_size)
2291: len = s->max_size;
1.1.1.4 root 2292: size = tcp_chr_recv(chr, (void *)buf, len);
1.1 root 2293: if (size == 0) {
2294: /* connection closed */
2295: s->connected = 0;
2296: if (s->listen_fd >= 0) {
1.1.1.12 root 2297: qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
1.1 root 2298: }
1.1.1.12 root 2299: qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
1.1 root 2300: closesocket(s->fd);
2301: s->fd = -1;
1.1.1.12 root 2302: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 2303: } else if (size > 0) {
2304: if (s->do_telnetopt)
2305: tcp_chr_process_IAC_bytes(chr, s, buf, &size);
2306: if (size > 0)
1.1.1.12 root 2307: qemu_chr_be_write(chr, buf, size);
1.1 root 2308: }
2309: }
2310:
1.1.1.9 root 2311: #ifndef _WIN32
2312: CharDriverState *qemu_chr_open_eventfd(int eventfd)
2313: {
1.1.1.8 root 2314: return qemu_chr_open_fd(eventfd, eventfd);
2315: }
1.1.1.9 root 2316: #endif
1.1.1.8 root 2317:
1.1 root 2318: static void tcp_chr_connect(void *opaque)
2319: {
2320: CharDriverState *chr = opaque;
2321: TCPCharDriver *s = chr->opaque;
2322:
2323: s->connected = 1;
2324: qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
2325: tcp_chr_read, NULL, chr);
1.1.1.5 root 2326: qemu_chr_generic_open(chr);
1.1 root 2327: }
2328:
2329: #define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
2330: static void tcp_chr_telnet_init(int fd)
2331: {
2332: char buf[3];
2333: /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
2334: IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
2335: send(fd, (char *)buf, 3, 0);
2336: IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
2337: send(fd, (char *)buf, 3, 0);
2338: IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
2339: send(fd, (char *)buf, 3, 0);
2340: IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
2341: send(fd, (char *)buf, 3, 0);
2342: }
2343:
2344: static void socket_set_nodelay(int fd)
2345: {
2346: int val = 1;
2347: setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
2348: }
2349:
1.1.1.11 root 2350: static int tcp_chr_add_client(CharDriverState *chr, int fd)
2351: {
2352: TCPCharDriver *s = chr->opaque;
2353: if (s->fd != -1)
2354: return -1;
2355:
2356: socket_set_nonblock(fd);
2357: if (s->do_nodelay)
2358: socket_set_nodelay(fd);
2359: s->fd = fd;
1.1.1.12 root 2360: qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL);
1.1.1.11 root 2361: tcp_chr_connect(chr);
2362:
2363: return 0;
2364: }
2365:
1.1 root 2366: static void tcp_chr_accept(void *opaque)
2367: {
2368: CharDriverState *chr = opaque;
2369: TCPCharDriver *s = chr->opaque;
2370: struct sockaddr_in saddr;
2371: #ifndef _WIN32
2372: struct sockaddr_un uaddr;
2373: #endif
2374: struct sockaddr *addr;
2375: socklen_t len;
2376: int fd;
2377:
2378: for(;;) {
2379: #ifndef _WIN32
2380: if (s->is_unix) {
2381: len = sizeof(uaddr);
2382: addr = (struct sockaddr *)&uaddr;
2383: } else
2384: #endif
2385: {
2386: len = sizeof(saddr);
2387: addr = (struct sockaddr *)&saddr;
2388: }
1.1.1.5 root 2389: fd = qemu_accept(s->listen_fd, addr, &len);
1.1 root 2390: if (fd < 0 && errno != EINTR) {
2391: return;
2392: } else if (fd >= 0) {
2393: if (s->do_telnetopt)
2394: tcp_chr_telnet_init(fd);
2395: break;
2396: }
2397: }
1.1.1.11 root 2398: if (tcp_chr_add_client(chr, fd) < 0)
2399: close(fd);
1.1 root 2400: }
2401:
2402: static void tcp_chr_close(CharDriverState *chr)
2403: {
2404: TCPCharDriver *s = chr->opaque;
1.1.1.3 root 2405: if (s->fd >= 0) {
1.1.1.12 root 2406: qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
1.1 root 2407: closesocket(s->fd);
1.1.1.3 root 2408: }
2409: if (s->listen_fd >= 0) {
1.1.1.12 root 2410: qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL);
1.1 root 2411: closesocket(s->listen_fd);
1.1.1.3 root 2412: }
1.1.1.12 root 2413: g_free(s);
2414: qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1.1 root 2415: }
2416:
1.1.1.13! root 2417: static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
1.1 root 2418: {
2419: CharDriverState *chr = NULL;
2420: TCPCharDriver *s = NULL;
1.1.1.5 root 2421: int fd = -1;
2422: int is_listen;
2423: int is_waitconnect;
2424: int do_nodelay;
2425: int is_unix;
2426: int is_telnet;
2427:
2428: is_listen = qemu_opt_get_bool(opts, "server", 0);
2429: is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);
2430: is_telnet = qemu_opt_get_bool(opts, "telnet", 0);
2431: do_nodelay = !qemu_opt_get_bool(opts, "delay", 1);
2432: is_unix = qemu_opt_get(opts, "path") != NULL;
1.1 root 2433: if (!is_listen)
2434: is_waitconnect = 0;
2435:
1.1.1.12 root 2436: chr = g_malloc0(sizeof(CharDriverState));
2437: s = g_malloc0(sizeof(TCPCharDriver));
1.1 root 2438:
2439: if (is_unix) {
2440: if (is_listen) {
1.1.1.5 root 2441: fd = unix_listen_opts(opts);
1.1 root 2442: } else {
1.1.1.5 root 2443: fd = unix_connect_opts(opts);
1.1 root 2444: }
2445: } else {
2446: if (is_listen) {
1.1.1.13! root 2447: fd = inet_listen_opts(opts, 0, NULL);
1.1 root 2448: } else {
1.1.1.13! root 2449: fd = inet_connect_opts(opts, NULL);
1.1 root 2450: }
2451: }
1.1.1.11 root 2452: if (fd < 0) {
1.1 root 2453: goto fail;
1.1.1.11 root 2454: }
1.1 root 2455:
2456: if (!is_waitconnect)
2457: socket_set_nonblock(fd);
2458:
2459: s->connected = 0;
2460: s->fd = -1;
2461: s->listen_fd = -1;
1.1.1.4 root 2462: s->msgfd = -1;
1.1 root 2463: s->is_unix = is_unix;
2464: s->do_nodelay = do_nodelay && !is_unix;
2465:
2466: chr->opaque = s;
2467: chr->chr_write = tcp_chr_write;
2468: chr->chr_close = tcp_chr_close;
1.1.1.4 root 2469: chr->get_msgfd = tcp_get_msgfd;
1.1.1.11 root 2470: chr->chr_add_client = tcp_chr_add_client;
1.1 root 2471:
2472: if (is_listen) {
2473: s->listen_fd = fd;
1.1.1.12 root 2474: qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
1.1 root 2475: if (is_telnet)
2476: s->do_telnetopt = 1;
1.1.1.5 root 2477:
1.1 root 2478: } else {
2479: s->connected = 1;
2480: s->fd = fd;
2481: socket_set_nodelay(fd);
2482: tcp_chr_connect(chr);
2483: }
2484:
1.1.1.5 root 2485: /* for "info chardev" monitor command */
1.1.1.12 root 2486: chr->filename = g_malloc(256);
1.1.1.5 root 2487: if (is_unix) {
2488: snprintf(chr->filename, 256, "unix:%s%s",
2489: qemu_opt_get(opts, "path"),
2490: qemu_opt_get_bool(opts, "server", 0) ? ",server" : "");
2491: } else if (is_telnet) {
2492: snprintf(chr->filename, 256, "telnet:%s:%s%s",
2493: qemu_opt_get(opts, "host"), qemu_opt_get(opts, "port"),
2494: qemu_opt_get_bool(opts, "server", 0) ? ",server" : "");
2495: } else {
2496: snprintf(chr->filename, 256, "tcp:%s:%s%s",
2497: qemu_opt_get(opts, "host"), qemu_opt_get(opts, "port"),
2498: qemu_opt_get_bool(opts, "server", 0) ? ",server" : "");
2499: }
2500:
1.1 root 2501: if (is_listen && is_waitconnect) {
2502: printf("QEMU waiting for connection on: %s\n",
1.1.1.5 root 2503: chr->filename);
1.1 root 2504: tcp_chr_accept(chr);
2505: socket_set_nonblock(s->listen_fd);
2506: }
1.1.1.13! root 2507: return chr;
1.1.1.5 root 2508:
1.1 root 2509: fail:
2510: if (fd >= 0)
2511: closesocket(fd);
1.1.1.12 root 2512: g_free(s);
2513: g_free(chr);
1.1.1.13! root 2514: return NULL;
1.1 root 2515: }
2516:
1.1.1.9 root 2517: /***********************************************************/
2518: /* Memory chardev */
2519: typedef struct {
2520: size_t outbuf_size;
2521: size_t outbuf_capacity;
2522: uint8_t *outbuf;
2523: } MemoryDriver;
2524:
2525: static int mem_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2526: {
2527: MemoryDriver *d = chr->opaque;
2528:
2529: /* TODO: the QString implementation has the same code, we should
2530: * introduce a generic way to do this in cutils.c */
2531: if (d->outbuf_capacity < d->outbuf_size + len) {
2532: /* grow outbuf */
2533: d->outbuf_capacity += len;
2534: d->outbuf_capacity *= 2;
1.1.1.12 root 2535: d->outbuf = g_realloc(d->outbuf, d->outbuf_capacity);
1.1.1.9 root 2536: }
2537:
2538: memcpy(d->outbuf + d->outbuf_size, buf, len);
2539: d->outbuf_size += len;
2540:
2541: return len;
2542: }
2543:
2544: void qemu_chr_init_mem(CharDriverState *chr)
2545: {
2546: MemoryDriver *d;
2547:
1.1.1.12 root 2548: d = g_malloc(sizeof(*d));
1.1.1.9 root 2549: d->outbuf_size = 0;
2550: d->outbuf_capacity = 4096;
1.1.1.12 root 2551: d->outbuf = g_malloc0(d->outbuf_capacity);
1.1.1.9 root 2552:
2553: memset(chr, 0, sizeof(*chr));
2554: chr->opaque = d;
2555: chr->chr_write = mem_chr_write;
2556: }
2557:
2558: QString *qemu_chr_mem_to_qs(CharDriverState *chr)
2559: {
2560: MemoryDriver *d = chr->opaque;
2561: return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1);
2562: }
2563:
1.1.1.12 root 2564: /* NOTE: this driver can not be closed with qemu_chr_delete()! */
1.1.1.9 root 2565: void qemu_chr_close_mem(CharDriverState *chr)
2566: {
2567: MemoryDriver *d = chr->opaque;
2568:
1.1.1.12 root 2569: g_free(d->outbuf);
2570: g_free(chr->opaque);
1.1.1.9 root 2571: chr->opaque = NULL;
2572: chr->chr_write = NULL;
2573: }
2574:
2575: size_t qemu_chr_mem_osize(const CharDriverState *chr)
2576: {
2577: const MemoryDriver *d = chr->opaque;
2578: return d->outbuf_size;
2579: }
2580:
1.1.1.5 root 2581: QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
1.1 root 2582: {
1.1.1.5 root 2583: char host[65], port[33], width[8], height[8];
2584: int pos;
1.1 root 2585: const char *p;
1.1.1.5 root 2586: QemuOpts *opts;
2587:
1.1.1.9 root 2588: opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1);
1.1.1.5 root 2589: if (NULL == opts)
2590: return NULL;
1.1 root 2591:
2592: if (strstart(filename, "mon:", &p)) {
1.1.1.5 root 2593: filename = p;
2594: qemu_opt_set(opts, "mux", "on");
2595: }
2596:
2597: if (strcmp(filename, "null") == 0 ||
2598: strcmp(filename, "pty") == 0 ||
2599: strcmp(filename, "msmouse") == 0 ||
2600: strcmp(filename, "braille") == 0 ||
2601: strcmp(filename, "stdio") == 0) {
2602: qemu_opt_set(opts, "backend", filename);
2603: return opts;
2604: }
2605: if (strstart(filename, "vc", &p)) {
2606: qemu_opt_set(opts, "backend", "vc");
2607: if (*p == ':') {
2608: if (sscanf(p+1, "%8[0-9]x%8[0-9]", width, height) == 2) {
2609: /* pixels */
2610: qemu_opt_set(opts, "width", width);
2611: qemu_opt_set(opts, "height", height);
2612: } else if (sscanf(p+1, "%8[0-9]Cx%8[0-9]C", width, height) == 2) {
2613: /* chars */
2614: qemu_opt_set(opts, "cols", width);
2615: qemu_opt_set(opts, "rows", height);
2616: } else {
2617: goto fail;
2618: }
1.1 root 2619: }
1.1.1.5 root 2620: return opts;
2621: }
2622: if (strcmp(filename, "con:") == 0) {
2623: qemu_opt_set(opts, "backend", "console");
2624: return opts;
2625: }
2626: if (strstart(filename, "COM", NULL)) {
2627: qemu_opt_set(opts, "backend", "serial");
2628: qemu_opt_set(opts, "path", filename);
2629: return opts;
2630: }
2631: if (strstart(filename, "file:", &p)) {
2632: qemu_opt_set(opts, "backend", "file");
2633: qemu_opt_set(opts, "path", p);
2634: return opts;
2635: }
2636: if (strstart(filename, "pipe:", &p)) {
2637: qemu_opt_set(opts, "backend", "pipe");
2638: qemu_opt_set(opts, "path", p);
2639: return opts;
2640: }
2641: if (strstart(filename, "tcp:", &p) ||
2642: strstart(filename, "telnet:", &p)) {
2643: if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
2644: host[0] = 0;
2645: if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
2646: goto fail;
2647: }
2648: qemu_opt_set(opts, "backend", "socket");
2649: qemu_opt_set(opts, "host", host);
2650: qemu_opt_set(opts, "port", port);
2651: if (p[pos] == ',') {
2652: if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)
2653: goto fail;
2654: }
2655: if (strstart(filename, "telnet:", &p))
2656: qemu_opt_set(opts, "telnet", "on");
2657: return opts;
2658: }
2659: if (strstart(filename, "udp:", &p)) {
2660: qemu_opt_set(opts, "backend", "udp");
2661: if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
2662: host[0] = 0;
1.1.1.7 root 2663: if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
1.1.1.5 root 2664: goto fail;
2665: }
2666: }
2667: qemu_opt_set(opts, "host", host);
2668: qemu_opt_set(opts, "port", port);
2669: if (p[pos] == '@') {
2670: p += pos + 1;
2671: if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
2672: host[0] = 0;
2673: if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
2674: goto fail;
2675: }
2676: }
2677: qemu_opt_set(opts, "localaddr", host);
2678: qemu_opt_set(opts, "localport", port);
2679: }
2680: return opts;
2681: }
1.1 root 2682: if (strstart(filename, "unix:", &p)) {
1.1.1.5 root 2683: qemu_opt_set(opts, "backend", "socket");
2684: if (qemu_opts_do_parse(opts, p, "path") != 0)
2685: goto fail;
2686: return opts;
2687: }
2688: if (strstart(filename, "/dev/parport", NULL) ||
2689: strstart(filename, "/dev/ppi", NULL)) {
2690: qemu_opt_set(opts, "backend", "parport");
2691: qemu_opt_set(opts, "path", filename);
2692: return opts;
2693: }
2694: if (strstart(filename, "/dev/", NULL)) {
2695: qemu_opt_set(opts, "backend", "tty");
2696: qemu_opt_set(opts, "path", filename);
2697: return opts;
2698: }
2699:
2700: fail:
2701: qemu_opts_del(opts);
2702: return NULL;
2703: }
2704:
2705: static const struct {
2706: const char *name;
1.1.1.13! root 2707: CharDriverState *(*open)(QemuOpts *opts);
1.1.1.5 root 2708: } backend_table[] = {
2709: { .name = "null", .open = qemu_chr_open_null },
2710: { .name = "socket", .open = qemu_chr_open_socket },
2711: { .name = "udp", .open = qemu_chr_open_udp },
2712: { .name = "msmouse", .open = qemu_chr_open_msmouse },
2713: { .name = "vc", .open = text_console_init },
2714: #ifdef _WIN32
2715: { .name = "file", .open = qemu_chr_open_win_file_out },
2716: { .name = "pipe", .open = qemu_chr_open_win_pipe },
2717: { .name = "console", .open = qemu_chr_open_win_con },
2718: { .name = "serial", .open = qemu_chr_open_win },
1.1.1.12 root 2719: { .name = "stdio", .open = qemu_chr_open_win_stdio },
1.1.1.5 root 2720: #else
2721: { .name = "file", .open = qemu_chr_open_file_out },
2722: { .name = "pipe", .open = qemu_chr_open_pipe },
2723: { .name = "pty", .open = qemu_chr_open_pty },
2724: { .name = "stdio", .open = qemu_chr_open_stdio },
2725: #endif
2726: #ifdef CONFIG_BRLAPI
2727: { .name = "braille", .open = chr_baum_init },
1.1 root 2728: #endif
2729: #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
1.1.1.5 root 2730: || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
2731: || defined(__FreeBSD_kernel__)
2732: { .name = "tty", .open = qemu_chr_open_tty },
1.1 root 2733: #endif
1.1.1.5 root 2734: #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) \
2735: || defined(__FreeBSD_kernel__)
2736: { .name = "parport", .open = qemu_chr_open_pp },
1.1 root 2737: #endif
1.1.1.9 root 2738: #ifdef CONFIG_SPICE
2739: { .name = "spicevmc", .open = qemu_chr_open_spice },
2740: #endif
1.1.1.5 root 2741: };
2742:
1.1.1.12 root 2743: CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
1.1.1.5 root 2744: void (*init)(struct CharDriverState *s))
2745: {
2746: CharDriverState *chr;
2747: int i;
2748:
2749: if (qemu_opts_id(opts) == NULL) {
2750: fprintf(stderr, "chardev: no id specified\n");
2751: return NULL;
2752: }
2753:
1.1.1.10 root 2754: if (qemu_opt_get(opts, "backend") == NULL) {
2755: fprintf(stderr, "chardev: \"%s\" missing backend\n",
2756: qemu_opts_id(opts));
2757: return NULL;
2758: }
1.1.1.5 root 2759: for (i = 0; i < ARRAY_SIZE(backend_table); i++) {
2760: if (strcmp(backend_table[i].name, qemu_opt_get(opts, "backend")) == 0)
2761: break;
2762: }
2763: if (i == ARRAY_SIZE(backend_table)) {
2764: fprintf(stderr, "chardev: backend \"%s\" not found\n",
2765: qemu_opt_get(opts, "backend"));
2766: return NULL;
2767: }
2768:
1.1.1.13! root 2769: chr = backend_table[i].open(opts);
! 2770: if (!chr) {
! 2771: fprintf(stderr, "chardev: opening backend \"%s\" failed\n",
! 2772: qemu_opt_get(opts, "backend"));
1.1.1.5 root 2773: return NULL;
2774: }
2775:
2776: if (!chr->filename)
1.1.1.12 root 2777: chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
1.1.1.5 root 2778: chr->init = init;
2779: QTAILQ_INSERT_TAIL(&chardevs, chr, next);
2780:
2781: if (qemu_opt_get_bool(opts, "mux", 0)) {
2782: CharDriverState *base = chr;
2783: int len = strlen(qemu_opts_id(opts)) + 6;
1.1.1.12 root 2784: base->label = g_malloc(len);
1.1.1.5 root 2785: snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
2786: chr = qemu_chr_open_mux(base);
2787: chr->filename = base->filename;
1.1.1.11 root 2788: chr->avail_connections = MAX_MUX;
1.1.1.5 root 2789: QTAILQ_INSERT_TAIL(&chardevs, chr, next);
1.1.1.11 root 2790: } else {
2791: chr->avail_connections = 1;
1.1.1.5 root 2792: }
1.1.1.12 root 2793: chr->label = g_strdup(qemu_opts_id(opts));
1.1.1.5 root 2794: return chr;
2795: }
2796:
1.1.1.12 root 2797: CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
1.1.1.5 root 2798: {
2799: const char *p;
2800: CharDriverState *chr;
2801: QemuOpts *opts;
2802:
2803: if (strstart(filename, "chardev:", &p)) {
2804: return qemu_chr_find(p);
1.1 root 2805: }
2806:
1.1.1.5 root 2807: opts = qemu_chr_parse_compat(label, filename);
2808: if (!opts)
2809: return NULL;
2810:
1.1.1.12 root 2811: chr = qemu_chr_new_from_opts(opts, init);
1.1.1.5 root 2812: if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
2813: monitor_init(chr, MONITOR_USE_READLINE);
1.1 root 2814: }
1.1.1.9 root 2815: qemu_opts_del(opts);
1.1 root 2816: return chr;
2817: }
2818:
1.1.1.12 root 2819: void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
1.1.1.9 root 2820: {
2821: if (chr->chr_set_echo) {
2822: chr->chr_set_echo(chr, echo);
2823: }
2824: }
2825:
1.1.1.12 root 2826: void qemu_chr_fe_open(struct CharDriverState *chr)
1.1.1.11 root 2827: {
2828: if (chr->chr_guest_open) {
2829: chr->chr_guest_open(chr);
2830: }
2831: }
2832:
1.1.1.12 root 2833: void qemu_chr_fe_close(struct CharDriverState *chr)
1.1.1.11 root 2834: {
2835: if (chr->chr_guest_close) {
2836: chr->chr_guest_close(chr);
2837: }
2838: }
2839:
1.1.1.12 root 2840: void qemu_chr_delete(CharDriverState *chr)
1.1 root 2841: {
1.1.1.5 root 2842: QTAILQ_REMOVE(&chardevs, chr, next);
1.1 root 2843: if (chr->chr_close)
2844: chr->chr_close(chr);
1.1.1.12 root 2845: g_free(chr->filename);
2846: g_free(chr->label);
2847: g_free(chr);
1.1.1.5 root 2848: }
2849:
1.1.1.12 root 2850: ChardevInfoList *qmp_query_chardev(Error **errp)
1.1.1.5 root 2851: {
1.1.1.12 root 2852: ChardevInfoList *chr_list = NULL;
1.1.1.5 root 2853: CharDriverState *chr;
2854:
2855: QTAILQ_FOREACH(chr, &chardevs, next) {
1.1.1.12 root 2856: ChardevInfoList *info = g_malloc0(sizeof(*info));
2857: info->value = g_malloc0(sizeof(*info->value));
2858: info->value->label = g_strdup(chr->label);
2859: info->value->filename = g_strdup(chr->filename);
2860:
2861: info->next = chr_list;
2862: chr_list = info;
1.1.1.5 root 2863: }
2864:
1.1.1.12 root 2865: return chr_list;
1.1.1.5 root 2866: }
2867:
2868: CharDriverState *qemu_chr_find(const char *name)
1.1 root 2869: {
2870: CharDriverState *chr;
2871:
1.1.1.5 root 2872: QTAILQ_FOREACH(chr, &chardevs, next) {
2873: if (strcmp(chr->label, name) != 0)
2874: continue;
2875: return chr;
1.1 root 2876: }
1.1.1.5 root 2877: return NULL;
1.1 root 2878: }
1.1.1.13! root 2879:
! 2880: /* Get a character (serial) device interface. */
! 2881: CharDriverState *qemu_char_get_next_serial(void)
! 2882: {
! 2883: static int next_serial;
! 2884:
! 2885: /* FIXME: This function needs to go away: use chardev properties! */
! 2886: return serial_hds[next_serial++];
! 2887: }
! 2888:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.