qemu-char.c 123.2 KB
Newer Older
A
aliguori 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
P
Peter Maydell 已提交
24
#include "qemu/osdep.h"
A
aliguori 已提交
25
#include "qemu-common.h"
26
#include "qemu/cutils.h"
27
#include "monitor/monitor.h"
28
#include "sysemu/sysemu.h"
29
#include "sysemu/block-backend.h"
30
#include "qemu/error-report.h"
31
#include "qemu/timer.h"
32
#include "sysemu/char.h"
A
aurel32 已提交
33
#include "hw/usb.h"
L
Luiz Capitulino 已提交
34
#include "qmp-commands.h"
35 36 37
#include "qapi/qmp-input-visitor.h"
#include "qapi/qmp-output-visitor.h"
#include "qapi-visit.h"
38
#include "qemu/base64.h"
39 40
#include "io/channel-socket.h"
#include "io/channel-file.h"
41
#include "io/channel-tls.h"
P
Pavel Dovgalyuk 已提交
42
#include "sysemu/replay.h"
A
aliguori 已提交
43 44 45 46 47 48 49 50

#include <zlib.h>

#ifndef _WIN32
#include <sys/times.h>
#include <sys/wait.h>
#include <termios.h>
#include <sys/ioctl.h>
B
blueswir1 已提交
51
#include <sys/resource.h>
A
aliguori 已提交
52 53
#include <sys/socket.h>
#include <netinet/in.h>
B
blueswir1 已提交
54 55
#include <net/if.h>
#include <arpa/inet.h>
A
aliguori 已提交
56 57
#include <netdb.h>
#include <sys/select.h>
J
Juan Quintela 已提交
58
#ifdef CONFIG_BSD
59 60 61
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
62 63 64
#elif defined(__DragonFly__)
#include <dev/misc/ppi/ppi.h>
#include <bus/ppbus/ppbconf.h>
A
aliguori 已提交
65
#endif
66
#else
A
aliguori 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
#ifdef __linux__
#include <linux/ppdev.h>
#include <linux/parport.h>
#endif
#ifdef __sun__
#include <sys/ethernet.h>
#include <sys/sockio.h>
#include <netinet/arp.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h> // must come after ip.h
#include <netinet/udp.h>
#include <netinet/tcp.h>
#endif
#endif
#endif

85
#include "qemu/sockets.h"
A
Alon Levy 已提交
86
#include "ui/qemu-spice.h"
A
aliguori 已提交
87

88
#define READ_BUF_LEN 4096
89
#define READ_RETRIES 10
M
Michael S. Tsirkin 已提交
90
#define TCP_MAX_FDS 16
91

92 93 94
/***********************************************************/
/* Socket address helpers */

95 96
static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
                                  bool is_listen, bool is_telnet)
97
{
98
    switch (addr->type) {
99
    case SOCKET_ADDRESS_KIND_INET:
100
        return g_strdup_printf("%s%s:%s:%s%s", prefix,
101 102 103 104
                               is_telnet ? "telnet" : "tcp",
                               addr->u.inet.data->host,
                               addr->u.inet.data->port,
                               is_listen ? ",server" : "");
105 106
        break;
    case SOCKET_ADDRESS_KIND_UNIX:
107
        return g_strdup_printf("%sunix:%s%s", prefix,
108
                               addr->u.q_unix.data->path,
109
                               is_listen ? ",server" : "");
110 111
        break;
    case SOCKET_ADDRESS_KIND_FD:
112
        return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.data->str,
113
                               is_listen ? ",server" : "");
114 115 116 117 118 119
        break;
    default:
        abort();
    }
}

120 121 122
static char *sockaddr_to_str(struct sockaddr_storage *ss, socklen_t ss_len,
                             struct sockaddr_storage *ps, socklen_t ps_len,
                             bool is_listen, bool is_telnet)
123
{
124 125
    char shost[NI_MAXHOST], sserv[NI_MAXSERV];
    char phost[NI_MAXHOST], pserv[NI_MAXSERV];
126 127 128 129 130
    const char *left = "", *right = "";

    switch (ss->ss_family) {
#ifndef _WIN32
    case AF_UNIX:
131 132 133
        return g_strdup_printf("unix:%s%s",
                               ((struct sockaddr_un *)(ss))->sun_path,
                               is_listen ? ",server" : "");
134 135 136 137 138 139
#endif
    case AF_INET6:
        left  = "[";
        right = "]";
        /* fall through */
    case AF_INET:
140 141 142 143
        getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
                    sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
        getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
                    pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
144 145 146 147 148
        return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
                               is_telnet ? "telnet" : "tcp",
                               left, shost, right, sserv,
                               is_listen ? ",server" : "",
                               left, phost, right, pserv);
149 150

    default:
151
        return g_strdup_printf("unknown");
152 153 154
    }
}

A
aliguori 已提交
155 156 157
/***********************************************************/
/* character device */

B
Blue Swirl 已提交
158 159
static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
    QTAILQ_HEAD_INITIALIZER(chardevs);
A
aliguori 已提交
160

161 162 163
static void qemu_chr_free_common(CharDriverState *chr);

CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp)
164 165
{
    CharDriverState *chr = g_malloc0(sizeof(CharDriverState));
166
    qemu_mutex_init(&chr->chr_write_lock);
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

    if (backend->has_logfile) {
        int flags = O_WRONLY | O_CREAT;
        if (backend->has_logappend &&
            backend->logappend) {
            flags |= O_APPEND;
        } else {
            flags |= O_TRUNC;
        }
        chr->logfd = qemu_open(backend->logfile, flags, 0666);
        if (chr->logfd < 0) {
            error_setg_errno(errp, errno,
                             "Unable to open logfile %s",
                             backend->logfile);
            g_free(chr);
            return NULL;
        }
    } else {
        chr->logfd = -1;
    }

188 189 190
    return chr;
}

191
void qemu_chr_be_event(CharDriverState *s, int event)
A
aliguori 已提交
192
{
193 194 195
    /* Keep track if the char device is open */
    switch (event) {
        case CHR_EVENT_OPENED:
196
            s->be_open = 1;
197 198
            break;
        case CHR_EVENT_CLOSED:
199
            s->be_open = 0;
200 201 202
            break;
    }

A
aliguori 已提交
203 204 205 206 207
    if (!s->chr_event)
        return;
    s->chr_event(s->handler_opaque, event);
}

208
void qemu_chr_be_generic_open(CharDriverState *s)
A
aliguori 已提交
209
{
210
    qemu_chr_be_event(s, CHR_EVENT_OPENED);
A
aliguori 已提交
211 212
}

213 214 215 216 217 218 219 220 221 222 223 224 225 226

/* Not reporting errors from writing to logfile, as logs are
 * defined to be "best effort" only */
static void qemu_chr_fe_write_log(CharDriverState *s,
                                  const uint8_t *buf, size_t len)
{
    size_t done = 0;
    ssize_t ret;

    if (s->logfd < 0) {
        return;
    }

    while (done < len) {
227 228 229 230 231 232
    retry:
        ret = write(s->logfd, buf + done, len - done);
        if (ret == -1 && errno == EAGAIN) {
            g_usleep(100);
            goto retry;
        }
233 234 235 236 237 238 239 240

        if (ret <= 0) {
            return;
        }
        done += ret;
    }
}

P
Pavel Dovgalyuk 已提交
241 242 243 244 245 246 247
static int qemu_chr_fe_write_buffer(CharDriverState *s, const uint8_t *buf, int len, int *offset)
{
    int res = 0;
    *offset = 0;

    qemu_mutex_lock(&s->chr_write_lock);
    while (*offset < len) {
248 249 250 251 252 253
    retry:
        res = s->chr_write(s, buf + *offset, len - *offset);
        if (res < 0 && errno == EAGAIN) {
            g_usleep(100);
            goto retry;
        }
P
Pavel Dovgalyuk 已提交
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268

        if (res <= 0) {
            break;
        }

        *offset += res;
    }
    if (*offset > 0) {
        qemu_chr_fe_write_log(s, buf, *offset);
    }
    qemu_mutex_unlock(&s->chr_write_lock);

    return res;
}

269
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
A
aliguori 已提交
270
{
271 272
    int ret;

P
Pavel Dovgalyuk 已提交
273 274 275 276 277 278 279 280
    if (s->replay && replay_mode == REPLAY_MODE_PLAY) {
        int offset;
        replay_char_write_event_load(&ret, &offset);
        assert(offset <= len);
        qemu_chr_fe_write_buffer(s, buf, offset, &offset);
        return ret;
    }

281 282
    qemu_mutex_lock(&s->chr_write_lock);
    ret = s->chr_write(s, buf, len);
283 284 285 286 287

    if (ret > 0) {
        qemu_chr_fe_write_log(s, buf, ret);
    }

288
    qemu_mutex_unlock(&s->chr_write_lock);
P
Pavel Dovgalyuk 已提交
289 290 291 292 293
    
    if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
        replay_char_write_event_save(ret, ret < 0 ? 0 : ret);
    }
    
294
    return ret;
A
aliguori 已提交
295 296
}

297 298
int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len)
{
P
Pavel Dovgalyuk 已提交
299 300
    int offset;
    int res;
301

P
Pavel Dovgalyuk 已提交
302 303 304 305 306 307
    if (s->replay && replay_mode == REPLAY_MODE_PLAY) {
        replay_char_write_event_load(&res, &offset);
        assert(offset <= len);
        qemu_chr_fe_write_buffer(s, buf, offset, &offset);
        return res;
    }
308

P
Pavel Dovgalyuk 已提交
309
    res = qemu_chr_fe_write_buffer(s, buf, len, &offset);
310

P
Pavel Dovgalyuk 已提交
311 312
    if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
        replay_char_write_event_save(res, offset);
313 314
    }

315 316 317
    if (res < 0) {
        return res;
    }
318 319 320
    return offset;
}

321 322 323 324 325 326 327 328
int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len)
{
    int offset = 0, counter = 10;
    int res;

    if (!s->chr_sync_read) {
        return 0;
    }
P
Pavel Dovgalyuk 已提交
329 330 331 332
    
    if (s->replay && replay_mode == REPLAY_MODE_PLAY) {
        return replay_char_read_all_load(buf);
    }
333 334

    while (offset < len) {
335 336 337 338 339 340
    retry:
        res = s->chr_sync_read(s, buf + offset, len - offset);
        if (res == -1 && errno == EAGAIN) {
            g_usleep(100);
            goto retry;
        }
341 342 343 344 345 346

        if (res == 0) {
            break;
        }

        if (res < 0) {
P
Pavel Dovgalyuk 已提交
347 348 349
            if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
                replay_char_read_all_save_error(res);
            }
350 351 352 353 354 355 356 357 358 359
            return res;
        }

        offset += res;

        if (!counter--) {
            break;
        }
    }

P
Pavel Dovgalyuk 已提交
360 361 362
    if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
        replay_char_read_all_save_buf(buf, offset);
    }
363 364 365
    return offset;
}

366
int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
A
aliguori 已提交
367
{
P
Pavel Dovgalyuk 已提交
368 369 370 371 372 373 374 375
    int res;
    if (!s->chr_ioctl || s->replay) {
        res = -ENOTSUP;
    } else {
        res = s->chr_ioctl(s, cmd, arg);
    }

    return res;
A
aliguori 已提交
376 377
}

378
int qemu_chr_be_can_write(CharDriverState *s)
A
aliguori 已提交
379 380 381 382 383 384
{
    if (!s->chr_can_read)
        return 0;
    return s->chr_can_read(s->handler_opaque);
}

P
Pavel Dovgalyuk 已提交
385
void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len)
A
aliguori 已提交
386
{
387 388 389
    if (s->chr_read) {
        s->chr_read(s->handler_opaque, buf, len);
    }
A
aliguori 已提交
390 391
}

P
Pavel Dovgalyuk 已提交
392 393 394 395 396 397 398 399 400 401 402 403
void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
{
    if (s->replay) {
        if (replay_mode == REPLAY_MODE_PLAY) {
            return;
        }
        replay_chr_be_write(s, buf, len);
    } else {
        qemu_chr_be_write_impl(s, buf, len);
    }
}

404
int qemu_chr_fe_get_msgfd(CharDriverState *s)
405
{
406
    int fd;
P
Pavel Dovgalyuk 已提交
407 408 409 410 411 412 413
    int res = (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
    if (s->replay) {
        fprintf(stderr,
                "Replay: get msgfd is not supported for serial devices yet\n");
        exit(1);
    }
    return res;
414 415 416 417 418
}

int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len)
{
    return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1;
419 420
}

421 422 423 424 425
int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num)
{
    return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1;
}

426 427 428 429 430
int qemu_chr_add_client(CharDriverState *s, int fd)
{
    return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
}

A
aliguori 已提交
431 432 433 434
void qemu_chr_accept_input(CharDriverState *s)
{
    if (s->chr_accept_input)
        s->chr_accept_input(s);
435
    qemu_notify_event();
A
aliguori 已提交
436 437
}

438
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
A
aliguori 已提交
439
{
440
    char buf[READ_BUF_LEN];
A
aliguori 已提交
441 442 443
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
444
    qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
A
aliguori 已提交
445 446 447
    va_end(ap);
}

448 449
static void remove_fd_in_watch(CharDriverState *chr);

A
aliguori 已提交
450
void qemu_chr_add_handlers(CharDriverState *s,
451
                           IOCanReadHandler *fd_can_read,
A
aliguori 已提交
452 453 454 455
                           IOReadHandler *fd_read,
                           IOEventHandler *fd_event,
                           void *opaque)
{
456 457
    int fe_open;

458
    if (!opaque && !fd_can_read && !fd_read && !fd_event) {
459
        fe_open = 0;
460
        remove_fd_in_watch(s);
461 462
    } else {
        fe_open = 1;
463
    }
A
aliguori 已提交
464 465 466 467
    s->chr_can_read = fd_can_read;
    s->chr_read = fd_read;
    s->chr_event = fd_event;
    s->handler_opaque = opaque;
468
    if (fe_open && s->chr_update_read_handler)
A
aliguori 已提交
469
        s->chr_update_read_handler(s);
470

471
    if (!s->explicit_fe_open) {
472
        qemu_chr_fe_set_open(s, fe_open);
473 474
    }

475 476
    /* We're connecting to an already opened device, so let's make sure we
       also get the open event */
477
    if (fe_open && s->be_open) {
478
        qemu_chr_be_generic_open(s);
479
    }
A
aliguori 已提交
480 481 482 483 484 485 486
}

static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    return len;
}

487 488 489 490
static CharDriverState *qemu_chr_open_null(const char *id,
                                           ChardevBackend *backend,
                                           ChardevReturn *ret,
                                           Error **errp)
A
aliguori 已提交
491 492
{
    CharDriverState *chr;
493
    ChardevCommon *common = backend->u.null.data;
A
aliguori 已提交
494

495 496 497 498
    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
        return NULL;
    }
A
aliguori 已提交
499
    chr->chr_write = null_chr_write;
500
    chr->explicit_be_open = true;
501
    return chr;
A
aliguori 已提交
502 503 504 505 506 507 508
}

/* MUX driver for serial I/O splitting */
#define MAX_MUX 4
#define MUX_BUFFER_SIZE 32	/* Must be a power of 2.  */
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
typedef struct {
509
    IOCanReadHandler *chr_can_read[MAX_MUX];
A
aliguori 已提交
510 511 512 513
    IOReadHandler *chr_read[MAX_MUX];
    IOEventHandler *chr_event[MAX_MUX];
    void *ext_opaque[MAX_MUX];
    CharDriverState *drv;
514
    int focus;
A
aliguori 已提交
515 516 517
    int mux_cnt;
    int term_got_escape;
    int max_size;
518 519 520 521 522 523
    /* Intermediate input buffer allows to catch escape sequences even if the
       currently active device is not accepting any input - but only until it
       is full as well. */
    unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
    int prod[MAX_MUX];
    int cons[MAX_MUX];
J
Jan Kiszka 已提交
524
    int timestamps;
525 526

    /* Protected by the CharDriverState chr_write_lock.  */
J
Jan Kiszka 已提交
527
    int linestart;
J
Jan Kiszka 已提交
528
    int64_t timestamps_start;
A
aliguori 已提交
529 530 531
} MuxDriver;


532
/* Called with chr_write_lock held.  */
A
aliguori 已提交
533 534 535 536
static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    MuxDriver *d = chr->opaque;
    int ret;
J
Jan Kiszka 已提交
537
    if (!d->timestamps) {
538
        ret = qemu_chr_fe_write(d->drv, buf, len);
A
aliguori 已提交
539 540 541 542
    } else {
        int i;

        ret = 0;
J
Jan Kiszka 已提交
543 544
        for (i = 0; i < len; i++) {
            if (d->linestart) {
A
aliguori 已提交
545 546 547 548
                char buf1[64];
                int64_t ti;
                int secs;

549
                ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
J
Jan Kiszka 已提交
550 551 552
                if (d->timestamps_start == -1)
                    d->timestamps_start = ti;
                ti -= d->timestamps_start;
553
                secs = ti / 1000;
A
aliguori 已提交
554 555 556 557 558
                snprintf(buf1, sizeof(buf1),
                         "[%02d:%02d:%02d.%03d] ",
                         secs / 3600,
                         (secs / 60) % 60,
                         secs % 60,
559
                         (int)(ti % 1000));
560
                qemu_chr_fe_write(d->drv, (uint8_t *)buf1, strlen(buf1));
J
Jan Kiszka 已提交
561 562
                d->linestart = 0;
            }
563
            ret += qemu_chr_fe_write(d->drv, buf+i, 1);
J
Jan Kiszka 已提交
564 565
            if (buf[i] == '\n') {
                d->linestart = 1;
A
aliguori 已提交
566 567 568 569 570 571 572 573 574 575
            }
        }
    }
    return ret;
}

static const char * const mux_help[] = {
    "% h    print this help\n\r",
    "% x    exit emulator\n\r",
    "% s    save disk data back to file (if -snapshot)\n\r",
G
Gonglei 已提交
576
    "% t    toggle console timestamps\n\r",
A
aliguori 已提交
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
    "% b    send break (magic sysrq)\n\r",
    "% c    switch between console and monitor\n\r",
    "% %  sends %\n\r",
    NULL
};

