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