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