int term_escape_char = 0x01; /* ctrl-a is used for escape */
static void mux_print_help(CharDriverState *chr)
{
    int i, j;
    char ebuf[15] = "Escape-Char";
    char cbuf[50] = "\n\r";

    if (term_escape_char > 0 && term_escape_char < 26) {
        snprintf(cbuf, sizeof(cbuf), "\n\r");
        snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
    } else {
        snprintf(cbuf, sizeof(cbuf),
                 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
                 term_escape_char);
    }
598
    qemu_chr_fe_write(chr, (uint8_t *)cbuf, strlen(cbuf));
A
aliguori 已提交
599 600 601
    for (i = 0; mux_help[i] != NULL; i++) {
        for (j=0; mux_help[i][j] != '\0'; j++) {
            if (mux_help[i][j] == '%')
602
                qemu_chr_fe_write(chr, (uint8_t *)ebuf, strlen(ebuf));
A
aliguori 已提交
603
            else
604
                qemu_chr_fe_write(chr, (uint8_t *)&mux_help[i][j], 1);
A
aliguori 已提交
605 606 607 608
        }
    }
}

609 610 611 612 613 614
static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event)
{
    if (d->chr_event[mux_nr])
        d->chr_event[mux_nr](d->ext_opaque[mux_nr], event);
}

A
aliguori 已提交
615 616 617 618 619 620 621 622 623 624 625 626 627 628
static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
{
    if (d->term_got_escape) {
        d->term_got_escape = 0;
        if (ch == term_escape_char)
            goto send_char;
        switch(ch) {
        case '?':
        case 'h':
            mux_print_help(chr);
            break;
        case 'x':
            {
                 const char *term =  "QEMU: Terminated\n\r";
629
                 qemu_chr_fe_write(chr, (uint8_t *)term, strlen(term));
A
aliguori 已提交
630 631 632 633
                 exit(0);
                 break;
            }
        case 's':
634
            blk_commit_all();
A
aliguori 已提交
635 636
            break;
        case 'b':
637
            qemu_chr_be_event(chr, CHR_EVENT_BREAK);
A
aliguori 已提交
638 639 640
            break;
        case 'c':
            /* Switch to the next registered device */
641 642 643 644 645
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
            d->focus++;
            if (d->focus >= d->mux_cnt)
                d->focus = 0;
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
A
aliguori 已提交
646
            break;
J
Jan Kiszka 已提交
647 648 649
        case 't':
            d->timestamps = !d->timestamps;
            d->timestamps_start = -1;
J
Jan Kiszka 已提交
650
            d->linestart = 0;
J
Jan Kiszka 已提交
651
            break;
A
aliguori 已提交
652 653 654 655 656 657 658 659 660 661 662 663 664
        }
    } else if (ch == term_escape_char) {
        d->term_got_escape = 1;
    } else {
    send_char:
        return 1;
    }
    return 0;
}

static void mux_chr_accept_input(CharDriverState *chr)
{
    MuxDriver *d = chr->opaque;
665
    int m = d->focus;
A
aliguori 已提交
666

667
    while (d->prod[m] != d->cons[m] &&
A
aliguori 已提交
668 669 670
           d->chr_can_read[m] &&
           d->chr_can_read[m](d->ext_opaque[m])) {
        d->chr_read[m](d->ext_opaque[m],
671
                       &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
A
aliguori 已提交
672 673 674 675 676 677 678
    }
}

static int mux_chr_can_read(void *opaque)
{
    CharDriverState *chr = opaque;
    MuxDriver *d = chr->opaque;
679
    int m = d->focus;
A
aliguori 已提交
680

681
    if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
A
aliguori 已提交
682
        return 1;
683 684
    if (d->chr_can_read[m])
        return d->chr_can_read[m](d->ext_opaque[m]);
A
aliguori 已提交
685 686 687 688 689 690 691
    return 0;
}

static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
{
    CharDriverState *chr = opaque;
    MuxDriver *d = chr->opaque;
692
    int m = d->focus;
A
aliguori 已提交
693 694 695 696 697 698
    int i;

    mux_chr_accept_input (opaque);

    for(i = 0; i < size; i++)
        if (mux_proc_byte(chr, d, buf[i])) {
699
            if (d->prod[m] == d->cons[m] &&
A
aliguori 已提交
700 701 702 703
                d->chr_can_read[m] &&
                d->chr_can_read[m](d->ext_opaque[m]))
                d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
            else
704
                d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
A
aliguori 已提交
705 706 707 708 709 710 711 712 713 714 715
        }
}

static void mux_chr_event(void *opaque, int event)
{
    CharDriverState *chr = opaque;
    MuxDriver *d = chr->opaque;
    int i;

    /* Send the event to all registered listeners */
    for (i = 0; i < d->mux_cnt; i++)
716
        mux_chr_send_event(d, i, event);
A
aliguori 已提交
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
}

static void mux_chr_update_read_handler(CharDriverState *chr)
{
    MuxDriver *d = chr->opaque;

    if (d->mux_cnt >= MAX_MUX) {
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
        return;
    }
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
    d->chr_read[d->mux_cnt] = chr->chr_read;
    d->chr_event[d->mux_cnt] = chr->chr_event;
    /* Fix up the real driver with mux routines */
    if (d->mux_cnt == 0) {
        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
                              mux_chr_event, chr);
    }
736 737
    if (d->focus != -1) {
        mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
G
Gerd Hoffmann 已提交
738
    }
739
    d->focus = d->mux_cnt;
A
aliguori 已提交
740
    d->mux_cnt++;
741
    mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
A
aliguori 已提交
742 743
}

744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
static bool muxes_realized;

/**
 * Called after processing of default and command-line-specified
 * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
 * to a mux chardev. This is done here to ensure that
 * output/prompts/banners are only displayed for the FE that has
 * focus when initial command-line processing/machine init is
 * completed.
 *
 * After this point, any new FE attached to any new or existing
 * mux will receive CHR_EVENT_OPENED notifications for the BE
 * immediately.
 */
static void muxes_realize_done(Notifier *notifier, void *unused)
{
    CharDriverState *chr;

    QTAILQ_FOREACH(chr, &chardevs, next) {
        if (chr->is_mux) {
            MuxDriver *d = chr->opaque;
            int i;

            /* send OPENED to all already-attached FEs */
            for (i = 0; i < d->mux_cnt; i++) {
                mux_chr_send_event(d, i, CHR_EVENT_OPENED);
            }
            /* mark mux as OPENED so any new FEs will immediately receive
             * OPENED event
             */
            qemu_chr_be_generic_open(chr);
        }
    }
    muxes_realized = true;
}

static Notifier muxes_realize_notify = {
    .notify = muxes_realize_done,
};

784 785 786 787 788 789
static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond)
{
    MuxDriver *d = s->opaque;
    return d->drv->chr_add_watch(d->drv, cond);
}

790 791 792
static CharDriverState *qemu_chr_open_mux(const char *id,
                                          ChardevBackend *backend,
                                          ChardevReturn *ret, Error **errp)
A
aliguori 已提交
793
{
794
    ChardevMux *mux = backend->u.mux.data;
795
    CharDriverState *chr, *drv;
A
aliguori 已提交
796
    MuxDriver *d;
797
    ChardevCommon *common = qapi_ChardevMux_base(mux);
A
aliguori 已提交
798

799 800 801 802 803 804
    drv = qemu_chr_find(mux->chardev);
    if (drv == NULL) {
        error_setg(errp, "mux: base chardev %s not found", mux->chardev);
        return NULL;
    }

805 806 807 808
    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
        return NULL;
    }
809
    d = g_new0(MuxDriver, 1);
A
aliguori 已提交
810 811 812

    chr->opaque = d;
    d->drv = drv;
813
    d->focus = -1;
A
aliguori 已提交
814 815 816
    chr->chr_write = mux_chr_write;
    chr->chr_update_read_handler = mux_chr_update_read_handler;
    chr->chr_accept_input = mux_chr_accept_input;
817
    /* Frontend guest-open / -close notification is not support with muxes */
818
    chr->chr_set_fe_open = NULL;
819 820 821
    if (drv->chr_add_watch) {
        chr->chr_add_watch = mux_chr_add_watch;
    }
822 823 824 825 826
    /* only default to opened state if we've realized the initial
     * set of muxes
     */
    chr->explicit_be_open = muxes_realized ? 0 : 1;
    chr->is_mux = 1;
827

A
aliguori 已提交
828 829 830 831
    return chr;
}


A
Anthony Liguori 已提交
832 833
typedef struct IOWatchPoll
{
834 835
    GSource parent;

836
    QIOChannel *ioc;
A
Anthony Liguori 已提交
837 838 839
    GSource *src;

    IOCanReadHandler *fd_can_read;
840
    GSourceFunc fd_read;
A
Anthony Liguori 已提交
841 842 843 844 845
    void *opaque;
} IOWatchPoll;

static IOWatchPoll *io_watch_poll_from_source(GSource *source)
{
846
    return container_of(source, IOWatchPoll, parent);
A
Anthony Liguori 已提交
847 848 849 850 851
}

static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
{
    IOWatchPoll *iwp = io_watch_poll_from_source(source);
852
    bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
853
    bool was_active = iwp->src != NULL;
854
    if (was_active == now_active) {
A
Anthony Liguori 已提交
855 856 857
        return FALSE;
    }

858
    if (now_active) {
859 860
        iwp->src = qio_channel_create_watch(
            iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
861
        g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
862 863
        g_source_attach(iwp->src, NULL);
    } else {
864 865 866
        g_source_destroy(iwp->src);
        g_source_unref(iwp->src);
        iwp->src = NULL;
867 868
    }
    return FALSE;
A
Anthony Liguori 已提交
869 870 871 872
}

static gboolean io_watch_poll_check(GSource *source)
{
873
    return FALSE;
A
Anthony Liguori 已提交
874 875 876 877 878
}

static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
                                       gpointer user_data)
{
879
    abort();
A
Anthony Liguori 已提交
880 881 882 883
}

static void io_watch_poll_finalize(GSource *source)
{
884 885 886 887 888 889 890 891 892 893
    /* Due to a glib bug, removing the last reference to a source
     * inside a finalize callback causes recursive locking (and a
     * deadlock).  This is not a problem inside other callbacks,
     * including dispatch callbacks, so we call io_remove_watch_poll
     * to remove this source.  At this point, iwp->src must
     * be NULL, or we would leak it.
     *
     * This would be solved much more elegantly by child sources,
     * but we support older glib versions that do not have them.
     */
A
Anthony Liguori 已提交
894
    IOWatchPoll *iwp = io_watch_poll_from_source(source);
895
    assert(iwp->src == NULL);
A
Anthony Liguori 已提交
896 897 898 899 900 901 902 903 904 905
}

static GSourceFuncs io_watch_poll_funcs = {
    .prepare = io_watch_poll_prepare,
    .check = io_watch_poll_check,
    .dispatch = io_watch_poll_dispatch,
    .finalize = io_watch_poll_finalize,
};

/* Can only be used for read */
906
static guint io_add_watch_poll(QIOChannel *ioc,
A
Anthony Liguori 已提交
907
                               IOCanReadHandler *fd_can_read,
908
                               QIOChannelFunc fd_read,
A
Anthony Liguori 已提交
909 910 911
                               gpointer user_data)
{
    IOWatchPoll *iwp;
912
    int tag;
A
Anthony Liguori 已提交
913

914
    iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs, sizeof(IOWatchPoll));
A
Anthony Liguori 已提交
915 916
    iwp->fd_can_read = fd_can_read;
    iwp->opaque = user_data;
917
    iwp->ioc = ioc;
918 919
    iwp->fd_read = (GSourceFunc) fd_read;
    iwp->src = NULL;
A
Anthony Liguori 已提交
920

921 922 923
    tag = g_source_attach(&iwp->parent, NULL);
    g_source_unref(&iwp->parent);
    return tag;
A
Anthony Liguori 已提交
924 925
}

926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944
static void io_remove_watch_poll(guint tag)
{
    GSource *source;
    IOWatchPoll *iwp;

    g_return_if_fail (tag > 0);

    source = g_main_context_find_source_by_id(NULL, tag);
    g_return_if_fail (source != NULL);

    iwp = io_watch_poll_from_source(source);
    if (iwp->src) {
        g_source_destroy(iwp->src);
        g_source_unref(iwp->src);
        iwp->src = NULL;
    }
    g_source_destroy(&iwp->parent);
}

945 946 947 948 949 950 951 952
static void remove_fd_in_watch(CharDriverState *chr)
{
    if (chr->fd_in_tag) {
        io_remove_watch_poll(chr->fd_in_tag);
        chr->fd_in_tag = 0;
    }
}

A
Anthony Liguori 已提交
953

954 955 956
static int io_channel_send_full(QIOChannel *ioc,
                                const void *buf, size_t len,
                                int *fds, size_t nfds)
957
{
958
    size_t offset = 0;
959

960 961 962 963 964 965 966 967 968 969 970 971
    while (offset < len) {
        ssize_t ret = 0;
        struct iovec iov = { .iov_base = (char *)buf + offset,
                             .iov_len = len - offset };

        ret = qio_channel_writev_full(
            ioc, &iov, 1,
            fds, nfds, NULL);
        if (ret == QIO_CHANNEL_ERR_BLOCK) {
            if (offset) {
                return offset;
            }
972

973 974 975
            errno = EAGAIN;
            return -1;
        } else if (ret < 0) {
976 977 978
            errno = EINVAL;
            return -1;
        }
979

980 981
        offset += ret;
    }
982

983
    return offset;
984 985
}

986

987
#ifndef _WIN32
988
static int io_channel_send(QIOChannel *ioc, const void *buf, size_t len)
A
Anthony Liguori 已提交
989
{
990
    return io_channel_send_full(ioc, buf, len, NULL, 0);
A
Anthony Liguori 已提交
991 992
}

B
Blue Swirl 已提交
993

994 995
typedef struct FDCharDriver {
    CharDriverState *chr;
996
    QIOChannel *ioc_in, *ioc_out;
A
aliguori 已提交
997 998 999
    int max_size;
} FDCharDriver;

1000
/* Called with chr_write_lock held.  */
A
aliguori 已提交
1001 1002 1003
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    FDCharDriver *s = chr->opaque;
1004
    
1005
    return io_channel_send(s->ioc_out, buf, len);
A
aliguori 已提交
1006 1007
}

1008
static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
A
aliguori 已提交
1009 1010 1011
{
    CharDriverState *chr = opaque;
    FDCharDriver *s = chr->opaque;
1012
    int len;
1013
    uint8_t buf[READ_BUF_LEN];
1014
    ssize_t ret;
A
aliguori 已提交
1015 1016

    len = sizeof(buf);
1017
    if (len > s->max_size) {
A
aliguori 已提交
1018
        len = s->max_size;
1019 1020
    }
    if (len == 0) {
1021
        return TRUE;
1022 1023
    }

1024 1025 1026
    ret = qio_channel_read(
        chan, (gchar *)buf, len, NULL);
    if (ret == 0) {
1027
        remove_fd_in_watch(chr);
1028
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1029
        return FALSE;
A
aliguori 已提交
1030
    }
1031 1032
    if (ret > 0) {
        qemu_chr_be_write(chr, buf, ret);
A
aliguori 已提交
1033
    }
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044

    return TRUE;
}

static int fd_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    FDCharDriver *s = chr->opaque;

    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
A
aliguori 已提交
1045 1046
}

A
Anthony Liguori 已提交
1047 1048 1049
static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{
    FDCharDriver *s = chr->opaque;
1050
    return qio_channel_create_watch(s->ioc_out, cond);
A
Anthony Liguori 已提交
1051 1052
}

A
aliguori 已提交
1053 1054 1055 1056
static void fd_chr_update_read_handler(CharDriverState *chr)
{
    FDCharDriver *s = chr->opaque;

1057
    remove_fd_in_watch(chr);
1058 1059 1060
    if (s->ioc_in) {
        chr->fd_in_tag = io_add_watch_poll(s->ioc_in,
                                           fd_chr_read_poll,
1061
                                           fd_chr_read, chr);
A
aliguori 已提交
1062 1063 1064 1065 1066 1067 1068
    }
}

static void fd_chr_close(struct CharDriverState *chr)
{
    FDCharDriver *s = chr->opaque;

1069
    remove_fd_in_watch(chr);
1070 1071
    if (s->ioc_in) {
        object_unref(OBJECT(s->ioc_in));
1072
    }
1073 1074
    if (s->ioc_out) {
        object_unref(OBJECT(s->ioc_out));
A
aliguori 已提交
1075 1076
    }

1077
    g_free(s);
1078
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
A
aliguori 已提交
1079 1080 1081
}

/* open a character device to a unix fd */
1082 1083
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out,
                                         ChardevCommon *backend, Error **errp)
A
aliguori 已提交
1084 1085 1086 1087
{
    CharDriverState *chr;
    FDCharDriver *s;

1088 1089 1090 1091
    chr = qemu_chr_alloc(backend, errp);
    if (!chr) {
        return NULL;
    }
1092
    s = g_new0(FDCharDriver, 1);
1093 1094
    s->ioc_in = QIO_CHANNEL(qio_channel_file_new_fd(fd_in));
    s->ioc_out = QIO_CHANNEL(qio_channel_file_new_fd(fd_out));
1095
    qemu_set_nonblock(fd_out);
1096
    s->chr = chr;
A
aliguori 已提交
1097
    chr->opaque = s;
A
Anthony Liguori 已提交
1098
    chr->chr_add_watch = fd_chr_add_watch;
A
aliguori 已提交
1099 1100 1101 1102 1103 1104 1105
    chr->chr_write = fd_chr_write;
    chr->chr_update_read_handler = fd_chr_update_read_handler;
    chr->chr_close = fd_chr_close;

    return chr;
}

1106 1107 1108 1109
static CharDriverState *qemu_chr_open_pipe(const char *id,
                                           ChardevBackend *backend,
                                           ChardevReturn *ret,
                                           Error **errp)
A
aliguori 已提交
1110
{
1111
    ChardevHostdev *opts = backend->u.pipe.data;
A
aliguori 已提交
1112
    int fd_in, fd_out;
1113 1114
    char *filename_in;
    char *filename_out;
1115
    const char *filename = opts->device;
1116
    ChardevCommon *common = qapi_ChardevHostdev_base(opts);
1117

1118 1119 1120

    filename_in = g_strdup_printf("%s.in", filename);
    filename_out = g_strdup_printf("%s.out", filename);
K
Kevin Wolf 已提交
1121 1122
    TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
    TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
1123 1124
    g_free(filename_in);
    g_free(filename_out);
A
aliguori 已提交
1125 1126 1127 1128 1129
    if (fd_in < 0 || fd_out < 0) {
	if (fd_in >= 0)
	    close(fd_in);
	if (fd_out >= 0)
	    close(fd_out);
1130
        TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
1131
        if (fd_in < 0) {
1132
            error_setg_file_open(errp, errno, filename);
1133
            return NULL;
1134
        }
A
aliguori 已提交
1135
    }
1136
    return qemu_chr_open_fd(fd_in, fd_out, common, errp);
A
aliguori 已提交
1137 1138 1139 1140 1141
}

/* init terminal so that we can grab keys */
static struct termios oldtty;
static int old_fd0_flags;
1142
static bool stdio_in_use;
1143
static bool stdio_allow_signal;
1144 1145 1146
static bool stdio_echo_state;

