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