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