static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo);
A
aliguori 已提交
1147 1148 1149 1150 1151 1152 1153

static void term_exit(void)
{
    tcsetattr (0, TCSANOW, &oldtty);
    fcntl(0, F_SETFL, old_fd0_flags);
}

1154 1155 1156 1157 1158 1159
static void term_stdio_handler(int sig)
{
    /* restore echo after resume from suspend. */
    qemu_chr_set_echo_stdio(NULL, stdio_echo_state);
}

1160
static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
A
aliguori 已提交
1161 1162 1163
{
    struct termios tty;

1164
    stdio_echo_state = echo;
1165
    tty = oldtty;
1166 1167
    if (!echo) {
        tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
A
aliguori 已提交
1168
                          |INLCR|IGNCR|ICRNL|IXON);
1169 1170 1171 1172 1173 1174 1175 1176
        tty.c_oflag |= OPOST;
        tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
        tty.c_cflag &= ~(CSIZE|PARENB);
        tty.c_cflag |= CS8;
        tty.c_cc[VMIN] = 1;
        tty.c_cc[VTIME] = 0;
    }
    if (!stdio_allow_signal)
A
aliguori 已提交
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
        tty.c_lflag &= ~ISIG;

    tcsetattr (0, TCSANOW, &tty);
}

static void qemu_chr_close_stdio(struct CharDriverState *chr)
{
    term_exit();
    fd_chr_close(chr);
}

1188 1189 1190 1191
static CharDriverState *qemu_chr_open_stdio(const char *id,
                                            ChardevBackend *backend,
                                            ChardevReturn *ret,
                                            Error **errp)
A
aliguori 已提交
1192
{
1193
    ChardevStdio *opts = backend->u.stdio.data;
A
aliguori 已提交
1194
    CharDriverState *chr;
1195
    struct sigaction act;
1196
    ChardevCommon *common = qapi_ChardevStdio_base(opts);
A
aliguori 已提交
1197

1198
    if (is_daemonized()) {
1199
        error_setg(errp, "cannot use stdio with -daemonize");
1200 1201
        return NULL;
    }
1202 1203

    if (stdio_in_use) {
1204 1205
        error_setg(errp, "cannot use stdio by multiple character devices");
        return NULL;
1206 1207 1208
    }

    stdio_in_use = true;
1209
    old_fd0_flags = fcntl(0, F_GETFL);
1210
    tcgetattr(0, &oldtty);
1211
    qemu_set_nonblock(0);
1212
    atexit(term_exit);
1213

1214 1215 1216 1217
    memset(&act, 0, sizeof(act));
    act.sa_handler = term_stdio_handler;
    sigaction(SIGCONT, &act, NULL);

1218
    chr = qemu_chr_open_fd(0, 1, common, errp);
A
aliguori 已提交
1219
    chr->chr_close = qemu_chr_close_stdio;
1220
    chr->chr_set_echo = qemu_chr_set_echo_stdio;
1221 1222 1223
    if (opts->has_signal) {
        stdio_allow_signal = opts->signal;
    }
1224
    qemu_chr_fe_set_echo(chr, false);
A
aliguori 已提交
1225

1226
    return chr;
A
aliguori 已提交
1227 1228 1229
}

#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
A
Aurelien Jarno 已提交
1230 1231
    || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
    || defined(__GLIBC__)
A
aliguori 已提交
1232

P
Paolo Bonzini 已提交
1233 1234
#define HAVE_CHARDEV_SERIAL 1
#define HAVE_CHARDEV_PTY 1
1235

A
aliguori 已提交
1236
typedef struct {
1237
    QIOChannel *ioc;
A
aliguori 已提交
1238
    int read_bytes;
1239 1240 1241

    /* Protected by the CharDriverState chr_write_lock.  */
    int connected;
1242
    guint timer_tag;
1243
    guint open_tag;
A
aliguori 已提交
1244 1245
} PtyCharDriver;

1246
static void pty_chr_update_read_handler_locked(CharDriverState *chr);
A
aliguori 已提交
1247 1248
static void pty_chr_state(CharDriverState *chr, int connected);

1249 1250 1251 1252 1253
static gboolean pty_chr_timer(gpointer opaque)
{
    struct CharDriverState *chr = opaque;
    PtyCharDriver *s = chr->opaque;

1254
    qemu_mutex_lock(&chr->chr_write_lock);
1255
    s->timer_tag = 0;
1256
    s->open_tag = 0;
G
Gerd Hoffmann 已提交
1257 1258
    if (!s->connected) {
        /* Next poll ... */
1259
        pty_chr_update_read_handler_locked(chr);
G
Gerd Hoffmann 已提交
1260
    }
1261
    qemu_mutex_unlock(&chr->chr_write_lock);
1262 1263 1264
    return FALSE;
}

1265
/* Called with chr_write_lock held.  */
1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
static void pty_chr_rearm_timer(CharDriverState *chr, int ms)
{
    PtyCharDriver *s = chr->opaque;

    if (s->timer_tag) {
        g_source_remove(s->timer_tag);
        s->timer_tag = 0;
    }

    if (ms == 1000) {
        s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
    } else {
        s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
    }
}

1282 1283
/* Called with chr_write_lock held.  */
static void pty_chr_update_read_handler_locked(CharDriverState *chr)
1284 1285 1286
{
    PtyCharDriver *s = chr->opaque;
    GPollFD pfd;
P
Paolo Bonzini 已提交
1287
    int rc;
1288
    QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc);
1289

1290
    pfd.fd = fioc->fd;
1291 1292
    pfd.events = G_IO_OUT;
    pfd.revents = 0;
P
Paolo Bonzini 已提交
1293 1294 1295 1296 1297
    do {
        rc = g_poll(&pfd, 1, 0);
    } while (rc == -1 && errno == EINTR);
    assert(rc >= 0);

1298 1299 1300 1301 1302 1303 1304
    if (pfd.revents & G_IO_HUP) {
        pty_chr_state(chr, 0);
    } else {
        pty_chr_state(chr, 1);
    }
}

1305 1306 1307 1308 1309 1310 1311 1312
static void pty_chr_update_read_handler(CharDriverState *chr)
{
    qemu_mutex_lock(&chr->chr_write_lock);
    pty_chr_update_read_handler_locked(chr);
    qemu_mutex_unlock(&chr->chr_write_lock);
}

/* Called with chr_write_lock held.  */
A
aliguori 已提交
1313 1314 1315 1316 1317 1318
static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    PtyCharDriver *s = chr->opaque;

    if (!s->connected) {
        /* guest sends data, check for (re-)connect */
1319
        pty_chr_update_read_handler_locked(chr);
1320 1321 1322
        if (!s->connected) {
            return 0;
        }
A
aliguori 已提交
1323
    }
1324
    return io_channel_send(s->ioc, buf, len);
A
aliguori 已提交
1325 1326
}

A
Anthony Liguori 已提交
1327 1328 1329
static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{
    PtyCharDriver *s = chr->opaque;
1330 1331 1332
    if (!s->connected) {
        return NULL;
    }
1333
    return qio_channel_create_watch(s->ioc, cond);
A
Anthony Liguori 已提交
1334 1335
}

A
aliguori 已提交
1336 1337 1338 1339 1340
static int pty_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    PtyCharDriver *s = chr->opaque;

1341
    s->read_bytes = qemu_chr_be_can_write(chr);
A
aliguori 已提交
1342 1343 1344
    return s->read_bytes;
}

1345
static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
A
aliguori 已提交
1346 1347 1348
{
    CharDriverState *chr = opaque;
    PtyCharDriver *s = chr->opaque;
1349
    gsize len;
1350
    uint8_t buf[READ_BUF_LEN];
1351
    ssize_t ret;
A
aliguori 已提交
1352 1353 1354 1355

    len = sizeof(buf);
    if (len > s->read_bytes)
        len = s->read_bytes;
1356 1357 1358
    if (len == 0) {
        return TRUE;
    }
1359 1360
    ret = qio_channel_read(s->ioc, (char *)buf, len, NULL);
    if (ret <= 0) {
A
aliguori 已提交
1361
        pty_chr_state(chr, 0);
1362 1363
        return FALSE;
    } else {
A
aliguori 已提交
1364
        pty_chr_state(chr, 1);
1365
        qemu_chr_be_write(chr, buf, ret);
A
aliguori 已提交
1366
    }
1367
    return TRUE;
A
aliguori 已提交
1368 1369
}

1370 1371 1372 1373 1374 1375 1376 1377 1378 1379
static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
{
    CharDriverState *chr = opaque;
    PtyCharDriver *s = chr->opaque;

    s->open_tag = 0;
    qemu_chr_be_generic_open(chr);
    return FALSE;
}

1380
/* Called with chr_write_lock held.  */
A
aliguori 已提交
1381 1382 1383 1384 1385
static void pty_chr_state(CharDriverState *chr, int connected)
{
    PtyCharDriver *s = chr->opaque;

    if (!connected) {
1386 1387 1388 1389
        if (s->open_tag) {
            g_source_remove(s->open_tag);
            s->open_tag = 0;
        }
1390
        remove_fd_in_watch(chr);
A
aliguori 已提交
1391 1392 1393 1394
        s->connected = 0;
        /* (re-)connect poll interval for idle guests: once per second.
         * We check more frequently in case the guests sends data to
         * the virtual device linked to our pty. */
1395
        pty_chr_rearm_timer(chr, 1000);
A
aliguori 已提交
1396
    } else {
P
Paolo Bonzini 已提交
1397 1398 1399 1400 1401
        if (s->timer_tag) {
            g_source_remove(s->timer_tag);
            s->timer_tag = 0;
        }
        if (!s->connected) {
1402
            g_assert(s->open_tag == 0);
P
Paolo Bonzini 已提交
1403
            s->connected = 1;
1404
            s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
1405 1406
        }
        if (!chr->fd_in_tag) {
1407 1408
            chr->fd_in_tag = io_add_watch_poll(s->ioc,
                                               pty_chr_read_poll,
1409
                                               pty_chr_read, chr);
P
Paolo Bonzini 已提交
1410
        }
A
aliguori 已提交
1411 1412 1413 1414 1415 1416 1417
    }
}

static void pty_chr_close(struct CharDriverState *chr)
{
    PtyCharDriver *s = chr->opaque;

1418 1419
    qemu_mutex_lock(&chr->chr_write_lock);
    pty_chr_state(chr, 0);
1420
    object_unref(OBJECT(s->ioc));
1421 1422
    if (s->timer_tag) {
        g_source_remove(s->timer_tag);
1423
        s->timer_tag = 0;
1424
    }
1425
    qemu_mutex_unlock(&chr->chr_write_lock);
1426
    g_free(s);
1427
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
A
aliguori 已提交
1428 1429
}

G
Gerd Hoffmann 已提交
1430
static CharDriverState *qemu_chr_open_pty(const char *id,
1431 1432 1433
                                          ChardevBackend *backend,
                                          ChardevReturn *ret,
                                          Error **errp)
A
aliguori 已提交
1434 1435 1436
{
    CharDriverState *chr;
    PtyCharDriver *s;
G
Gerd Hoffmann 已提交
1437
    int master_fd, slave_fd;
A
aliguori 已提交
1438
    char pty_name[PATH_MAX];
1439
    ChardevCommon *common = backend->u.pty.data;
A
aliguori 已提交
1440

1441 1442
    master_fd = qemu_openpty_raw(&slave_fd, pty_name);
    if (master_fd < 0) {
1443
        error_setg_errno(errp, errno, "Failed to create PTY");
1444
        return NULL;
A
aliguori 已提交
1445 1446
    }

1447
    close(slave_fd);
D
Don Slutz 已提交
1448
    qemu_set_nonblock(master_fd);
A
aliguori 已提交
1449

1450 1451 1452 1453 1454
    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
        close(master_fd);
        return NULL;
    }
1455

1456 1457
    chr->filename = g_strdup_printf("pty:%s", pty_name);
    ret->pty = g_strdup(pty_name);
G
Gerd Hoffmann 已提交
1458
    ret->has_pty = true;
1459

G
Gerd Hoffmann 已提交
1460
    fprintf(stderr, "char device redirected to %s (label %s)\n",
1461
            pty_name, id);
A
aliguori 已提交
1462

1463
    s = g_new0(PtyCharDriver, 1);
A
aliguori 已提交
1464 1465 1466 1467
    chr->opaque = s;
    chr->chr_write = pty_chr_write;
    chr->chr_update_read_handler = pty_chr_update_read_handler;
    chr->chr_close = pty_chr_close;
A
Anthony Liguori 已提交
1468
    chr->chr_add_watch = pty_chr_add_watch;
1469
    chr->explicit_be_open = true;
A
aliguori 已提交
1470

1471
    s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd));
1472
    s->timer_tag = 0;
A
aliguori 已提交
1473

1474
    return chr;
A
aliguori 已提交
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488
}

static void tty_serial_init(int fd, int speed,
                            int parity, int data_bits, int stop_bits)
{
    struct termios tty;
    speed_t spd;

#if 0
    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
           speed, parity, data_bits, stop_bits);
#endif
    tcgetattr (fd, &tty);

1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548
#define check_speed(val) if (speed <= val) { spd = B##val; break; }
    speed = speed * 10 / 11;
    do {
        check_speed(50);
        check_speed(75);
        check_speed(110);
        check_speed(134);
        check_speed(150);
        check_speed(200);
        check_speed(300);
        check_speed(600);
        check_speed(1200);
        check_speed(1800);
        check_speed(2400);
        check_speed(4800);
        check_speed(9600);
        check_speed(19200);
        check_speed(38400);
        /* Non-Posix values follow. They may be unsupported on some systems. */
        check_speed(57600);
        check_speed(115200);
#ifdef B230400
        check_speed(230400);
#endif
#ifdef B460800
        check_speed(460800);
#endif
#ifdef B500000
        check_speed(500000);
#endif
#ifdef B576000
        check_speed(576000);
#endif
#ifdef B921600
        check_speed(921600);
#endif
#ifdef B1000000
        check_speed(1000000);
#endif
#ifdef B1152000
        check_speed(1152000);
#endif
#ifdef B1500000
        check_speed(1500000);
#endif
#ifdef B2000000
        check_speed(2000000);
#endif
#ifdef B2500000
        check_speed(2500000);
#endif
#ifdef B3000000
        check_speed(3000000);
#endif
#ifdef B3500000
        check_speed(3500000);
#endif
#ifdef B4000000
        check_speed(4000000);
#endif
A
aliguori 已提交
1549
        spd = B115200;
1550
    } while (0);
A
aliguori 已提交
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594

    cfsetispeed(&tty, spd);
    cfsetospeed(&tty, spd);

    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                          |INLCR|IGNCR|ICRNL|IXON);
    tty.c_oflag |= OPOST;
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
    switch(data_bits) {
    default:
    case 8:
        tty.c_cflag |= CS8;
        break;
    case 7:
        tty.c_cflag |= CS7;
        break;
    case 6:
        tty.c_cflag |= CS6;
        break;
    case 5:
        tty.c_cflag |= CS5;
        break;
    }
    switch(parity) {
    default:
    case 'N':
        break;
    case 'E':
        tty.c_cflag |= PARENB;
        break;
    case 'O':
        tty.c_cflag |= PARENB | PARODD;
        break;
    }
    if (stop_bits == 2)
        tty.c_cflag |= CSTOPB;

    tcsetattr (fd, TCSANOW, &tty);
}

static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
{
    FDCharDriver *s = chr->opaque;
1595
    QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc_in);
A
aliguori 已提交
1596 1597 1598 1599 1600

    switch(cmd) {
    case CHR_IOCTL_SERIAL_SET_PARAMS:
        {
            QEMUSerialSetParams *ssp = arg;
1601
            tty_serial_init(fioc->fd,
1602
                            ssp->speed, ssp->parity,
A
aliguori 已提交
1603 1604 1605 1606 1607 1608
                            ssp->data_bits, ssp->stop_bits);
        }
        break;
    case CHR_IOCTL_SERIAL_SET_BREAK:
        {
            int enable = *(int *)arg;
1609
            if (enable) {
1610
                tcsendbreak(fioc->fd, 1);
1611
            }
A
aliguori 已提交
1612 1613 1614 1615 1616 1617
        }
        break;
    case CHR_IOCTL_SERIAL_GET_TIOCM:
        {
            int sarg = 0;
            int *targ = (int *)arg;
1618
            ioctl(fioc->fd, TIOCMGET, &sarg);
A
aliguori 已提交
1619
            *targ = 0;
A
aurel32 已提交
1620
            if (sarg & TIOCM_CTS)
A
aliguori 已提交
1621
                *targ |= CHR_TIOCM_CTS;
A
aurel32 已提交
1622
            if (sarg & TIOCM_CAR)
A
aliguori 已提交
1623
                *targ |= CHR_TIOCM_CAR;
A
aurel32 已提交
1624
            if (sarg & TIOCM_DSR)
A
aliguori 已提交
1625
                *targ |= CHR_TIOCM_DSR;
A
aurel32 已提交
1626
            if (sarg & TIOCM_RI)
A
aliguori 已提交
1627
                *targ |= CHR_TIOCM_RI;
A
aurel32 已提交
1628
            if (sarg & TIOCM_DTR)
A
aliguori 已提交
1629
                *targ |= CHR_TIOCM_DTR;
A
aurel32 已提交
1630
            if (sarg & TIOCM_RTS)
A
aliguori 已提交
1631 1632 1633 1634 1635 1636 1637
                *targ |= CHR_TIOCM_RTS;
        }
        break;
    case CHR_IOCTL_SERIAL_SET_TIOCM:
        {
            int sarg = *(int *)arg;
            int targ = 0;
1638
            ioctl(fioc->fd, TIOCMGET, &targ);
A
aurel32 已提交
1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
            targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
                     | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
            if (sarg & CHR_TIOCM_CTS)
                targ |= TIOCM_CTS;
            if (sarg & CHR_TIOCM_CAR)
                targ |= TIOCM_CAR;
            if (sarg & CHR_TIOCM_DSR)
                targ |= TIOCM_DSR;
            if (sarg & CHR_TIOCM_RI)
                targ |= TIOCM_RI;
            if (sarg & CHR_TIOCM_DTR)
A
aliguori 已提交
1650
                targ |= TIOCM_DTR;
A
aurel32 已提交
1651
            if (sarg & CHR_TIOCM_RTS)
A
aliguori 已提交
1652
                targ |= TIOCM_RTS;
1653
            ioctl(fioc->fd, TIOCMSET, &targ);
A
aliguori 已提交
1654 1655 1656 1657 1658 1659 1660 1661
        }
        break;
    default:
        return -ENOTSUP;
    }
    return 0;
}

1662 1663 1664 1665 1666
static void qemu_chr_close_tty(CharDriverState *chr)
{
    fd_chr_close(chr);
}

1667 1668 1669
static CharDriverState *qemu_chr_open_tty_fd(int fd,
                                             ChardevCommon *backend,
                                             Error **errp)
1670 1671 1672 1673
{
    CharDriverState *chr;

    tty_serial_init(fd, 115200, 'N', 8, 1);
1674
    chr = qemu_chr_open_fd(fd, fd, backend, errp);
1675 1676 1677 1678
    chr->chr_ioctl = tty_serial_ioctl;
    chr->chr_close = qemu_chr_close_tty;
    return chr;
}
A
aliguori 已提交
1679 1680 1681
#endif /* __linux__ || __sun__ */

#if defined(__linux__)
1682 1683 1684

#define HAVE_CHARDEV_PARPORT 1

A
aliguori 已提交
1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789
typedef struct {
    int fd;
    int mode;
} ParallelCharDriver;

static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
{
    if (s->mode != mode) {
	int m = mode;
        if (ioctl(s->fd, PPSETMODE, &m) < 0)
            return 0;
	s->mode = mode;
    }
    return 1;
}

static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
{
    ParallelCharDriver *drv = chr->opaque;
    int fd = drv->fd;
    uint8_t b;

    switch(cmd) {
    case CHR_IOCTL_PP_READ_DATA:
        if (ioctl(fd, PPRDATA, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    case CHR_IOCTL_PP_WRITE_DATA:
        b = *(uint8_t *)arg;
        if (ioctl(fd, PPWDATA, &b) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_CONTROL:
        if (ioctl(fd, PPRCONTROL, &b) < 0)
            return -ENOTSUP;
	/* Linux gives only the lowest bits, and no way to know data
	   direction! For better compatibility set the fixed upper
	   bits. */
        *(uint8_t *)arg = b | 0xc0;
        break;
    case CHR_IOCTL_PP_WRITE_CONTROL:
        b = *(uint8_t *)arg;
        if (ioctl(fd, PPWCONTROL, &b) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_STATUS:
        if (ioctl(fd, PPRSTATUS, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    case CHR_IOCTL_PP_DATA_DIR:
        if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_EPP_READ_ADDR:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
	    struct ParallelIOArg *parg = arg;
	    int n = read(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    case CHR_IOCTL_PP_EPP_READ:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
	    struct ParallelIOArg *parg = arg;
	    int n = read(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    case CHR_IOCTL_PP_EPP_WRITE_ADDR:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
	    struct ParallelIOArg *parg = arg;
	    int n = write(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    case CHR_IOCTL_PP_EPP_WRITE:
	if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
	    struct ParallelIOArg *parg = arg;
	    int n = write(fd, parg->buffer, parg->count);
	    if (n != parg->count) {
		return -EIO;
	    }
	}
        break;
    default:
        return -ENOTSUP;
    }
    return 0;
}

static void pp_close(CharDriverState *chr)
{
    ParallelCharDriver *drv = chr->opaque;
    int fd = drv->fd;

    pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
    ioctl(fd, PPRELEASE);
    close(fd);
1790
    g_free(drv);
1791
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
A
aliguori 已提交
1792 1793
}

1794 1795 1796
static CharDriverState *qemu_chr_open_pp_fd(int fd,
                                            ChardevCommon *backend,
                                            Error **errp)
A
aliguori 已提交
1797 1798 1799 1800 1801
{
    CharDriverState *chr;
    ParallelCharDriver *drv;

    if (ioctl(fd, PPCLAIM) < 0) {
1802
        error_setg_errno(errp, errno, "not a parallel port");
A
aliguori 已提交
1803
        close(fd);
1804
        return NULL;
A
aliguori 已提交
1805 1806
    }

1807 1808 1809 1810
    chr = qemu_chr_alloc(backend, errp);
    if (!chr) {
        return NULL;
    }
1811 1812 1813

    drv = g_new0(ParallelCharDriver, 1);
    chr->opaque = drv;
A
aliguori 已提交
1814 1815 1816
    chr->chr_write = null_chr_write;
    chr->chr_ioctl = pp_ioctl;
    chr->chr_close = pp_close;
1817 1818 1819

    drv->fd = fd;
    drv->mode = IEEE1284_MODE_COMPAT;
A
aliguori 已提交
1820

1821
    return chr;
A
aliguori 已提交
1822 1823 1824
}
#endif /* __linux__ */

A
Aurelien Jarno 已提交
1825
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1826 1827 1828

#define HAVE_CHARDEV_PARPORT 1

1829 1830
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
{
1831
    int fd = (int)(intptr_t)chr->opaque;
1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865
    uint8_t b;

    switch(cmd) {
    case CHR_IOCTL_PP_READ_DATA:
        if (ioctl(fd, PPIGDATA, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    case CHR_IOCTL_PP_WRITE_DATA:
        b = *(uint8_t *)arg;
        if (ioctl(fd, PPISDATA, &b) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_CONTROL:
        if (ioctl(fd, PPIGCTRL, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    case CHR_IOCTL_PP_WRITE_CONTROL:
        b = *(uint8_t *)arg;
        if (ioctl(fd, PPISCTRL, &b) < 0)
            return -ENOTSUP;
        break;
    case CHR_IOCTL_PP_READ_STATUS:
        if (ioctl(fd, PPIGSTATUS, &b) < 0)
            return -ENOTSUP;
        *(uint8_t *)arg = b;
        break;
    default:
        return -ENOTSUP;
    }
    return 0;
}

1866
static CharDriverState *qemu_chr_open_pp_fd(int fd,
1867
                                            ChardevCommon *backend,
1868
                                            Error **errp)
1869 1870 1871
{
    CharDriverState *chr;

1872
    chr = qemu_chr_alloc(backend, errp);
1873 1874 1875
    if (!chr) {
        return NULL;
    }
1876
    chr->opaque = (void *)(intptr_t)fd;
1877 1878
    chr->chr_write = null_chr_write;
    chr->chr_ioctl = pp_ioctl;
1879
    chr->explicit_be_open = true;
1880
    return chr;
1881 1882 1883
}
#endif

A
aliguori 已提交
1884 1885
#else /* _WIN32 */

P
Paolo Bonzini 已提交
1886 1887
#define HAVE_CHARDEV_SERIAL 1

A
aliguori 已提交
1888 1889 1890
typedef struct {
    int max_size;
    HANDLE hcom, hrecv, hsend;
1891
    OVERLAPPED orecv;
A
aliguori 已提交
1892 1893
    BOOL fpipe;
    DWORD len;
1894 1895 1896

    /* Protected by the CharDriverState chr_write_lock.  */
    OVERLAPPED osend;
A
aliguori 已提交
1897 1898
} WinCharState;

F
Fabien Chouteau 已提交
1899 1900 1901 1902 1903 1904 1905 1906
typedef struct {
    HANDLE  hStdIn;
    HANDLE  hInputReadyEvent;
    HANDLE  hInputDoneEvent;
    HANDLE  hInputThread;
    uint8_t win_stdio_buf;
} WinStdioCharState;

A
aliguori 已提交
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934
#define NSENDBUF 2048
#define NRECVBUF 2048
#define MAXCONNECT 1
#define NTIMEOUT 5000

static int win_chr_poll(void *opaque);
static int win_chr_pipe_poll(void *opaque);

static void win_chr_close(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;

    if (s->hsend) {
        CloseHandle(s->hsend);
        s->hsend = NULL;
    }
    if (s->hrecv) {
        CloseHandle(s->hrecv);
        s->hrecv = NULL;
    }
    if (s->hcom) {
        CloseHandle(s->hcom);
        s->hcom = NULL;
    }
    if (s->fpipe)
        qemu_del_polling_cb(win_chr_pipe_poll, chr);
    else
        qemu_del_polling_cb(win_chr_poll, chr);
1935

1936
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
A
aliguori 已提交
1937 1938
}

1939
static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp)
A
aliguori 已提交
1940 1941 1942 1943 1944 1945 1946 1947 1948 1949
{
    WinCharState *s = chr->opaque;
    COMMCONFIG comcfg;
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
    COMSTAT comstat;
    DWORD size;
    DWORD err;

    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hsend) {
1950
        error_setg(errp, "Failed CreateEvent");
A
aliguori 已提交
1951 1952 1953 1954
        goto fail;
    }
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hrecv) {
1955
        error_setg(errp, "Failed CreateEvent");
A
aliguori 已提交
1956 1957 1958 1959 1960 1961
        goto fail;
    }

    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
    if (s->hcom == INVALID_HANDLE_VALUE) {
1962
        error_setg(errp, "Failed CreateFile (%lu)", GetLastError());
A
aliguori 已提交
1963 1964 1965 1966 1967
        s->hcom = NULL;
        goto fail;
    }

    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
1968
        error_setg(errp, "Failed SetupComm");
A
aliguori 已提交
1969 1970 1971 1972 1973 1974 1975 1976 1977 1978
        goto fail;
    }

    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
    size = sizeof(COMMCONFIG);
    GetDefaultCommConfig(filename, &comcfg, &size);
    comcfg.dcb.DCBlength = sizeof(DCB);
    CommConfigDialog(filename, NULL, &comcfg);

    if (!SetCommState(s->hcom, &comcfg.dcb)) {
1979
        error_setg(errp, "Failed SetCommState");
A
aliguori 已提交
1980 1981 1982 1983
        goto fail;
    }

    if (!SetCommMask(s->hcom, EV_ERR)) {
1984
        error_setg(errp, "Failed SetCommMask");
A
aliguori 已提交
1985 1986 1987 1988 1989
        goto fail;
    }

    cto.ReadIntervalTimeout = MAXDWORD;
    if (!SetCommTimeouts(s->hcom, &cto)) {
1990
        error_setg(errp, "Failed SetCommTimeouts");
A
aliguori 已提交
1991 1992 1993 1994
        goto fail;
    }

    if (!ClearCommError(s->hcom, &err, &comstat)) {
1995
        error_setg(errp, "Failed ClearCommError");
A
aliguori 已提交
1996 1997 1998 1999 2000 2001 2002 2003 2004 2005
        goto fail;
    }
    qemu_add_polling_cb(win_chr_poll, chr);
    return 0;

 fail:
    win_chr_close(chr);
    return -1;
}

2006
/* Called with chr_write_lock held.  */
A
aliguori 已提交
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044
static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
{
    WinCharState *s = chr->opaque;
    DWORD len, ret, size, err;

    len = len1;
    ZeroMemory(&s->osend, sizeof(s->osend));
    s->osend.hEvent = s->hsend;
    while (len > 0) {
        if (s->hsend)
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
        else
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
        if (!ret) {
            err = GetLastError();
            if (err == ERROR_IO_PENDING) {
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
                if (ret) {
                    buf += size;
                    len -= size;
                } else {
                    break;
                }
            } else {
                break;
            }
        } else {
            buf += size;
            len -= size;
        }
    }
    return len1 - len;
}

static int win_chr_read_poll(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;

2045
    s->max_size = qemu_chr_be_can_write(chr);
A
aliguori 已提交
2046 2047 2048 2049 2050 2051 2052
    return s->max_size;
}

static void win_chr_readfile(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;
    int ret, err;
2053
    uint8_t buf[READ_BUF_LEN];
A
aliguori 已提交
2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066
    DWORD size;

    ZeroMemory(&s->orecv, sizeof(s->orecv));
    s->orecv.hEvent = s->hrecv;
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
    if (!ret) {
        err = GetLastError();
        if (err == ERROR_IO_PENDING) {
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
        }
    }

    if (size > 0) {
2067
        qemu_chr_be_write(chr, buf, size);
A
aliguori 已提交
2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
    }
}

static void win_chr_read(CharDriverState *chr)
{
    WinCharState *s = chr->opaque;

    if (s->len > s->max_size)
        s->len = s->max_size;
    if (s->len == 0)
        return;

    win_chr_readfile(chr);
}

static int win_chr_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    WinCharState *s = chr->opaque;
    COMSTAT status;
    DWORD comerr;

    ClearCommError(s->hcom, &comerr, &status);
    if (status.cbInQue > 0) {
        s->len = status.cbInQue;
        win_chr_read_poll(chr);
        win_chr_read(chr);
        return 1;
    }
    return 0;
}

2100
static CharDriverState *qemu_chr_open_win_path(const char *filename,
2101
                                               ChardevCommon *backend,
2102
                                               Error **errp)
A
aliguori 已提交
2103 2104 2105 2106
{
    CharDriverState *chr;
    WinCharState *s;

2107 2108 2109 2110
    chr = qemu_chr_alloc(backend, errp);
    if (!chr) {
        return NULL;
    }
2111
    s = g_new0(WinCharState, 1);
A
aliguori 已提交
2112 2113 2114 2115
    chr->opaque = s;
    chr->chr_write = win_chr_write;
    chr->chr_close = win_chr_close;

2116
    if (win_chr_init(chr, filename, errp) < 0) {
2117
        g_free(s);
2118
        qemu_chr_free_common(chr);
2119
        return NULL;
A
aliguori 已提交
2120
    }
2121
    return chr;
A
aliguori 已提交
2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
}

static int win_chr_pipe_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    WinCharState *s = chr->opaque;
    DWORD size;

    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
    if (size > 0) {
        s->len = size;
        win_chr_read_poll(chr);
        win_chr_read(chr);
        return 1;
    }
    return 0;
}

2140 2141
static int win_chr_pipe_init(CharDriverState *chr, const char *filename,
                             Error **errp)
A
aliguori 已提交
2142 2143 2144 2145 2146
{
    WinCharState *s = chr->opaque;
    OVERLAPPED ov;
    int ret;
    DWORD size;
2147
    char *openname;
A
aliguori 已提交
2148 2149 2150 2151 2152

    s->fpipe = TRUE;

    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hsend) {
2153
        error_setg(errp, "Failed CreateEvent");
A
aliguori 已提交
2154 2155 2156 2157
        goto fail;
    }
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!s->hrecv) {
2158
        error_setg(errp, "Failed CreateEvent");
A
aliguori 已提交
2159 2160 2161
        goto fail;
    }

2162
    openname = g_strdup_printf("\\\\.\\pipe\\%s", filename);
A
aliguori 已提交
2163 2164 2165 2166
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
                              PIPE_WAIT,
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
2167
    g_free(openname);
A
aliguori 已提交
2168
    if (s->hcom == INVALID_HANDLE_VALUE) {
2169
        error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError());
A
aliguori 已提交
2170 2171 2172 2173 2174 2175 2176 2177
        s->hcom = NULL;
        goto fail;
    }

    ZeroMemory(&ov, sizeof(ov));
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    ret = ConnectNamedPipe(s->hcom, &ov);
    if (ret) {
2178
        error_setg(errp, "Failed ConnectNamedPipe");
A
aliguori 已提交
2179 2180 2181 2182 2183
        goto fail;
    }

    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
    if (!ret) {
2184
        error_setg(errp, "Failed GetOverlappedResult");
A
aliguori 已提交
2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204
        if (ov.hEvent) {
            CloseHandle(ov.hEvent);
            ov.hEvent = NULL;
        }
        goto fail;
    }

    if (ov.hEvent) {
        CloseHandle(ov.hEvent);
        ov.hEvent = NULL;
    }
    qemu_add_polling_cb(win_chr_pipe_poll, chr);
    return 0;

 fail:
    win_chr_close(chr);
    return -1;
}


2205 2206 2207 2208
static CharDriverState *qemu_chr_open_pipe(const char *id,
                                           ChardevBackend *backend,
                                           ChardevReturn *ret,
                                           Error **errp)
A
aliguori 已提交
2209
{
2210
    ChardevHostdev *opts = backend->u.pipe.data;
2211
    const char *filename = opts->device;
A
aliguori 已提交
2212 2213
    CharDriverState *chr;
    WinCharState *s;
2214
    ChardevCommon *common = qapi_ChardevHostdev_base(opts);
A
aliguori 已提交
2215

2216 2217 2218 2219
    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
        return NULL;
    }
2220
    s = g_new0(WinCharState, 1);
A
aliguori 已提交
2221 2222 2223 2224
    chr->opaque = s;
    chr->chr_write = win_chr_write;
    chr->chr_close = win_chr_close;

2225
    if (win_chr_pipe_init(chr, filename, errp) < 0) {
2226
        g_free(s);
2227
        qemu_chr_free_common(chr);
2228
        return NULL;
A
aliguori 已提交
2229
    }
2230
    return chr;
A
aliguori 已提交
2231 2232
}

2233 2234 2235
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out,
                                               ChardevCommon *backend,
                                               Error **errp)
A
aliguori 已提交
2236 2237 2238 2239
{
    CharDriverState *chr;
    WinCharState *s;

2240 2241 2242 2243
    chr = qemu_chr_alloc(backend, errp);
    if (!chr) {
        return NULL;
    }
2244
    s = g_new0(WinCharState, 1);
A
aliguori 已提交
2245 2246 2247
    s->hcom = fd_out;
    chr->opaque = s;
    chr->chr_write = win_chr_write;
2248
    return chr;
A
aliguori 已提交
2249 2250
}

2251 2252 2253 2254
static CharDriverState *qemu_chr_open_win_con(const char *id,
                                              ChardevBackend *backend,
                                              ChardevReturn *ret,
                                              Error **errp)
A
aliguori 已提交
2255
{
2256
    ChardevCommon *common = backend->u.console.data;
2257 2258
    return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE),
                                  common, errp);
A
aliguori 已提交
2259 2260
}

F
Fabien Chouteau 已提交
2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288
static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    HANDLE  hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD   dwSize;
    int     len1;

    len1 = len;

    while (len1 > 0) {
        if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
            break;
        }
        buf  += dwSize;
        len1 -= dwSize;
    }

    return len - len1;
}

static void win_stdio_wait_func(void *opaque)
{
    CharDriverState   *chr   = opaque;
    WinStdioCharState *stdio = chr->opaque;
    INPUT_RECORD       buf[4];
    int                ret;
    DWORD              dwSize;
    int                i;

2289
    ret = ReadConsoleInput(stdio->hStdIn, buf, ARRAY_SIZE(buf), &dwSize);
F
Fabien Chouteau 已提交
2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396

    if (!ret) {
        /* Avoid error storm */
        qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
        return;
    }

    for (i = 0; i < dwSize; i++) {
        KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;

        if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
            int j;
            if (kev->uChar.AsciiChar != 0) {
                for (j = 0; j < kev->wRepeatCount; j++) {
                    if (qemu_chr_be_can_write(chr)) {
                        uint8_t c = kev->uChar.AsciiChar;
                        qemu_chr_be_write(chr, &c, 1);
                    }
                }
            }
        }
    }
}

static DWORD WINAPI win_stdio_thread(LPVOID param)
{
    CharDriverState   *chr   = param;
    WinStdioCharState *stdio = chr->opaque;
    int                ret;
    DWORD              dwSize;

    while (1) {

        /* Wait for one byte */
        ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);

        /* Exit in case of error, continue if nothing read */
        if (!ret) {
            break;
        }
        if (!dwSize) {
            continue;
        }

        /* Some terminal emulator returns \r\n for Enter, just pass \n */
        if (stdio->win_stdio_buf == '\r') {
            continue;
        }

        /* Signal the main thread and wait until the byte was eaten */
        if (!SetEvent(stdio->hInputReadyEvent)) {
            break;
        }
        if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
            != WAIT_OBJECT_0) {
            break;
        }
    }

    qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
    return 0;
}

static void win_stdio_thread_wait_func(void *opaque)
{
    CharDriverState   *chr   = opaque;
    WinStdioCharState *stdio = chr->opaque;

    if (qemu_chr_be_can_write(chr)) {
        qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
    }

    SetEvent(stdio->hInputDoneEvent);
}

static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo)
{
    WinStdioCharState *stdio  = chr->opaque;
    DWORD              dwMode = 0;

    GetConsoleMode(stdio->hStdIn, &dwMode);

    if (echo) {
        SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
    } else {
        SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
    }
}

static void win_stdio_close(CharDriverState *chr)
{
    WinStdioCharState *stdio = chr->opaque;

    if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
        CloseHandle(stdio->hInputReadyEvent);
    }
    if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
        CloseHandle(stdio->hInputDoneEvent);
    }
    if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
        TerminateThread(stdio->hInputThread, 0);
    }

    g_free(chr->opaque);
    g_free(chr);
}

2397 2398 2399 2400
static CharDriverState *qemu_chr_open_stdio(const char *id,
                                            ChardevBackend *backend,
                                            ChardevReturn *ret,
                                            Error **errp)
F
Fabien Chouteau 已提交
2401 2402 2403 2404 2405
{
    CharDriverState   *chr;
    WinStdioCharState *stdio;
    DWORD              dwMode;
    int                is_console = 0;
2406
    ChardevCommon *common = qapi_ChardevStdio_base(backend->u.stdio.data);
F
Fabien Chouteau 已提交
2407

2408 2409 2410 2411
    chr   = qemu_chr_alloc(common, errp);
    if (!chr) {
        return NULL;
    }
2412
    stdio = g_new0(WinStdioCharState, 1);
F
Fabien Chouteau 已提交
2413 2414 2415

    stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
2416 2417
        error_setg(errp, "cannot open stdio: invalid handle");
        return NULL;
F
Fabien Chouteau 已提交
2418 2419 2420 2421 2422 2423 2424 2425
    }

    is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;

    chr->opaque    = stdio;
    chr->chr_write = win_stdio_write;
    chr->chr_close = win_stdio_close;

2426 2427 2428
    if (is_console) {
        if (qemu_add_wait_object(stdio->hStdIn,
                                 win_stdio_wait_func, chr)) {
2429 2430
            error_setg(errp, "qemu_add_wait_object: failed");
            goto err1;
2431 2432 2433 2434 2435 2436
        }
    } else {
        DWORD   dwId;
            
        stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        stdio->hInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
2437
        if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
2438
            || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
2439 2440
            error_setg(errp, "cannot create event");
            goto err2;
2441 2442 2443
        }
        if (qemu_add_wait_object(stdio->hInputReadyEvent,
                                 win_stdio_thread_wait_func, chr)) {
2444 2445 2446 2447 2448 2449 2450 2451 2452
            error_setg(errp, "qemu_add_wait_object: failed");
            goto err2;
        }
        stdio->hInputThread     = CreateThread(NULL, 0, win_stdio_thread,
                                               chr, 0, &dwId);

        if (stdio->hInputThread == INVALID_HANDLE_VALUE) {
            error_setg(errp, "cannot create stdio thread");
            goto err3;
F
Fabien Chouteau 已提交
2453 2454 2455 2456 2457
        }
    }

    dwMode |= ENABLE_LINE_INPUT;

2458
    if (is_console) {
F
Fabien Chouteau 已提交
2459 2460 2461 2462 2463 2464 2465 2466 2467 2468
        /* set the terminal in raw mode */
        /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
        dwMode |= ENABLE_PROCESSED_INPUT;
    }

    SetConsoleMode(stdio->hStdIn, dwMode);

    chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
    qemu_chr_fe_set_echo(chr, false);

2469
    return chr;
2470 2471 2472 2473 2474 2475 2476 2477 2478

err3:
    qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
err2:
    CloseHandle(stdio->hInputReadyEvent);
    CloseHandle(stdio->hInputDoneEvent);
err1:
    qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
    return NULL;
F
Fabien Chouteau 已提交
2479
}
A
aliguori 已提交
2480 2481
#endif /* !_WIN32 */

2482

A
aliguori 已提交
2483 2484 2485 2486
/***********************************************************/
/* UDP Net console */

typedef struct {
2487
    QIOChannel *ioc;
2488
    uint8_t buf[READ_BUF_LEN];
A
aliguori 已提交
2489 2490 2491 2492 2493
    int bufcnt;
    int bufptr;
    int max_size;
} NetCharDriver;

2494
/* Called with chr_write_lock held.  */
A
aliguori 已提交
2495 2496 2497
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    NetCharDriver *s = chr->opaque;
2498

2499 2500
    return qio_channel_write(
        s->ioc, (const char *)buf, len, NULL);
A
aliguori 已提交
2501 2502 2503 2504 2505 2506 2507
}

static int udp_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    NetCharDriver *s = chr->opaque;

2508
    s->max_size = qemu_chr_be_can_write(chr);
A
aliguori 已提交
2509 2510 2511 2512 2513

    /* If there were any stray characters in the queue process them
     * first
     */
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2514
        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
A
aliguori 已提交
2515
        s->bufptr++;
2516
        s->max_size = qemu_chr_be_can_write(chr);
A
aliguori 已提交
2517 2518 2519 2520
    }
    return s->max_size;
}

2521
static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
A
aliguori 已提交
2522 2523 2524
{
    CharDriverState *chr = opaque;
    NetCharDriver *s = chr->opaque;
2525
    ssize_t ret;
A
aliguori 已提交
2526

2527 2528 2529
    if (s->max_size == 0) {
        return TRUE;
    }
2530 2531 2532
    ret = qio_channel_read(
        s->ioc, (char *)s->buf, sizeof(s->buf), NULL);
    if (ret <= 0) {
2533
        remove_fd_in_watch(chr);
2534 2535
        return FALSE;
    }
2536
    s->bufcnt = ret;
A
aliguori 已提交
2537 2538 2539

    s->bufptr = 0;
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2540
        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
A
aliguori 已提交
2541
        s->bufptr++;
2542
        s->max_size = qemu_chr_be_can_write(chr);
A
aliguori 已提交
2543
    }
2544 2545

    return TRUE;
A
aliguori 已提交
2546 2547 2548 2549 2550 2551
}

static void udp_chr_update_read_handler(CharDriverState *chr)
{
    NetCharDriver *s = chr->opaque;

2552
    remove_fd_in_watch(chr);
2553 2554 2555
    if (s->ioc) {
        chr->fd_in_tag = io_add_watch_poll(s->ioc,
                                           udp_chr_read_poll,
2556
                                           udp_chr_read, chr);
A
aliguori 已提交
2557 2558 2559
    }
}

2560 2561 2562
static void udp_chr_close(CharDriverState *chr)
{
    NetCharDriver *s = chr->opaque;
2563 2564

    remove_fd_in_watch(chr);
2565 2566
    if (s->ioc) {
        object_unref(OBJECT(s->ioc));
2567
    }
2568
    g_free(s);
2569
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
2570 2571
}

2572 2573 2574
static CharDriverState *qemu_chr_open_udp(QIOChannelSocket *sioc,
                                          ChardevCommon *backend,
                                          Error **errp)
A
aliguori 已提交
2575 2576 2577 2578
{
    CharDriverState *chr = NULL;
    NetCharDriver *s = NULL;

2579 2580 2581 2582
    chr = qemu_chr_alloc(backend, errp);
    if (!chr) {
        return NULL;
    }
2583
    s = g_new0(NetCharDriver, 1);
A
aliguori 已提交
2584

2585
    s->ioc = QIO_CHANNEL(sioc);
A
aliguori 已提交
2586 2587 2588 2589 2590
    s->bufcnt = 0;
    s->bufptr = 0;
    chr->opaque = s;
    chr->chr_write = udp_chr_write;
    chr->chr_update_read_handler = udp_chr_update_read_handler;
2591
    chr->chr_close = udp_chr_close;
2592 2593
    /* be isn't opened until we get a connection */
    chr->explicit_be_open = true;
2594
    return chr;
G
Gerd Hoffmann 已提交
2595
}
A
aliguori 已提交
2596 2597 2598 2599 2600

/***********************************************************/
/* TCP Net console */

typedef struct {
2601 2602
    QIOChannel *ioc; /* Client I/O channel */
    QIOChannelSocket *sioc; /* Client master channel */
2603
    QIOChannelSocket *listen_ioc;
2604
    guint listen_tag;
2605
    QCryptoTLSCreds *tls_creds;
A
aliguori 已提交
2606 2607 2608 2609 2610
    int connected;
    int max_size;
    int do_telnetopt;
    int do_nodelay;
    int is_unix;
2611
    int *read_msgfds;
2612
    size_t read_msgfds_num;
2613
    int *write_msgfds;
2614
    size_t write_msgfds_num;
2615 2616 2617 2618

    SocketAddress *addr;
    bool is_listen;
    bool is_telnet;
2619 2620 2621

    guint reconnect_timer;
    int64_t reconnect_time;
2622
    bool connect_err_reported;
A
aliguori 已提交
2623 2624
} TCPCharDriver;

2625 2626 2627 2628 2629 2630 2631 2632 2633 2634
static gboolean socket_reconnect_timeout(gpointer opaque);

static void qemu_chr_socket_restart_timer(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;
    assert(s->connected == 0);
    s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
                                               socket_reconnect_timeout, chr);
}

2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
static void check_report_connect_error(CharDriverState *chr,
                                       Error *err)
{
    TCPCharDriver *s = chr->opaque;

    if (!s->connect_err_reported) {
        error_report("Unable to connect character device %s: %s",
                     chr->label, error_get_pretty(err));
        s->connect_err_reported = true;
    }
    qemu_chr_socket_restart_timer(chr);
}

2648 2649 2650
static gboolean tcp_chr_accept(QIOChannel *chan,
                               GIOCondition cond,
                               void *opaque);
2651

2652
/* Called with chr_write_lock held.  */
A
aliguori 已提交
2653 2654 2655 2656
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
    TCPCharDriver *s = chr->opaque;
    if (s->connected) {
2657 2658 2659 2660 2661 2662 2663 2664 2665
        int ret =  io_channel_send_full(s->ioc, buf, len,
                                        s->write_msgfds,
                                        s->write_msgfds_num);

        /* free the written msgfds, no matter what */
        if (s->write_msgfds_num) {
            g_free(s->write_msgfds);
            s->write_msgfds = 0;
            s->write_msgfds_num = 0;
2666
        }
2667 2668

        return ret;
2669
    } else {
2670
        /* XXX: indicate an error ? */
2671
        return len;
A
aliguori 已提交
2672 2673 2674 2675 2676 2677 2678 2679 2680
    }
}

static int tcp_chr_read_poll(void *opaque)
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;
    if (!s->connected)
        return 0;
2681
    s->max_size = qemu_chr_be_can_write(chr);
A
aliguori 已提交
2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713
    return s->max_size;
}

#define IAC 255
#define IAC_BREAK 243
static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
                                      TCPCharDriver *s,
                                      uint8_t *buf, int *size)
{
    /* Handle any telnet client's basic IAC options to satisfy char by
     * char mode with no echo.  All IAC options will be removed from
     * the buf and the do_telnetopt variable will be used to track the
     * state of the width of the IAC information.
     *
     * IAC commands come in sets of 3 bytes with the exception of the
     * "IAC BREAK" command and the double IAC.
     */

    int i;
    int j = 0;

    for (i = 0; i < *size; i++) {
        if (s->do_telnetopt > 1) {
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
                /* Double IAC means send an IAC */
                if (j != i)
                    buf[j] = buf[i];
                j++;
                s->do_telnetopt = 1;
            } else {
                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
                    /* Handle IAC break commands by sending a serial break */
2714
                    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
A
aliguori 已提交
2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734
                    s->do_telnetopt++;
                }
                s->do_telnetopt++;
            }
            if (s->do_telnetopt >= 4) {
                s->do_telnetopt = 1;
            }
        } else {
            if ((unsigned char)buf[i] == IAC) {
                s->do_telnetopt = 2;
            } else {
                if (j != i)
                    buf[j] = buf[i];
                j++;
            }
        }
    }
    *size = j;
}

2735
static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num)
2736 2737
{
    TCPCharDriver *s = chr->opaque;
2738 2739
    int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;

M
Michael S. Tsirkin 已提交
2740 2741
    assert(num <= TCP_MAX_FDS);

2742
    if (to_copy) {
2743 2744
        int i;

2745 2746
        memcpy(fds, s->read_msgfds, to_copy * sizeof(int));

2747 2748 2749 2750 2751
        /* Close unused fds */
        for (i = to_copy; i < s->read_msgfds_num; i++) {
            close(s->read_msgfds[i]);
        }

2752 2753 2754 2755 2756 2757
        g_free(s->read_msgfds);
        s->read_msgfds = 0;
        s->read_msgfds_num = 0;
    }

    return to_copy;
2758 2759
}

2760 2761 2762 2763
static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num)
{
    TCPCharDriver *s = chr->opaque;

2764 2765 2766 2767
    if (!qio_channel_has_feature(s->ioc,
                                 QIO_CHANNEL_FEATURE_FD_PASS)) {
        return -1;
    }
2768
    /* clear old pending fd array */
2769
    g_free(s->write_msgfds);
2770
    s->write_msgfds = NULL;
2771 2772

    if (num) {
2773
        s->write_msgfds = g_new(int, num);
2774 2775 2776 2777 2778 2779 2780 2781
        memcpy(s->write_msgfds, fds, num * sizeof(int));
    }

    s->write_msgfds_num = num;

    return 0;
}

2782
static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2783 2784
{
    TCPCharDriver *s = chr->opaque;
2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799
    struct iovec iov = { .iov_base = buf, .iov_len = len };
    int ret;
    size_t i;
    int *msgfds = NULL;
    size_t msgfds_num = 0;

    if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
        ret = qio_channel_readv_full(s->ioc, &iov, 1,
                                     &msgfds, &msgfds_num,
                                     NULL);
    } else {
        ret = qio_channel_readv_full(s->ioc, &iov, 1,
                                     NULL, NULL,
                                     NULL);
    }
2800

2801 2802 2803 2804 2805 2806 2807
    if (ret == QIO_CHANNEL_ERR_BLOCK) {
        errno = EAGAIN;
        ret = -1;
    } else if (ret == -1) {
        errno = EIO;
    }

2808
    if (msgfds_num) {
2809 2810 2811 2812
        /* close and clean read_msgfds */
        for (i = 0; i < s->read_msgfds_num; i++) {
            close(s->read_msgfds[i]);
        }
2813

2814 2815 2816 2817
        if (s->read_msgfds_num) {
            g_free(s->read_msgfds);
        }

2818 2819
        s->read_msgfds = msgfds;
        s->read_msgfds_num = msgfds_num;
2820 2821
    }

2822 2823 2824 2825 2826
    for (i = 0; i < s->read_msgfds_num; i++) {
        int fd = s->read_msgfds[i];
        if (fd < 0) {
            continue;
        }
2827

2828 2829
        /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
        qemu_set_block(fd);
2830

2831 2832
#ifndef MSG_CMSG_CLOEXEC
        qemu_set_cloexec(fd);
2833 2834
#endif
    }
2835

2836
    return ret;
2837 2838
}

2839 2840 2841
static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{
    TCPCharDriver *s = chr->opaque;
2842
    return qio_channel_create_watch(s->ioc, cond);
2843 2844
}

2845 2846 2847 2848
static void tcp_chr_disconnect(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;

2849 2850 2851 2852
    if (!s->connected) {
        return;
    }

2853
    s->connected = 0;
2854 2855 2856
    if (s->listen_ioc) {
        s->listen_tag = qio_channel_add_watch(
            QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
2857
    }
2858
    tcp_set_msgfds(chr, NULL, 0);
2859
    remove_fd_in_watch(chr);
2860 2861
    object_unref(OBJECT(s->sioc));
    s->sioc = NULL;
2862 2863
    object_unref(OBJECT(s->ioc));
    s->ioc = NULL;
2864 2865 2866
    g_free(chr->filename);
    chr->filename = SocketAddress_to_str("disconnected:", s->addr,
                                         s->is_listen, s->is_telnet);
2867
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
2868 2869 2870
    if (s->reconnect_time) {
        qemu_chr_socket_restart_timer(chr);
    }
2871 2872
}

2873
static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
A
aliguori 已提交
2874 2875 2876
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;
2877
    uint8_t buf[READ_BUF_LEN];
A
aliguori 已提交
2878 2879
    int len, size;

2880
    if (!s->connected || s->max_size <= 0) {
2881
        return TRUE;
2882
    }
A
aliguori 已提交
2883 2884 2885
    len = sizeof(buf);
    if (len > s->max_size)
        len = s->max_size;
2886
    size = tcp_chr_recv(chr, (void *)buf, len);
2887
    if (size == 0 || size == -1) {
A
aliguori 已提交
2888
        /* connection closed */
2889
        tcp_chr_disconnect(chr);
A
aliguori 已提交
2890 2891 2892 2893
    } else if (size > 0) {
        if (s->do_telnetopt)
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
        if (size > 0)
2894
            qemu_chr_be_write(chr, buf, size);
A
aliguori 已提交
2895
    }
2896 2897

    return TRUE;
A
aliguori 已提交
2898 2899
}

2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917
static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len)
{
    TCPCharDriver *s = chr->opaque;
    int size;

    if (!s->connected) {
        return 0;
    }

    size = tcp_chr_recv(chr, (void *) buf, len);
    if (size == 0) {
        /* connection closed */
        tcp_chr_disconnect(chr);
    }

    return size;
}

A
aliguori 已提交
2918 2919 2920 2921
static void tcp_chr_connect(void *opaque)
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;
2922

2923
    g_free(chr->filename);
2924 2925 2926 2927
    chr->filename = sockaddr_to_str(
        &s->sioc->localAddr, s->sioc->localAddrLen,
        &s->sioc->remoteAddr, s->sioc->remoteAddrLen,
        s->is_listen, s->is_telnet);
A
aliguori 已提交
2928 2929

    s->connected = 1;
2930 2931 2932
    if (s->ioc) {
        chr->fd_in_tag = io_add_watch_poll(s->ioc,
                                           tcp_chr_read_poll,
2933
                                           tcp_chr_read, chr);
2934
    }
2935
    qemu_chr_be_generic_open(chr);
A
aliguori 已提交
2936 2937
}

2938 2939 2940 2941
static void tcp_chr_update_read_handler(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;

2942 2943 2944 2945
    if (!s->connected) {
        return;
    }

2946
    remove_fd_in_watch(chr);
2947 2948 2949
    if (s->ioc) {
        chr->fd_in_tag = io_add_watch_poll(s->ioc,
                                           tcp_chr_read_poll,
2950 2951 2952 2953
                                           tcp_chr_read, chr);
    }
}

2954 2955 2956 2957 2958 2959 2960 2961 2962
typedef struct {
    CharDriverState *chr;
    char buf[12];
    size_t buflen;
} TCPCharDriverTelnetInit;

static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
                                       GIOCondition cond G_GNUC_UNUSED,
                                       gpointer user_data)
A
aliguori 已提交
2963
{
2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017
    TCPCharDriverTelnetInit *init = user_data;
    ssize_t ret;

    ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
    if (ret < 0) {
        if (ret == QIO_CHANNEL_ERR_BLOCK) {
            ret = 0;
        } else {
            tcp_chr_disconnect(init->chr);
            return FALSE;
        }
    }
    init->buflen -= ret;

    if (init->buflen == 0) {
        tcp_chr_connect(init->chr);
        return FALSE;
    }

    memmove(init->buf, init->buf + ret, init->buflen);

    return TRUE;
}

static void tcp_chr_telnet_init(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;
    TCPCharDriverTelnetInit *init =
        g_new0(TCPCharDriverTelnetInit, 1);
    size_t n = 0;

    init->chr = chr;
    init->buflen = 12;

#define IACSET(x, a, b, c)                      \
    do {                                        \
        x[n++] = a;                             \
        x[n++] = b;                             \
        x[n++] = c;                             \
    } while (0)

    /* Prep the telnet negotion to put telnet in binary,
     * no echo, single char mode */
    IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
    IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
    IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
    IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */

#undef IACSET

    qio_channel_add_watch(
        s->ioc, G_IO_OUT,
        tcp_chr_telnet_init_io,
        init, NULL);
A
aliguori 已提交
3018 3019
}

3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053

static void tcp_chr_tls_handshake(Object *source,
                                  Error *err,
                                  gpointer user_data)
{
    CharDriverState *chr = user_data;
    TCPCharDriver *s = chr->opaque;

    if (err) {
        tcp_chr_disconnect(chr);
    } else {
        if (s->do_telnetopt) {
            tcp_chr_telnet_init(chr);
        } else {
            tcp_chr_connect(chr);
        }
    }
}


static void tcp_chr_tls_init(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;
    QIOChannelTLS *tioc;
    Error *err = NULL;

    if (s->is_listen) {
        tioc = qio_channel_tls_new_server(
            s->ioc, s->tls_creds,
            NULL, /* XXX Use an ACL */
            &err);
    } else {
        tioc = qio_channel_tls_new_client(
            s->ioc, s->tls_creds,
3054
            s->addr->u.inet.data->host,
3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070
            &err);
    }
    if (tioc == NULL) {
        error_free(err);
        tcp_chr_disconnect(chr);
    }
    object_unref(OBJECT(s->ioc));
    s->ioc = QIO_CHANNEL(tioc);

    qio_channel_tls_handshake(tioc,
                              tcp_chr_tls_handshake,
                              chr,
                              NULL);
}


3071
static int tcp_chr_new_client(CharDriverState *chr, QIOChannelSocket *sioc)
3072 3073
{
    TCPCharDriver *s = chr->opaque;
3074
    if (s->ioc != NULL) {
3075
	return -1;
3076
    }
3077

3078 3079
    s->ioc = QIO_CHANNEL(sioc);
    object_ref(OBJECT(sioc));
3080 3081
    s->sioc = sioc;
    object_ref(OBJECT(sioc));
3082

3083 3084
    qio_channel_set_blocking(s->ioc, false, NULL);

3085 3086 3087
    if (s->do_nodelay) {
        qio_channel_set_delay(s->ioc, false);
    }
3088 3089 3090 3091
    if (s->listen_tag) {
        g_source_remove(s->listen_tag);
        s->listen_tag = 0;
    }
3092

3093 3094
    if (s->tls_creds) {
        tcp_chr_tls_init(chr);
3095
    } else {
3096 3097 3098 3099 3100
        if (s->do_telnetopt) {
            tcp_chr_telnet_init(chr);
        } else {
            tcp_chr_connect(chr);
        }
3101
    }
3102 3103 3104 3105

    return 0;
}

3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123

static int tcp_chr_add_client(CharDriverState *chr, int fd)
{
    int ret;
    QIOChannelSocket *sioc;

    sioc = qio_channel_socket_new_fd(fd, NULL);
    if (!sioc) {
        return -1;
    }
    ret = tcp_chr_new_client(chr, sioc);
    object_unref(OBJECT(sioc));
    return ret;
}

static gboolean tcp_chr_accept(QIOChannel *channel,
                               GIOCondition cond,
                               void *opaque)
A
aliguori 已提交
3124 3125
{
    CharDriverState *chr = opaque;
3126
    QIOChannelSocket *sioc;
A
aliguori 已提交
3127

3128 3129 3130 3131
    sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(channel),
                                     NULL);
    if (!sioc) {
        return TRUE;
A
aliguori 已提交
3132
    }
3133 3134 3135 3136

    tcp_chr_new_client(chr, sioc);

    object_unref(OBJECT(sioc));
3137 3138

    return TRUE;
A
aliguori 已提交
3139 3140 3141 3142 3143
}

static void tcp_chr_close(CharDriverState *chr)
{
    TCPCharDriver *s = chr->opaque;
3144
    int i;
3145

3146 3147 3148 3149
    if (s->reconnect_timer) {
        g_source_remove(s->reconnect_timer);
        s->reconnect_timer = 0;
    }
3150
    qapi_free_SocketAddress(s->addr);
3151 3152 3153
    remove_fd_in_watch(chr);
    if (s->ioc) {
        object_unref(OBJECT(s->ioc));
3154
    }
3155 3156 3157 3158 3159 3160
    if (s->listen_tag) {
        g_source_remove(s->listen_tag);
        s->listen_tag = 0;
    }
    if (s->listen_ioc) {
        object_unref(OBJECT(s->listen_ioc));
3161
    }
3162 3163 3164 3165 3166 3167
    if (s->read_msgfds_num) {
        for (i = 0; i < s->read_msgfds_num; i++) {
            close(s->read_msgfds[i]);
        }
        g_free(s->read_msgfds);
    }
3168 3169 3170
    if (s->tls_creds) {
        object_unref(OBJECT(s->tls_creds));
    }
3171 3172 3173
    if (s->write_msgfds_num) {
        g_free(s->write_msgfds);
    }
3174
    g_free(s);
3175
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
A
aliguori 已提交
3176 3177
}

3178

3179
static void qemu_chr_socket_connected(Object *src, Error *err, void *opaque)
3180
{
3181
    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(src);
3182
    CharDriverState *chr = opaque;
3183
    TCPCharDriver *s = chr->opaque;
3184

3185
    if (err) {
3186
        check_report_connect_error(chr, err);
3187
        object_unref(src);
3188 3189 3190
        return;
    }

3191
    s->connect_err_reported = false;
3192 3193
    tcp_chr_new_client(chr, sioc);
    object_unref(OBJECT(sioc));
3194 3195
}

3196

3197
/*********************************************************/
3198
/* Ring buffer chardev */
3199 3200 3201 3202 3203 3204

typedef struct {
    size_t size;
    size_t prod;
    size_t cons;
    uint8_t *cbuf;
3205
} RingBufCharDriver;
3206

3207
static size_t ringbuf_count(const CharDriverState *chr)
3208
{
3209
    const RingBufCharDriver *d = chr->opaque;
3210

3211
    return d->prod - d->cons;
3212 3213
}

3214
/* Called with chr_write_lock held.  */
3215
static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3216
{
3217
    RingBufCharDriver *d = chr->opaque;
3218 3219 3220 3221 3222 3223 3224
    int i;

    if (!buf || (len < 0)) {
        return -1;
    }

    for (i = 0; i < len; i++ ) {
3225 3226
        d->cbuf[d->prod++ & (d->size - 1)] = buf[i];
        if (d->prod - d->cons > d->size) {
3227 3228 3229 3230 3231 3232 3233
            d->cons = d->prod - d->size;
        }
    }

    return 0;
}

3234
static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len)
3235
{
3236
    RingBufCharDriver *d = chr->opaque;
3237 3238
    int i;

3239
    qemu_mutex_lock(&chr->chr_write_lock);
3240 3241
    for (i = 0; i < len && d->cons != d->prod; i++) {
        buf[i] = d->cbuf[d->cons++ & (d->size - 1)];
3242
    }
3243
    qemu_mutex_unlock(&chr->chr_write_lock);
3244 3245 3246 3247

    return i;
}

3248
static void ringbuf_chr_close(struct CharDriverState *chr)
3249
{
3250
    RingBufCharDriver *d = chr->opaque;
3251 3252 3253 3254 3255 3256

    g_free(d->cbuf);
    g_free(d);
    chr->opaque = NULL;
}

3257 3258 3259
static CharDriverState *qemu_chr_open_ringbuf(const char *id,
                                              ChardevBackend *backend,
                                              ChardevReturn *ret,
3260
                                              Error **errp)
3261
{
3262
    ChardevRingbuf *opts = backend->u.ringbuf.data;
3263
    ChardevCommon *common = qapi_ChardevRingbuf_base(opts);
3264
    CharDriverState *chr;
3265
    RingBufCharDriver *d;
3266

3267 3268 3269 3270
    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
        return NULL;
    }
3271 3272
    d = g_malloc(sizeof(*d));

3273
    d->size = opts->has_size ? opts->size : 65536;
3274 3275 3276

    /* The size must be power of 2 */
    if (d->size & (d->size - 1)) {
3277
        error_setg(errp, "size of ringbuf chardev must be power of two");
3278 3279 3280 3281 3282 3283 3284 3285
        goto fail;
    }

    d->prod = 0;
    d->cons = 0;
    d->cbuf = g_malloc0(d->size);

    chr->opaque = d;
3286 3287
    chr->chr_write = ringbuf_chr_write;
    chr->chr_close = ringbuf_chr_close;
3288 3289 3290 3291 3292

    return chr;

fail:
    g_free(d);
3293
    qemu_chr_free_common(chr);
3294 3295 3296
    return NULL;
}

3297
bool chr_is_ringbuf(const CharDriverState *chr)
3298
{
3299
    return chr->chr_write == ringbuf_chr_write;
3300 3301
}

3302
void qmp_ringbuf_write(const char *device, const char *data,
3303
                       bool has_format, enum DataFormat format,
3304 3305 3306
                       Error **errp)
{
    CharDriverState *chr;
3307
    const uint8_t *write_data;
3308
    int ret;
3309
    gsize write_count;
3310 3311 3312

    chr = qemu_chr_find(device);
    if (!chr) {
3313
        error_setg(errp, "Device '%s' not found", device);
3314 3315 3316
        return;
    }

3317 3318
    if (!chr_is_ringbuf(chr)) {
        error_setg(errp,"%s is not a ringbuf device", device);
3319 3320 3321 3322
        return;
    }

    if (has_format && (format == DATA_FORMAT_BASE64)) {
3323 3324 3325 3326 3327 3328
        write_data = qbase64_decode(data, -1,
                                    &write_count,
                                    errp);
        if (!write_data) {
            return;
        }
3329 3330
    } else {
        write_data = (uint8_t *)data;
3331
        write_count = strlen(data);
3332 3333
    }

3334
    ret = ringbuf_chr_write(chr, write_data, write_count);
3335

3336 3337 3338 3339
    if (write_data != (uint8_t *)data) {
        g_free((void *)write_data);
    }

3340 3341 3342 3343 3344 3345
    if (ret < 0) {
        error_setg(errp, "Failed to write to device %s", device);
        return;
    }
}

3346
char *qmp_ringbuf_read(const char *device, int64_t size,
3347 3348
                       bool has_format, enum DataFormat format,
                       Error **errp)
3349 3350
{
    CharDriverState *chr;
3351
    uint8_t *read_data;
3352
    size_t count;
3353
    char *data;
3354 3355 3356

    chr = qemu_chr_find(device);
    if (!chr) {
3357
        error_setg(errp, "Device '%s' not found", device);
3358 3359 3360
        return NULL;
    }

3361 3362
    if (!chr_is_ringbuf(chr)) {
        error_setg(errp,"%s is not a ringbuf device", device);
3363 3364 3365 3366 3367 3368 3369 3370
        return NULL;
    }

    if (size <= 0) {
        error_setg(errp, "size must be greater than zero");
        return NULL;
    }

3371
    count = ringbuf_count(chr);
3372
    size = size > count ? count : size;
3373
    read_data = g_malloc(size + 1);
3374

3375
    ringbuf_chr_read(chr, read_data, size);
3376 3377

    if (has_format && (format == DATA_FORMAT_BASE64)) {
3378
        data = g_base64_encode(read_data, size);
3379
        g_free(read_data);
3380
    } else {
3381 3382 3383 3384 3385 3386 3387
        /*
         * FIXME should read only complete, valid UTF-8 characters up
         * to @size bytes.  Invalid sequences should be replaced by a
         * suitable replacement character.  Except when (and only
         * when) ring buffer lost characters since last read, initial
         * continuation characters should be dropped.
         */
3388
        read_data[size] = 0;
3389
        data = (char *)read_data;
3390 3391
    }

3392
    return data;
3393 3394
}

G
Gerd Hoffmann 已提交
3395
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
3396
{
G
Gerd Hoffmann 已提交
3397
    char host[65], port[33], width[8], height[8];
3398
    int pos;
3399
    const char *p;
3400
    QemuOpts *opts;
3401
    Error *local_err = NULL;
3402

3403
    opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
3404
    if (local_err) {
3405
        error_report_err(local_err);
3406
        return NULL;
3407
    }
3408

G
Gerd Hoffmann 已提交
3409 3410
    if (strstart(filename, "mon:", &p)) {
        filename = p;
3411
        qemu_opt_set(opts, "mux", "on", &error_abort);
3412 3413 3414 3415 3416 3417
        if (strcmp(filename, "stdio") == 0) {
            /* Monitor is muxed to stdio: do not exit on Ctrl+C by default
             * but pass it to the guest.  Handle this only for compat syntax,
             * for -chardev syntax we have special option for this.
             * This is what -nographic did, redirecting+muxing serial+monitor
             * to stdio causing Ctrl+C to be passed to guest. */
3418
            qemu_opt_set(opts, "signal", "off", &error_abort);
3419
        }
G
Gerd Hoffmann 已提交
3420 3421
    }

3422 3423 3424
    if (strcmp(filename, "null")    == 0 ||
        strcmp(filename, "pty")     == 0 ||
        strcmp(filename, "msmouse") == 0 ||
3425
        strcmp(filename, "braille") == 0 ||
P
Paolo Bonzini 已提交
3426
        strcmp(filename, "testdev") == 0 ||
3427
        strcmp(filename, "stdio")   == 0) {
3428
        qemu_opt_set(opts, "backend", filename, &error_abort);
3429 3430
        return opts;
    }
G
Gerd Hoffmann 已提交
3431
    if (strstart(filename, "vc", &p)) {
3432
        qemu_opt_set(opts, "backend", "vc", &error_abort);
G
Gerd Hoffmann 已提交
3433
        if (*p == ':') {
3434
            if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
G
Gerd Hoffmann 已提交
3435
                /* pixels */
3436 3437
                qemu_opt_set(opts, "width", width, &error_abort);
                qemu_opt_set(opts, "height", height, &error_abort);
3438
            } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
G
Gerd Hoffmann 已提交
3439
                /* chars */
3440 3441
                qemu_opt_set(opts, "cols", width, &error_abort);
                qemu_opt_set(opts, "rows", height, &error_abort);
G
Gerd Hoffmann 已提交
3442 3443 3444 3445 3446 3447
            } else {
                goto fail;
            }
        }
        return opts;
    }
3448
    if (strcmp(filename, "con:") == 0) {
3449
        qemu_opt_set(opts, "backend", "console", &error_abort);
3450 3451
        return opts;
    }
3452
    if (strstart(filename, "COM", NULL)) {
3453 3454
        qemu_opt_set(opts, "backend", "serial", &error_abort);
        qemu_opt_set(opts, "path", filename, &error_abort);
3455 3456
        return opts;
    }
3457
    if (strstart(filename, "file:", &p)) {
3458 3459
        qemu_opt_set(opts, "backend", "file", &error_abort);
        qemu_opt_set(opts, "path", p, &error_abort);
3460 3461 3462
        return opts;
    }
    if (strstart(filename, "pipe:", &p)) {
3463 3464
        qemu_opt_set(opts, "backend", "pipe", &error_abort);
        qemu_opt_set(opts, "path", p, &error_abort);
3465 3466
        return opts;
    }
3467 3468 3469 3470 3471 3472 3473
    if (strstart(filename, "tcp:", &p) ||
        strstart(filename, "telnet:", &p)) {
        if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
            host[0] = 0;
            if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
                goto fail;
        }
3474 3475 3476
        qemu_opt_set(opts, "backend", "socket", &error_abort);
        qemu_opt_set(opts, "host", host, &error_abort);
        qemu_opt_set(opts, "port", port, &error_abort);
3477
        if (p[pos] == ',') {
3478 3479 3480
            qemu_opts_do_parse(opts, p+pos+1, NULL, &local_err);
            if (local_err) {
                error_report_err(local_err);
3481
                goto fail;
3482
            }
3483 3484
        }
        if (strstart(filename, "telnet:", &p))
3485
            qemu_opt_set(opts, "telnet", "on", &error_abort);
3486 3487
        return opts;
    }
G
Gerd Hoffmann 已提交
3488
    if (strstart(filename, "udp:", &p)) {
3489
        qemu_opt_set(opts, "backend", "udp", &error_abort);
G
Gerd Hoffmann 已提交
3490 3491
        if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
            host[0] = 0;
3492
            if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
G
Gerd Hoffmann 已提交
3493 3494 3495
                goto fail;
            }
        }
3496 3497
        qemu_opt_set(opts, "host", host, &error_abort);
        qemu_opt_set(opts, "port", port, &error_abort);
G
Gerd Hoffmann 已提交
3498 3499 3500 3501 3502 3503 3504 3505
        if (p[pos] == '@') {
            p += pos + 1;
            if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
                host[0] = 0;
                if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
                    goto fail;
                }
            }
3506 3507
            qemu_opt_set(opts, "localaddr", host, &error_abort);
            qemu_opt_set(opts, "localport", port, &error_abort);
G
Gerd Hoffmann 已提交
3508 3509 3510
        }
        return opts;
    }
3511
    if (strstart(filename, "unix:", &p)) {
3512
        qemu_opt_set(opts, "backend", "socket", &error_abort);
3513 3514 3515
        qemu_opts_do_parse(opts, p, "path", &local_err);
        if (local_err) {
            error_report_err(local_err);
3516
            goto fail;
3517
        }
3518 3519
        return opts;
    }
3520 3521
    if (strstart(filename, "/dev/parport", NULL) ||
        strstart(filename, "/dev/ppi", NULL)) {
3522 3523
        qemu_opt_set(opts, "backend", "parport", &error_abort);
        qemu_opt_set(opts, "path", filename, &error_abort);
3524 3525 3526
        return opts;
    }
    if (strstart(filename, "/dev/", NULL)) {
3527 3528
        qemu_opt_set(opts, "backend", "tty", &error_abort);
        qemu_opt_set(opts, "path", filename, &error_abort);
3529 3530
        return opts;
    }
3531

3532
fail:
3533 3534 3535 3536
    qemu_opts_del(opts);
    return NULL;
}

3537
void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548
{
    const char *logfile = qemu_opt_get(opts, "logfile");

    backend->has_logfile = logfile != NULL;
    backend->logfile = logfile ? g_strdup(logfile) : NULL;

    backend->has_logappend = true;
    backend->logappend = qemu_opt_get_bool(opts, "logappend", false);
}


3549 3550 3551 3552
static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
                                    Error **errp)
{
    const char *path = qemu_opt_get(opts, "path");
3553
    ChardevFile *file;
3554 3555 3556 3557 3558

    if (path == NULL) {
        error_setg(errp, "chardev: file: no filename given");
        return;
    }
3559
    file = backend->u.file.data = g_new0(ChardevFile, 1);
3560 3561
    qemu_chr_parse_common(opts, qapi_ChardevFile_base(file));
    file->out = g_strdup(path);
3562

3563 3564
    file->has_append = true;
    file->append = qemu_opt_get_bool(opts, "append", false);
3565 3566
}

3567 3568 3569
static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
                                 Error **errp)
{
3570 3571
    ChardevStdio *stdio;

3572
    stdio = backend->u.stdio.data = g_new0(ChardevStdio, 1);
3573 3574 3575
    qemu_chr_parse_common(opts, qapi_ChardevStdio_base(stdio));
    stdio->has_signal = true;
    stdio->signal = qemu_opt_get_bool(opts, "signal", true);
3576 3577
}

3578
#ifdef HAVE_CHARDEV_SERIAL
3579 3580 3581 3582
static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
                                  Error **errp)
{
    const char *device = qemu_opt_get(opts, "path");
3583
    ChardevHostdev *serial;
3584 3585 3586 3587 3588

    if (device == NULL) {
        error_setg(errp, "chardev: serial/tty: no device path given");
        return;
    }
3589
    serial = backend->u.serial.data = g_new0(ChardevHostdev, 1);
3590 3591
    qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial));
    serial->device = g_strdup(device);
3592
}
3593
#endif
3594

3595
#ifdef HAVE_CHARDEV_PARPORT
3596 3597 3598 3599
static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
                                    Error **errp)
{
    const char *device = qemu_opt_get(opts, "path");
3600
    ChardevHostdev *parallel;
3601 3602 3603 3604 3605

    if (device == NULL) {
        error_setg(errp, "chardev: parallel: no device path given");
        return;
    }
3606
    parallel = backend->u.parallel.data = g_new0(ChardevHostdev, 1);
3607 3608
    qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(parallel));
    parallel->device = g_strdup(device);
3609
}
3610
#endif
3611

3612 3613 3614 3615
static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
                                Error **errp)
{
    const char *device = qemu_opt_get(opts, "path");
3616
    ChardevHostdev *dev;
3617 3618 3619 3620 3621

    if (device == NULL) {
        error_setg(errp, "chardev: pipe: no device path given");
        return;
    }
3622
    dev = backend->u.pipe.data = g_new0(ChardevHostdev, 1);
3623 3624
    qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(dev));
    dev->device = g_strdup(device);
3625 3626
}

3627 3628
static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
                                   Error **errp)
3629 3630
{
    int val;
3631
    ChardevRingbuf *ringbuf;
3632

3633
    ringbuf = backend->u.ringbuf.data = g_new0(ChardevRingbuf, 1);
3634
    qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(ringbuf));
3635

3636
    val = qemu_opt_get_size(opts, "size", 0);
3637
    if (val != 0) {
3638 3639
        ringbuf->has_size = true;
        ringbuf->size = val;
3640 3641 3642
    }
}

3643 3644 3645 3646
static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
                               Error **errp)
{
    const char *chardev = qemu_opt_get(opts, "chardev");
3647
    ChardevMux *mux;
3648 3649 3650 3651 3652

    if (chardev == NULL) {
        error_setg(errp, "chardev: mux: no chardev given");
        return;
    }
3653
    mux = backend->u.mux.data = g_new0(ChardevMux, 1);
3654 3655
    qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux));
    mux->chardev = g_strdup(chardev);
3656 3657
}

3658 3659 3660 3661 3662 3663 3664
static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
                                  Error **errp)
{
    bool is_listen      = qemu_opt_get_bool(opts, "server", false);
    bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
    bool is_telnet      = qemu_opt_get_bool(opts, "telnet", false);
    bool do_nodelay     = !qemu_opt_get_bool(opts, "delay", true);
3665
    int64_t reconnect   = qemu_opt_get_number(opts, "reconnect", 0);
3666 3667 3668
    const char *path = qemu_opt_get(opts, "path");
    const char *host = qemu_opt_get(opts, "host");
    const char *port = qemu_opt_get(opts, "port");
3669
    const char *tls_creds = qemu_opt_get(opts, "tls-creds");
3670
    SocketAddress *addr;
3671
    ChardevSocket *sock;
3672 3673 3674 3675 3676 3677 3678 3679 3680 3681

    if (!path) {
        if (!host) {
            error_setg(errp, "chardev: socket: no host given");
            return;
        }
        if (!port) {
            error_setg(errp, "chardev: socket: no port given");
            return;
        }
3682 3683 3684 3685 3686
    } else {
        if (tls_creds) {
            error_setg(errp, "TLS can only be used over TCP socket");
            return;
        }
3687 3688
    }

3689
    sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
3690
    qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
3691

3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702
    sock->has_nodelay = true;
    sock->nodelay = do_nodelay;
    sock->has_server = true;
    sock->server = is_listen;
    sock->has_telnet = true;
    sock->telnet = is_telnet;
    sock->has_wait = true;
    sock->wait = is_waitconnect;
    sock->has_reconnect = true;
    sock->reconnect = reconnect;
    sock->tls_creds = g_strdup(tls_creds);
3703 3704 3705

    addr = g_new0(SocketAddress, 1);
    if (path) {
3706
        UnixSocketAddress *q_unix;
3707
        addr->type = SOCKET_ADDRESS_KIND_UNIX;
3708
        q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
3709
        q_unix->path = g_strdup(path);
3710
    } else {
3711
        addr->type = SOCKET_ADDRESS_KIND_INET;
3712 3713
        addr->u.inet.data = g_new(InetSocketAddress, 1);
        *addr->u.inet.data = (InetSocketAddress) {
3714 3715 3716 3717 3718 3719 3720 3721 3722
            .host = g_strdup(host),
            .port = g_strdup(port),
            .has_to = qemu_opt_get(opts, "to"),
            .to = qemu_opt_get_number(opts, "to", 0),
            .has_ipv4 = qemu_opt_get(opts, "ipv4"),
            .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
            .has_ipv6 = qemu_opt_get(opts, "ipv6"),
            .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
        };
3723
    }
3724
    sock->addr = addr;
3725 3726
}

3727 3728 3729 3730 3731 3732 3733 3734 3735
static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
                               Error **errp)
{
    const char *host = qemu_opt_get(opts, "host");
    const char *port = qemu_opt_get(opts, "port");
    const char *localaddr = qemu_opt_get(opts, "localaddr");
    const char *localport = qemu_opt_get(opts, "localport");
    bool has_local = false;
    SocketAddress *addr;
3736
    ChardevUdp *udp;
3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755

    if (host == NULL || strlen(host) == 0) {
        host = "localhost";
    }
    if (port == NULL || strlen(port) == 0) {
        error_setg(errp, "chardev: udp: remote port not specified");
        return;
    }
    if (localport == NULL || strlen(localport) == 0) {
        localport = "0";
    } else {
        has_local = true;
    }
    if (localaddr == NULL || strlen(localaddr) == 0) {
        localaddr = "";
    } else {
        has_local = true;
    }

3756
    udp = backend->u.udp.data = g_new0(ChardevUdp, 1);
3757
    qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp));
3758 3759

    addr = g_new0(SocketAddress, 1);
3760
    addr->type = SOCKET_ADDRESS_KIND_INET;
3761 3762
    addr->u.inet.data = g_new(InetSocketAddress, 1);
    *addr->u.inet.data = (InetSocketAddress) {
3763 3764 3765 3766 3767 3768 3769
        .host = g_strdup(host),
        .port = g_strdup(port),
        .has_ipv4 = qemu_opt_get(opts, "ipv4"),
        .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
        .has_ipv6 = qemu_opt_get(opts, "ipv6"),
        .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
    };
3770
    udp->remote = addr;
3771 3772

    if (has_local) {
3773
        udp->has_local = true;
3774
        addr = g_new0(SocketAddress, 1);
3775
        addr->type = SOCKET_ADDRESS_KIND_INET;
3776 3777
        addr->u.inet.data = g_new(InetSocketAddress, 1);
        *addr->u.inet.data = (InetSocketAddress) {
3778 3779 3780
            .host = g_strdup(localaddr),
            .port = g_strdup(localport),
        };
3781
        udp->local = addr;
3782 3783 3784
    }
}

3785
typedef struct CharDriver {
3786
    const char *name;
3787
    ChardevBackendKind kind;
3788
    void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
3789 3790
    CharDriverState *(*create)(const char *id, ChardevBackend *backend,
                               ChardevReturn *ret, Error **errp);
3791 3792 3793 3794
} CharDriver;

static GSList *backends;

3795
void register_char_driver(const char *name, ChardevBackendKind kind,
3796 3797 3798
        void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp),
        CharDriverState *(*create)(const char *id, ChardevBackend *backend,
                                   ChardevReturn *ret, Error **errp))
3799 3800 3801 3802 3803 3804 3805
{
    CharDriver *s;

    s = g_malloc0(sizeof(*s));
    s->name = g_strdup(name);
    s->kind = kind;
    s->parse = parse;
3806
    s->create = create;
3807 3808 3809 3810

    backends = g_slist_append(backends, s);
}

3811
CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
3812 3813
                                    void (*init)(struct CharDriverState *s),
                                    Error **errp)
3814
{
3815
    Error *local_err = NULL;
3816
    CharDriver *cd;
3817
    CharDriverState *chr;
3818
    GSList *i;
3819 3820 3821 3822
    ChardevReturn *ret = NULL;
    ChardevBackend *backend;
    const char *id = qemu_opts_id(opts);
    char *bid = NULL;
3823

3824
    if (id == NULL) {
3825
        error_setg(errp, "chardev: no id specified");
G
Gerd Hoffmann 已提交
3826
        goto err;
3827 3828
    }

3829
    if (qemu_opt_get(opts, "backend") == NULL) {
3830
        error_setg(errp, "chardev: \"%s\" missing backend",
3831
                   qemu_opts_id(opts));
G
Gerd Hoffmann 已提交
3832
        goto err;
3833
    }
3834 3835 3836 3837
    for (i = backends; i; i = i->next) {
        cd = i->data;

        if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) {
3838
            break;
3839
        }
3840
    }
3841
    if (i == NULL) {
3842
        error_setg(errp, "chardev: backend \"%s\" not found",
3843
                   qemu_opt_get(opts, "backend"));
3844
        goto err;
3845 3846
    }

3847
    backend = g_new0(ChardevBackend, 1);
3848

3849 3850 3851
    if (qemu_opt_get_bool(opts, "mux", 0)) {
        bid = g_strdup_printf("%s-base", id);
    }
3852

3853
    chr = NULL;
3854
    backend->type = cd->kind;
3855 3856 3857 3858
    if (cd->parse) {
        cd->parse(opts, backend, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
3859 3860
            goto qapi_out;
        }
3861 3862 3863
    } else {
        ChardevCommon *cc = g_new0(ChardevCommon, 1);
        qemu_chr_parse_common(opts, cc);
3864
        backend->u.null.data = cc; /* Any ChardevCommon member would work */
3865
    }
3866

3867 3868 3869
    ret = qmp_chardev_add(bid ? bid : id, backend, errp);
    if (!ret) {
        goto qapi_out;
3870 3871
    }

3872 3873 3874 3875
    if (bid) {
        qapi_free_ChardevBackend(backend);
        qapi_free_ChardevReturn(ret);
        backend = g_new0(ChardevBackend, 1);
3876
        backend->u.mux.data = g_new0(ChardevMux, 1);
3877
        backend->type = CHARDEV_BACKEND_KIND_MUX;
3878
        backend->u.mux.data->chardev = g_strdup(bid);
3879 3880 3881 3882 3883 3884 3885
        ret = qmp_chardev_add(id, backend, errp);
        if (!ret) {
            chr = qemu_chr_find(bid);
            qemu_chr_delete(chr);
            chr = NULL;
            goto qapi_out;
        }
3886
    }
G
Gerd Hoffmann 已提交
3887

3888
    chr = qemu_chr_find(id);
G
Gerd Hoffmann 已提交
3889
    chr->opts = opts;
3890 3891 3892 3893 3894

qapi_out:
    qapi_free_ChardevBackend(backend);
    qapi_free_ChardevReturn(ret);
    g_free(bid);
3895
    return chr;
G
Gerd Hoffmann 已提交
3896 3897 3898 3899

err:
    qemu_opts_del(opts);
    return NULL;
3900 3901
}

P
Pavel Dovgalyuk 已提交
3902 3903
CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename,
                                       void (*init)(struct CharDriverState *s))
A
aliguori 已提交
3904 3905 3906
{
    const char *p;
    CharDriverState *chr;
3907
    QemuOpts *opts;
3908
    Error *err = NULL;
3909

G
Gerd Hoffmann 已提交
3910 3911 3912 3913
    if (strstart(filename, "chardev:", &p)) {
        return qemu_chr_find(p);
    }

3914
    opts = qemu_chr_parse_compat(label, filename);
G
Gerd Hoffmann 已提交
3915 3916
    if (!opts)
        return NULL;
A
aliguori 已提交
3917

3918
    chr = qemu_chr_new_from_opts(opts, init, &err);
3919
    if (err) {
3920
        error_report_err(err);
3921
    }
G
Gerd Hoffmann 已提交
3922
    if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
3923
        qemu_chr_fe_claim_no_fail(chr);
G
Gerd Hoffmann 已提交
3924
        monitor_init(chr, MONITOR_USE_READLINE);
A
aliguori 已提交
3925 3926 3927 3928
    }
    return chr;
}

P
Pavel Dovgalyuk 已提交
3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943
CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
{
    CharDriverState *chr;
    chr = qemu_chr_new_noreplay(label, filename, init);
    if (chr) {
        chr->replay = replay_mode != REPLAY_MODE_NONE;
        if (chr->replay && chr->chr_ioctl) {
            fprintf(stderr,
                    "Replay: ioctl is not supported for serial devices yet\n");
        }
        replay_register_char_driver(chr);
    }
    return chr;
}

3944
void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
P
Paolo Bonzini 已提交
3945 3946 3947 3948 3949 3950
{
    if (chr->chr_set_echo) {
        chr->chr_set_echo(chr, echo);
    }
}

3951
void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open)
3952
{
3953
    if (chr->fe_open == fe_open) {
H
Hans de Goede 已提交
3954 3955
        return;
    }
3956
    chr->fe_open = fe_open;
3957 3958
    if (chr->chr_set_fe_open) {
        chr->chr_set_fe_open(chr, fe_open);
3959 3960 3961
    }
}

M
Marc-André Lureau 已提交
3962 3963 3964 3965 3966 3967 3968
void qemu_chr_fe_event(struct CharDriverState *chr, int event)
{
    if (chr->chr_fe_event) {
        chr->chr_fe_event(chr, event);
    }
}

3969 3970
int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
                          GIOFunc func, void *user_data)
A
Anthony Liguori 已提交
3971 3972 3973 3974 3975 3976 3977 3978 3979
{
    GSource *src;
    guint tag;

    if (s->chr_add_watch == NULL) {
        return -ENOSYS;
    }

    src = s->chr_add_watch(s, cond);
3980 3981 3982 3983
    if (!src) {
        return -EINVAL;
    }

A
Anthony Liguori 已提交
3984 3985 3986 3987 3988 3989 3990
    g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
    tag = g_source_attach(src, NULL);
    g_source_unref(src);

    return tag;
}

3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013
int qemu_chr_fe_claim(CharDriverState *s)
{
    if (s->avail_connections < 1) {
        return -1;
    }
    s->avail_connections--;
    return 0;
}

void qemu_chr_fe_claim_no_fail(CharDriverState *s)
{
    if (qemu_chr_fe_claim(s) != 0) {
        fprintf(stderr, "%s: error chardev \"%s\" already used\n",
                __func__, s->label);
        exit(1);
    }
}

void qemu_chr_fe_release(CharDriverState *s)
{
    s->avail_connections++;
}

4014 4015 4016 4017 4018 4019 4020
void qemu_chr_disconnect(CharDriverState *chr)
{
    if (chr->chr_disconnect) {
        chr->chr_disconnect(chr);
    }
}

4021
static void qemu_chr_free_common(CharDriverState *chr)
A
aliguori 已提交
4022
{
4023 4024
    g_free(chr->filename);
    g_free(chr->label);
4025
    qemu_opts_del(chr->opts);
4026 4027 4028
    if (chr->logfd != -1) {
        close(chr->logfd);
    }
4029
    qemu_mutex_destroy(&chr->chr_write_lock);
4030
    g_free(chr);
A
aliguori 已提交
4031 4032
}

4033 4034 4035 4036 4037 4038 4039 4040
void qemu_chr_free(CharDriverState *chr)
{
    if (chr->chr_close) {
        chr->chr_close(chr);
    }
    qemu_chr_free_common(chr);
}

M
Marc-André Lureau 已提交
4041 4042 4043 4044 4045 4046
void qemu_chr_delete(CharDriverState *chr)
{
    QTAILQ_REMOVE(&chardevs, chr, next);
    qemu_chr_free(chr);
}

L
Luiz Capitulino 已提交
4047
ChardevInfoList *qmp_query_chardev(Error **errp)
A
aliguori 已提交
4048
{
L
Luiz Capitulino 已提交
4049
    ChardevInfoList *chr_list = NULL;
A
aliguori 已提交
4050 4051
    CharDriverState *chr;

B
Blue Swirl 已提交
4052
    QTAILQ_FOREACH(chr, &chardevs, next) {
L
Luiz Capitulino 已提交
4053 4054 4055 4056
        ChardevInfoList *info = g_malloc0(sizeof(*info));
        info->value = g_malloc0(sizeof(*info->value));
        info->value->label = g_strdup(chr->label);
        info->value->filename = g_strdup(chr->filename);
4057
        info->value->frontend_open = chr->fe_open;
L
Luiz Capitulino 已提交
4058 4059 4060

        info->next = chr_list;
        chr_list = info;
A
aliguori 已提交
4061
    }
4062

L
Luiz Capitulino 已提交
4063
    return chr_list;
A
aliguori 已提交
4064
}
G
Gerd Hoffmann 已提交
4065

4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084
ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
{
    ChardevBackendInfoList *backend_list = NULL;
    CharDriver *c = NULL;
    GSList *i = NULL;

    for (i = backends; i; i = i->next) {
        ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
        c = i->data;
        info->value = g_malloc0(sizeof(*info->value));
        info->value->name = g_strdup(c->name);

        info->next = backend_list;
        backend_list = info;
    }

    return backend_list;
}

G
Gerd Hoffmann 已提交
4085 4086 4087 4088
CharDriverState *qemu_chr_find(const char *name)
{
    CharDriverState *chr;

B
Blue Swirl 已提交
4089
    QTAILQ_FOREACH(chr, &chardevs, next) {
G
Gerd Hoffmann 已提交
4090 4091 4092 4093 4094 4095
        if (strcmp(chr->label, name) != 0)
            continue;
        return chr;
    }
    return NULL;
}
A
Anthony Liguori 已提交
4096

4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137
QemuOptsList qemu_chardev_opts = {
    .name = "chardev",
    .implied_opt_name = "backend",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
    .desc = {
        {
            .name = "backend",
            .type = QEMU_OPT_STRING,
        },{
            .name = "path",
            .type = QEMU_OPT_STRING,
        },{
            .name = "host",
            .type = QEMU_OPT_STRING,
        },{
            .name = "port",
            .type = QEMU_OPT_STRING,
        },{
            .name = "localaddr",
            .type = QEMU_OPT_STRING,
        },{
            .name = "localport",
            .type = QEMU_OPT_STRING,
        },{
            .name = "to",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "ipv4",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "ipv6",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "wait",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "server",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "delay",
            .type = QEMU_OPT_BOOL,
4138 4139 4140
        },{
            .name = "reconnect",
            .type = QEMU_OPT_NUMBER,
4141 4142 4143
        },{
            .name = "telnet",
            .type = QEMU_OPT_BOOL,
4144 4145 4146
        },{
            .name = "tls-creds",
            .type = QEMU_OPT_STRING,
4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170
        },{
            .name = "width",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "height",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "cols",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "rows",
            .type = QEMU_OPT_NUMBER,
        },{
            .name = "mux",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "signal",
            .type = QEMU_OPT_BOOL,
        },{
            .name = "name",
            .type = QEMU_OPT_STRING,
        },{
            .name = "debug",
            .type = QEMU_OPT_NUMBER,
4171
        },{
4172
            .name = "size",
4173
            .type = QEMU_OPT_SIZE,
4174 4175 4176
        },{
            .name = "chardev",
            .type = QEMU_OPT_STRING,
4177 4178 4179
        },{
            .name = "append",
            .type = QEMU_OPT_BOOL,
4180 4181 4182 4183 4184 4185
        },{
            .name = "logfile",
            .type = QEMU_OPT_STRING,
        },{
            .name = "logappend",
            .type = QEMU_OPT_BOOL,
4186 4187 4188 4189
        },
        { /* end of list */ }
    },
};
4190

4191 4192
#ifdef _WIN32

4193 4194 4195 4196
static CharDriverState *qmp_chardev_open_file(const char *id,
                                              ChardevBackend *backend,
                                              ChardevReturn *ret,
                                              Error **errp)
4197
{
4198
    ChardevFile *file = backend->u.file.data;
4199
    ChardevCommon *common = qapi_ChardevFile_base(file);
4200 4201
    HANDLE out;

4202
    if (file->has_in) {
4203 4204 4205 4206 4207 4208 4209 4210 4211 4212
        error_setg(errp, "input file not supported");
        return NULL;
    }

    out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                     OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (out == INVALID_HANDLE_VALUE) {
        error_setg(errp, "open %s failed", file->out);
        return NULL;
    }
4213
    return qemu_chr_open_win_file(out, common, errp);
4214 4215
}

4216 4217 4218
static CharDriverState *qmp_chardev_open_serial(const char *id,
                                                ChardevBackend *backend,
                                                ChardevReturn *ret,
4219
                                                Error **errp)
4220
{
4221
    ChardevHostdev *serial = backend->u.serial.data;
4222
    ChardevCommon *common = qapi_ChardevHostdev_base(serial);
4223
    return qemu_chr_open_win_path(serial->device, common, errp);
4224 4225
}

4226 4227 4228 4229 4230 4231 4232 4233 4234
#else /* WIN32 */

static int qmp_chardev_open_file_source(char *src, int flags,
                                        Error **errp)
{
    int fd = -1;

    TFR(fd = qemu_open(src, flags, 0666));
    if (fd == -1) {
4235
        error_setg_file_open(errp, errno, src);
4236 4237 4238 4239
    }
    return fd;
}

4240 4241 4242 4243
static CharDriverState *qmp_chardev_open_file(const char *id,
                                              ChardevBackend *backend,
                                              ChardevReturn *ret,
                                              Error **errp)
4244
{
4245
    ChardevFile *file = backend->u.file.data;
4246
    ChardevCommon *common = qapi_ChardevFile_base(file);
4247
    int flags, in = -1, out;
4248

4249 4250 4251 4252 4253 4254 4255
    flags = O_WRONLY | O_CREAT | O_BINARY;
    if (file->has_append && file->append) {
        flags |= O_APPEND;
    } else {
        flags |= O_TRUNC;
    }

4256
    out = qmp_chardev_open_file_source(file->out, flags, errp);
4257
    if (out < 0) {
4258 4259 4260
        return NULL;
    }

4261
    if (file->has_in) {
4262 4263
        flags = O_RDONLY;
        in = qmp_chardev_open_file_source(file->in, flags, errp);
4264
        if (in < 0) {
4265 4266 4267 4268 4269
            qemu_close(out);
            return NULL;
        }
    }

4270
    return qemu_chr_open_fd(in, out, common, errp);
4271 4272
}

P
Paolo Bonzini 已提交
4273
#ifdef HAVE_CHARDEV_SERIAL
4274 4275 4276
static CharDriverState *qmp_chardev_open_serial(const char *id,
                                                ChardevBackend *backend,
                                                ChardevReturn *ret,
4277
                                                Error **errp)
4278
{
4279
    ChardevHostdev *serial = backend->u.serial.data;
4280
    ChardevCommon *common = qapi_ChardevHostdev_base(serial);
4281 4282 4283
    int fd;

    fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
4284
    if (fd < 0) {
4285
        return NULL;
4286
    }
4287
    qemu_set_nonblock(fd);
4288
    return qemu_chr_open_tty_fd(fd, common, errp);
4289
}
4290
#endif
4291

P
Paolo Bonzini 已提交
4292
#ifdef HAVE_CHARDEV_PARPORT
4293 4294 4295
static CharDriverState *qmp_chardev_open_parallel(const char *id,
                                                  ChardevBackend *backend,
                                                  ChardevReturn *ret,
4296 4297
                                                  Error **errp)
{
4298
    ChardevHostdev *parallel = backend->u.parallel.data;
4299
    ChardevCommon *common = qapi_ChardevHostdev_base(parallel);
4300 4301 4302
    int fd;

    fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
4303
    if (fd < 0) {
4304 4305
        return NULL;
    }
4306
    return qemu_chr_open_pp_fd(fd, common, errp);
4307
}
P
Paolo Bonzini 已提交
4308
#endif
4309

4310 4311
#endif /* WIN32 */

4312 4313 4314 4315
static gboolean socket_reconnect_timeout(gpointer opaque)
{
    CharDriverState *chr = opaque;
    TCPCharDriver *s = chr->opaque;
4316
    QIOChannelSocket *sioc;
4317 4318 4319 4320 4321 4322 4323

    s->reconnect_timer = 0;

    if (chr->be_open) {
        return false;
    }

4324 4325 4326 4327
    sioc = qio_channel_socket_new();
    qio_channel_socket_connect_async(sioc, s->addr,
                                     qemu_chr_socket_connected,
                                     chr, NULL);
4328 4329 4330 4331

    return false;
}

4332 4333 4334
static CharDriverState *qmp_chardev_open_socket(const char *id,
                                                ChardevBackend *backend,
                                                ChardevReturn *ret,
4335 4336
                                                Error **errp)
{
4337 4338
    CharDriverState *chr;
    TCPCharDriver *s;
4339
    ChardevSocket *sock = backend->u.socket.data;
4340 4341 4342 4343 4344
    SocketAddress *addr = sock->addr;
    bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
    bool is_listen      = sock->has_server  ? sock->server  : true;
    bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
    bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
4345
    int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
4346
    ChardevCommon *common = qapi_ChardevSocket_base(sock);
4347
    QIOChannelSocket *sioc = NULL;
4348

4349 4350 4351 4352
    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
        return NULL;
    }
4353
    s = g_new0(TCPCharDriver, 1);
4354

4355
    s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX;
4356 4357
    s->is_listen = is_listen;
    s->is_telnet = is_telnet;
4358
    s->do_nodelay = do_nodelay;
4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391
    if (sock->tls_creds) {
        Object *creds;
        creds = object_resolve_path_component(
            object_get_objects_root(), sock->tls_creds);
        if (!creds) {
            error_setg(errp, "No TLS credentials with id '%s'",
                       sock->tls_creds);
            goto error;
        }
        s->tls_creds = (QCryptoTLSCreds *)
            object_dynamic_cast(creds,
                                TYPE_QCRYPTO_TLS_CREDS);
        if (!s->tls_creds) {
            error_setg(errp, "Object with id '%s' is not TLS credentials",
                       sock->tls_creds);
            goto error;
        }
        object_ref(OBJECT(s->tls_creds));
        if (is_listen) {
            if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
                error_setg(errp, "%s",
                           "Expected TLS credentials for server endpoint");
                goto error;
            }
        } else {
            if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
                error_setg(errp, "%s",
                           "Expected TLS credentials for client endpoint");
                goto error;
            }
        }
    }

4392
    qapi_copy_SocketAddress(&s->addr, sock->addr);
4393 4394 4395 4396 4397

    chr->opaque = s;
    chr->chr_write = tcp_chr_write;
    chr->chr_sync_read = tcp_chr_sync_read;
    chr->chr_close = tcp_chr_close;
4398
    chr->chr_disconnect = tcp_chr_disconnect;
4399 4400 4401 4402 4403 4404 4405 4406
    chr->get_msgfds = tcp_get_msgfds;
    chr->set_msgfds = tcp_set_msgfds;
    chr->chr_add_client = tcp_chr_add_client;
    chr->chr_add_watch = tcp_chr_add_watch;
    chr->chr_update_read_handler = tcp_chr_update_read_handler;
    /* be isn't opened until we get a connection */
    chr->explicit_be_open = true;

4407 4408
    chr->filename = SocketAddress_to_str("disconnected:",
                                         addr, is_listen, is_telnet);
4409 4410

    if (is_listen) {
4411 4412 4413
        if (is_telnet) {
            s->do_telnetopt = 1;
        }
4414 4415
    } else if (reconnect > 0) {
        s->reconnect_time = reconnect;
4416
    }
4417

4418
    sioc = qio_channel_socket_new();
4419
    if (s->reconnect_time) {
4420 4421 4422
        qio_channel_socket_connect_async(sioc, s->addr,
                                         qemu_chr_socket_connected,
                                         chr, NULL);
4423 4424 4425 4426 4427 4428 4429 4430 4431 4432
    } else if (s->is_listen) {
        if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) {
            goto error;
        }
        s->listen_ioc = sioc;
        if (is_waitconnect) {
            fprintf(stderr, "QEMU waiting for connection on: %s\n",
                    chr->filename);
            tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr);
        }
4433
        qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL);
4434 4435 4436 4437 4438 4439 4440 4441 4442 4443
        if (!s->ioc) {
            s->listen_tag = qio_channel_add_watch(
                QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
        }
    } else {
        if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
            goto error;
        }
        tcp_chr_new_client(chr, sioc);
        object_unref(OBJECT(sioc));
4444 4445 4446
    }

    return chr;
4447 4448

 error:
4449 4450 4451
    if (sioc) {
        object_unref(OBJECT(sioc));
    }
4452 4453 4454 4455 4456 4457
    if (s->tls_creds) {
        object_unref(OBJECT(s->tls_creds));
    }
    g_free(s);
    qemu_chr_free_common(chr);
    return NULL;
4458 4459
}

4460 4461 4462
static CharDriverState *qmp_chardev_open_udp(const char *id,
                                             ChardevBackend *backend,
                                             ChardevReturn *ret,
4463
                                             Error **errp)
G
Gerd Hoffmann 已提交
4464
{
4465
    ChardevUdp *udp = backend->u.udp.data;
4466
    ChardevCommon *common = qapi_ChardevUdp_base(udp);
4467
    QIOChannelSocket *sioc = qio_channel_socket_new();
G
Gerd Hoffmann 已提交
4468

4469
    if (qio_channel_socket_dgram_sync(sioc,
4470
                                      udp->local, udp->remote,
4471 4472
                                      errp) < 0) {
        object_unref(OBJECT(sioc));
G
Gerd Hoffmann 已提交
4473 4474
        return NULL;
    }
4475
    return qemu_chr_open_udp(sioc, common, errp);
G
Gerd Hoffmann 已提交
4476 4477
}

4478 4479 4480 4481
ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
                               Error **errp)
{
    ChardevReturn *ret = g_new0(ChardevReturn, 1);
4482
    CharDriverState *chr = NULL;
P
Paolo Bonzini 已提交
4483
    Error *local_err = NULL;
4484 4485
    GSList *i;
    CharDriver *cd;
4486 4487 4488 4489 4490 4491 4492 4493

    chr = qemu_chr_find(id);
    if (chr) {
        error_setg(errp, "Chardev '%s' already exists", id);
        g_free(ret);
        return NULL;
    }

4494 4495 4496
    for (i = backends; i; i = i->next) {
        cd = i->data;

4497
        if (cd->kind == backend->type) {
4498 4499 4500 4501 4502 4503 4504 4505 4506 4507
            chr = cd->create(id, backend, ret, &local_err);
            if (local_err) {
                error_propagate(errp, local_err);
                goto out_error;
            }
            break;
        }
    }

    if (chr == NULL) {
4508 4509 4510
        assert(!i);
        error_setg(errp, "chardev backend not available");
        goto out_error;
P
Paolo Bonzini 已提交
4511 4512 4513 4514
    }

    chr->label = g_strdup(id);
    chr->avail_connections =
4515
        (backend->type == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
P
Paolo Bonzini 已提交
4516
    if (!chr->filename) {
4517
        chr->filename = g_strdup(ChardevBackendKind_lookup[backend->type]);
4518
    }
P
Paolo Bonzini 已提交
4519 4520 4521 4522 4523 4524 4525 4526 4527
    if (!chr->explicit_be_open) {
        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
    }
    QTAILQ_INSERT_TAIL(&chardevs, chr, next);
    return ret;

out_error:
    g_free(ret);
    return NULL;
4528 4529 4530 4531 4532 4533 4534
}

void qmp_chardev_remove(const char *id, Error **errp)
{
    CharDriverState *chr;

    chr = qemu_chr_find(id);
G
Gonglei 已提交
4535
    if (chr == NULL) {
4536 4537 4538 4539 4540 4541 4542 4543
        error_setg(errp, "Chardev '%s' not found", id);
        return;
    }
    if (chr->chr_can_read || chr->chr_read ||
        chr->chr_event || chr->handler_opaque) {
        error_setg(errp, "Chardev '%s' is busy", id);
        return;
    }
P
Pavel Dovgalyuk 已提交
4544 4545 4546 4547 4548
    if (chr->replay) {
        error_setg(errp,
            "Chardev '%s' cannot be unplugged in record/replay mode", id);
        return;
    }
4549 4550
    qemu_chr_delete(chr);
}
4551 4552 4553

static void register_types(void)
{
4554
    register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL,
4555
                         qemu_chr_open_null);
4556
    register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET,
4557
                         qemu_chr_parse_socket, qmp_chardev_open_socket);
4558
    register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp,
4559
                         qmp_chardev_open_udp);
4560
    register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
4561
                         qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf);
4562
    register_char_driver("file", CHARDEV_BACKEND_KIND_FILE,
4563
                         qemu_chr_parse_file_out, qmp_chardev_open_file);
4564
    register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO,
4565
                         qemu_chr_parse_stdio, qemu_chr_open_stdio);
4566
#if defined HAVE_CHARDEV_SERIAL
4567
    register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL,
4568
                         qemu_chr_parse_serial, qmp_chardev_open_serial);
4569
    register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL,
4570 4571
                         qemu_chr_parse_serial, qmp_chardev_open_serial);
#endif
4572
#ifdef HAVE_CHARDEV_PARPORT
4573
    register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
4574
                         qemu_chr_parse_parallel, qmp_chardev_open_parallel);
4575
    register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL,
4576 4577
                         qemu_chr_parse_parallel, qmp_chardev_open_parallel);
#endif
4578
#ifdef HAVE_CHARDEV_PTY
4579
    register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL,
4580 4581
                         qemu_chr_open_pty);
#endif
4582
#ifdef _WIN32
4583
    register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL,
4584 4585
                         qemu_chr_open_win_con);
#endif
4586
    register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE,
4587
                         qemu_chr_parse_pipe, qemu_chr_open_pipe);
4588
    register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux,
4589
                         qemu_chr_open_mux);
4590
    /* Bug-compatibility: */
4591
    register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY,
4592
                         qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf);
4593 4594 4595 4596 4597
    /* this must be done after machine init, since we register FEs with muxes
     * as part of realize functions like serial_isa_realizefn when -nographic
     * is specified
     */
    qemu_add_machine_init_done_notifier(&muxes_realize_notify);
4598 4599 4600
}

type_init(register_types);