qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

test-char.c (48212B)


      1 #include "qemu/osdep.h"
      2 #include <glib/gstdio.h>
      3 
      4 #include "qemu/config-file.h"
      5 #include "qemu/module.h"
      6 #include "qemu/option.h"
      7 #include "qemu/sockets.h"
      8 #include "chardev/char-fe.h"
      9 #include "sysemu/sysemu.h"
     10 #include "qapi/error.h"
     11 #include "qapi/qapi-commands-char.h"
     12 #include "qapi/qmp/qdict.h"
     13 #include "qom/qom-qobject.h"
     14 #include "io/channel-socket.h"
     15 #include "qapi/qobject-input-visitor.h"
     16 #include "qapi/qapi-visit-sockets.h"
     17 #include "socket-helpers.h"
     18 
     19 static bool quit;
     20 
     21 typedef struct FeHandler {
     22     int read_count;
     23     bool is_open;
     24     int openclose_count;
     25     bool openclose_mismatch;
     26     int last_event;
     27     char read_buf[128];
     28 } FeHandler;
     29 
     30 static void main_loop(void)
     31 {
     32     quit = false;
     33     do {
     34         main_loop_wait(false);
     35     } while (!quit);
     36 }
     37 
     38 static int fe_can_read(void *opaque)
     39 {
     40     FeHandler *h = opaque;
     41 
     42     return sizeof(h->read_buf) - h->read_count;
     43 }
     44 
     45 static void fe_read(void *opaque, const uint8_t *buf, int size)
     46 {
     47     FeHandler *h = opaque;
     48 
     49     g_assert_cmpint(size, <=, fe_can_read(opaque));
     50 
     51     memcpy(h->read_buf + h->read_count, buf, size);
     52     h->read_count += size;
     53     quit = true;
     54 }
     55 
     56 static void fe_event(void *opaque, QEMUChrEvent event)
     57 {
     58     FeHandler *h = opaque;
     59     bool new_open_state;
     60 
     61     h->last_event = event;
     62     switch (event) {
     63     case CHR_EVENT_BREAK:
     64         break;
     65     case CHR_EVENT_OPENED:
     66     case CHR_EVENT_CLOSED:
     67         h->openclose_count++;
     68         new_open_state = (event == CHR_EVENT_OPENED);
     69         if (h->is_open == new_open_state) {
     70             h->openclose_mismatch = true;
     71         }
     72         h->is_open = new_open_state;
     73         /* fallthrough */
     74     default:
     75         quit = true;
     76         break;
     77     }
     78 }
     79 
     80 #ifdef _WIN32
     81 static void char_console_test_subprocess(void)
     82 {
     83     QemuOpts *opts;
     84     Chardev *chr;
     85 
     86     opts = qemu_opts_create(qemu_find_opts("chardev"), "console-label",
     87                             1, &error_abort);
     88     qemu_opt_set(opts, "backend", "console", &error_abort);
     89 
     90     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
     91     g_assert_nonnull(chr);
     92 
     93     qemu_chr_write_all(chr, (const uint8_t *)"CONSOLE", 7);
     94 
     95     qemu_opts_del(opts);
     96     object_unparent(OBJECT(chr));
     97 }
     98 
     99 static void char_console_test(void)
    100 {
    101     g_test_trap_subprocess("/char/console/subprocess", 0, 0);
    102     g_test_trap_assert_passed();
    103     g_test_trap_assert_stdout("CONSOLE");
    104 }
    105 #endif
    106 static void char_stdio_test_subprocess(void)
    107 {
    108     Chardev *chr;
    109     CharBackend be;
    110     int ret;
    111 
    112     chr = qemu_chr_new("label", "stdio", NULL);
    113     g_assert_nonnull(chr);
    114 
    115     qemu_chr_fe_init(&be, chr, &error_abort);
    116     qemu_chr_fe_set_open(&be, true);
    117     ret = qemu_chr_fe_write(&be, (void *)"buf", 4);
    118     g_assert_cmpint(ret, ==, 4);
    119 
    120     qemu_chr_fe_deinit(&be, true);
    121 }
    122 
    123 static void char_stdio_test(void)
    124 {
    125     g_test_trap_subprocess("/char/stdio/subprocess", 0, 0);
    126     g_test_trap_assert_passed();
    127     g_test_trap_assert_stdout("buf");
    128 }
    129 
    130 static void char_ringbuf_test(void)
    131 {
    132     QemuOpts *opts;
    133     Chardev *chr;
    134     CharBackend be;
    135     char *data;
    136     int ret;
    137 
    138     opts = qemu_opts_create(qemu_find_opts("chardev"), "ringbuf-label",
    139                             1, &error_abort);
    140     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
    141 
    142     qemu_opt_set(opts, "size", "5", &error_abort);
    143     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
    144     g_assert_null(chr);
    145     qemu_opts_del(opts);
    146 
    147     opts = qemu_opts_create(qemu_find_opts("chardev"), "ringbuf-label",
    148                             1, &error_abort);
    149     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
    150     qemu_opt_set(opts, "size", "2", &error_abort);
    151     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
    152     g_assert_nonnull(chr);
    153     qemu_opts_del(opts);
    154 
    155     qemu_chr_fe_init(&be, chr, &error_abort);
    156     ret = qemu_chr_fe_write(&be, (void *)"buff", 4);
    157     g_assert_cmpint(ret, ==, 4);
    158 
    159     data = qmp_ringbuf_read("ringbuf-label", 4, false, 0, &error_abort);
    160     g_assert_cmpstr(data, ==, "ff");
    161     g_free(data);
    162 
    163     data = qmp_ringbuf_read("ringbuf-label", 4, false, 0, &error_abort);
    164     g_assert_cmpstr(data, ==, "");
    165     g_free(data);
    166 
    167     qemu_chr_fe_deinit(&be, true);
    168 
    169     /* check alias */
    170     opts = qemu_opts_create(qemu_find_opts("chardev"), "memory-label",
    171                             1, &error_abort);
    172     qemu_opt_set(opts, "backend", "memory", &error_abort);
    173     qemu_opt_set(opts, "size", "2", &error_abort);
    174     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
    175     g_assert_nonnull(chr);
    176     object_unparent(OBJECT(chr));
    177     qemu_opts_del(opts);
    178 }
    179 
    180 static void char_mux_test(void)
    181 {
    182     QemuOpts *opts;
    183     Chardev *chr, *base;
    184     char *data;
    185     FeHandler h1 = { 0, false, 0, false, }, h2 = { 0, false, 0, false, };
    186     CharBackend chr_be1, chr_be2;
    187 
    188     opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
    189                             1, &error_abort);
    190     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
    191     qemu_opt_set(opts, "size", "128", &error_abort);
    192     qemu_opt_set(opts, "mux", "on", &error_abort);
    193     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
    194     g_assert_nonnull(chr);
    195     qemu_opts_del(opts);
    196 
    197     qemu_chr_fe_init(&chr_be1, chr, &error_abort);
    198     qemu_chr_fe_set_handlers(&chr_be1,
    199                              fe_can_read,
    200                              fe_read,
    201                              fe_event,
    202                              NULL,
    203                              &h1,
    204                              NULL, true);
    205 
    206     qemu_chr_fe_init(&chr_be2, chr, &error_abort);
    207     qemu_chr_fe_set_handlers(&chr_be2,
    208                              fe_can_read,
    209                              fe_read,
    210                              fe_event,
    211                              NULL,
    212                              &h2,
    213                              NULL, true);
    214     qemu_chr_fe_take_focus(&chr_be2);
    215 
    216     base = qemu_chr_find("mux-label-base");
    217     g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);
    218 
    219     qemu_chr_be_write(base, (void *)"hello", 6);
    220     g_assert_cmpint(h1.read_count, ==, 0);
    221     g_assert_cmpint(h2.read_count, ==, 6);
    222     g_assert_cmpstr(h2.read_buf, ==, "hello");
    223     h2.read_count = 0;
    224 
    225     g_assert_cmpint(h1.last_event, !=, 42); /* should be MUX_OUT or OPENED */
    226     g_assert_cmpint(h2.last_event, !=, 42); /* should be MUX_IN or OPENED */
    227     /* sending event on the base broadcast to all fe, historical reasons? */
    228     qemu_chr_be_event(base, 42);
    229     g_assert_cmpint(h1.last_event, ==, 42);
    230     g_assert_cmpint(h2.last_event, ==, 42);
    231     qemu_chr_be_event(chr, -1);
    232     g_assert_cmpint(h1.last_event, ==, 42);
    233     g_assert_cmpint(h2.last_event, ==, -1);
    234 
    235     /* switch focus */
    236     qemu_chr_be_write(base, (void *)"\1b", 2);
    237     g_assert_cmpint(h1.last_event, ==, 42);
    238     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_BREAK);
    239 
    240     qemu_chr_be_write(base, (void *)"\1c", 2);
    241     g_assert_cmpint(h1.last_event, ==, CHR_EVENT_MUX_IN);
    242     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
    243     qemu_chr_be_event(chr, -1);
    244     g_assert_cmpint(h1.last_event, ==, -1);
    245     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
    246 
    247     qemu_chr_be_write(base, (void *)"hello", 6);
    248     g_assert_cmpint(h2.read_count, ==, 0);
    249     g_assert_cmpint(h1.read_count, ==, 6);
    250     g_assert_cmpstr(h1.read_buf, ==, "hello");
    251     h1.read_count = 0;
    252 
    253     qemu_chr_be_write(base, (void *)"\1b", 2);
    254     g_assert_cmpint(h1.last_event, ==, CHR_EVENT_BREAK);
    255     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
    256 
    257     /* open/close state and corresponding events */
    258     g_assert_true(qemu_chr_fe_backend_open(&chr_be1));
    259     g_assert_true(qemu_chr_fe_backend_open(&chr_be2));
    260     g_assert_true(h1.is_open);
    261     g_assert_false(h1.openclose_mismatch);
    262     g_assert_true(h2.is_open);
    263     g_assert_false(h2.openclose_mismatch);
    264 
    265     h1.openclose_count = h2.openclose_count = 0;
    266 
    267     qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
    268                              NULL, NULL, false);
    269     qemu_chr_fe_set_handlers(&chr_be2, NULL, NULL, NULL, NULL,
    270                              NULL, NULL, false);
    271     g_assert_cmpint(h1.openclose_count, ==, 0);
    272     g_assert_cmpint(h2.openclose_count, ==, 0);
    273 
    274     h1.is_open = h2.is_open = false;
    275     qemu_chr_fe_set_handlers(&chr_be1,
    276                              NULL,
    277                              NULL,
    278                              fe_event,
    279                              NULL,
    280                              &h1,
    281                              NULL, false);
    282     qemu_chr_fe_set_handlers(&chr_be2,
    283                              NULL,
    284                              NULL,
    285                              fe_event,
    286                              NULL,
    287                              &h2,
    288                              NULL, false);
    289     g_assert_cmpint(h1.openclose_count, ==, 1);
    290     g_assert_false(h1.openclose_mismatch);
    291     g_assert_cmpint(h2.openclose_count, ==, 1);
    292     g_assert_false(h2.openclose_mismatch);
    293 
    294     qemu_chr_be_event(base, CHR_EVENT_CLOSED);
    295     qemu_chr_be_event(base, CHR_EVENT_OPENED);
    296     g_assert_cmpint(h1.openclose_count, ==, 3);
    297     g_assert_false(h1.openclose_mismatch);
    298     g_assert_cmpint(h2.openclose_count, ==, 3);
    299     g_assert_false(h2.openclose_mismatch);
    300 
    301     qemu_chr_fe_set_handlers(&chr_be2,
    302                              fe_can_read,
    303                              fe_read,
    304                              fe_event,
    305                              NULL,
    306                              &h2,
    307                              NULL, false);
    308     qemu_chr_fe_set_handlers(&chr_be1,
    309                              fe_can_read,
    310                              fe_read,
    311                              fe_event,
    312                              NULL,
    313                              &h1,
    314                              NULL, false);
    315 
    316     /* remove first handler */
    317     qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
    318                              NULL, NULL, true);
    319     qemu_chr_be_write(base, (void *)"hello", 6);
    320     g_assert_cmpint(h1.read_count, ==, 0);
    321     g_assert_cmpint(h2.read_count, ==, 0);
    322 
    323     qemu_chr_be_write(base, (void *)"\1c", 2);
    324     qemu_chr_be_write(base, (void *)"hello", 6);
    325     g_assert_cmpint(h1.read_count, ==, 0);
    326     g_assert_cmpint(h2.read_count, ==, 6);
    327     g_assert_cmpstr(h2.read_buf, ==, "hello");
    328     h2.read_count = 0;
    329 
    330     /* print help */
    331     qemu_chr_be_write(base, (void *)"\1?", 2);
    332     data = qmp_ringbuf_read("mux-label-base", 128, false, 0, &error_abort);
    333     g_assert_cmpint(strlen(data), !=, 0);
    334     g_free(data);
    335 
    336     qemu_chr_fe_deinit(&chr_be1, false);
    337     qemu_chr_fe_deinit(&chr_be2, true);
    338 }
    339 
    340 
    341 static void websock_server_read(void *opaque, const uint8_t *buf, int size)
    342 {
    343     g_assert_cmpint(size, ==, 5);
    344     g_assert(memcmp(buf, "world", size) == 0);
    345     quit = true;
    346 }
    347 
    348 
    349 static int websock_server_can_read(void *opaque)
    350 {
    351     return 10;
    352 }
    353 
    354 
    355 static bool websock_check_http_headers(char *buf, int size)
    356 {
    357     int i;
    358     const char *ans[] = { "HTTP/1.1 101 Switching Protocols\r\n",
    359                           "Server: QEMU VNC\r\n",
    360                           "Upgrade: websocket\r\n",
    361                           "Connection: Upgrade\r\n",
    362                           "Sec-WebSocket-Accept:",
    363                           "Sec-WebSocket-Protocol: binary\r\n" };
    364 
    365     for (i = 0; i < 6; i++) {
    366         if (g_strstr_len(buf, size, ans[i]) == NULL) {
    367             return false;
    368         }
    369     }
    370 
    371     return true;
    372 }
    373 
    374 
    375 static void websock_client_read(void *opaque, const uint8_t *buf, int size)
    376 {
    377     const uint8_t ping[] = { 0x89, 0x85,                  /* Ping header */
    378                              0x07, 0x77, 0x9e, 0xf9,      /* Masking key */
    379                              0x6f, 0x12, 0xf2, 0x95, 0x68 /* "hello" */ };
    380 
    381     const uint8_t binary[] = { 0x82, 0x85,                  /* Binary header */
    382                                0x74, 0x90, 0xb9, 0xdf,      /* Masking key */
    383                                0x03, 0xff, 0xcb, 0xb3, 0x10 /* "world" */ };
    384     Chardev *chr_client = opaque;
    385 
    386     if (websock_check_http_headers((char *) buf, size)) {
    387         qemu_chr_fe_write(chr_client->be, ping, sizeof(ping));
    388     } else if (buf[0] == 0x8a && buf[1] == 0x05) {
    389         g_assert(strncmp((char *) buf + 2, "hello", 5) == 0);
    390         qemu_chr_fe_write(chr_client->be, binary, sizeof(binary));
    391     } else {
    392         g_assert(buf[0] == 0x88 && buf[1] == 0x16);
    393         g_assert(strncmp((char *) buf + 4, "peer requested close", 10) == 0);
    394         quit = true;
    395     }
    396 }
    397 
    398 
    399 static int websock_client_can_read(void *opaque)
    400 {
    401     return 4096;
    402 }
    403 
    404 
    405 static void char_websock_test(void)
    406 {
    407     QObject *addr;
    408     QDict *qdict;
    409     const char *port;
    410     char *tmp;
    411     char *handshake_port;
    412     CharBackend be;
    413     CharBackend client_be;
    414     Chardev *chr_client;
    415     Chardev *chr = qemu_chr_new("server",
    416                                 "websocket:127.0.0.1:0,server=on,wait=off", NULL);
    417     const char handshake[] = "GET / HTTP/1.1\r\n"
    418                              "Upgrade: websocket\r\n"
    419                              "Connection: Upgrade\r\n"
    420                              "Host: localhost:%s\r\n"
    421                              "Origin: http://localhost:%s\r\n"
    422                              "Sec-WebSocket-Key: o9JHNiS3/0/0zYE1wa3yIw==\r\n"
    423                              "Sec-WebSocket-Version: 13\r\n"
    424                              "Sec-WebSocket-Protocol: binary\r\n\r\n";
    425     const uint8_t close[] = { 0x88, 0x82,             /* Close header */
    426                               0xef, 0xaa, 0xc5, 0x97, /* Masking key */
    427                               0xec, 0x42              /* Status code */ };
    428 
    429     addr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
    430     qdict = qobject_to(QDict, addr);
    431     port = qdict_get_str(qdict, "port");
    432     tmp = g_strdup_printf("tcp:127.0.0.1:%s", port);
    433     handshake_port = g_strdup_printf(handshake, port, port);
    434     qobject_unref(qdict);
    435 
    436     qemu_chr_fe_init(&be, chr, &error_abort);
    437     qemu_chr_fe_set_handlers(&be, websock_server_can_read, websock_server_read,
    438                              NULL, NULL, chr, NULL, true);
    439 
    440     chr_client = qemu_chr_new("client", tmp, NULL);
    441     qemu_chr_fe_init(&client_be, chr_client, &error_abort);
    442     qemu_chr_fe_set_handlers(&client_be, websock_client_can_read,
    443                              websock_client_read,
    444                              NULL, NULL, chr_client, NULL, true);
    445     g_free(tmp);
    446 
    447     qemu_chr_write_all(chr_client,
    448                        (uint8_t *) handshake_port,
    449                        strlen(handshake_port));
    450     g_free(handshake_port);
    451     main_loop();
    452 
    453     g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
    454     g_assert(object_property_get_bool(OBJECT(chr_client),
    455                                       "connected", &error_abort));
    456 
    457     qemu_chr_write_all(chr_client, close, sizeof(close));
    458     main_loop();
    459 
    460     object_unparent(OBJECT(chr_client));
    461     object_unparent(OBJECT(chr));
    462 }
    463 
    464 
    465 #ifndef _WIN32
    466 static void char_pipe_test(void)
    467 {
    468     gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
    469     gchar *tmp, *in, *out, *pipe = g_build_filename(tmp_path, "pipe", NULL);
    470     Chardev *chr;
    471     CharBackend be;
    472     int ret, fd;
    473     char buf[10];
    474     FeHandler fe = { 0, };
    475 
    476     in = g_strdup_printf("%s.in", pipe);
    477     if (mkfifo(in, 0600) < 0) {
    478         abort();
    479     }
    480     out = g_strdup_printf("%s.out", pipe);
    481     if (mkfifo(out, 0600) < 0) {
    482         abort();
    483     }
    484 
    485     tmp = g_strdup_printf("pipe:%s", pipe);
    486     chr = qemu_chr_new("pipe", tmp, NULL);
    487     g_assert_nonnull(chr);
    488     g_free(tmp);
    489 
    490     qemu_chr_fe_init(&be, chr, &error_abort);
    491 
    492     ret = qemu_chr_fe_write(&be, (void *)"pipe-out", 9);
    493     g_assert_cmpint(ret, ==, 9);
    494 
    495     fd = open(out, O_RDWR);
    496     ret = read(fd, buf, sizeof(buf));
    497     g_assert_cmpint(ret, ==, 9);
    498     g_assert_cmpstr(buf, ==, "pipe-out");
    499     close(fd);
    500 
    501     fd = open(in, O_WRONLY);
    502     ret = write(fd, "pipe-in", 8);
    503     g_assert_cmpint(ret, ==, 8);
    504     close(fd);
    505 
    506     qemu_chr_fe_set_handlers(&be,
    507                              fe_can_read,
    508                              fe_read,
    509                              fe_event,
    510                              NULL,
    511                              &fe,
    512                              NULL, true);
    513 
    514     main_loop();
    515 
    516     g_assert_cmpint(fe.read_count, ==, 8);
    517     g_assert_cmpstr(fe.read_buf, ==, "pipe-in");
    518 
    519     qemu_chr_fe_deinit(&be, true);
    520 
    521     g_assert(g_unlink(in) == 0);
    522     g_assert(g_unlink(out) == 0);
    523     g_assert(g_rmdir(tmp_path) == 0);
    524     g_free(in);
    525     g_free(out);
    526     g_free(tmp_path);
    527     g_free(pipe);
    528 }
    529 #endif
    530 
    531 typedef struct SocketIdleData {
    532     GMainLoop *loop;
    533     Chardev *chr;
    534     bool conn_expected;
    535     CharBackend *be;
    536     CharBackend *client_be;
    537 } SocketIdleData;
    538 
    539 
    540 static void socket_read_hello(void *opaque, const uint8_t *buf, int size)
    541 {
    542     g_assert_cmpint(size, ==, 5);
    543     g_assert(strncmp((char *)buf, "hello", 5) == 0);
    544 
    545     quit = true;
    546 }
    547 
    548 static int socket_can_read_hello(void *opaque)
    549 {
    550     return 10;
    551 }
    552 
    553 static int make_udp_socket(int *port)
    554 {
    555     struct sockaddr_in addr = { 0, };
    556     socklen_t alen = sizeof(addr);
    557     int ret, sock = qemu_socket(PF_INET, SOCK_DGRAM, 0);
    558 
    559     g_assert_cmpint(sock, >, 0);
    560     addr.sin_family = AF_INET ;
    561     addr.sin_addr.s_addr = htonl(INADDR_ANY);
    562     addr.sin_port = 0;
    563     ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
    564     g_assert_cmpint(ret, ==, 0);
    565     ret = getsockname(sock, (struct sockaddr *)&addr, &alen);
    566     g_assert_cmpint(ret, ==, 0);
    567 
    568     *port = ntohs(addr.sin_port);
    569     return sock;
    570 }
    571 
    572 static void char_udp_test_internal(Chardev *reuse_chr, int sock)
    573 {
    574     struct sockaddr_in other;
    575     SocketIdleData d = { 0, };
    576     Chardev *chr;
    577     CharBackend *be;
    578     socklen_t alen = sizeof(other);
    579     int ret;
    580     char buf[10];
    581     char *tmp = NULL;
    582 
    583     if (reuse_chr) {
    584         chr = reuse_chr;
    585         be = chr->be;
    586     } else {
    587         int port;
    588         sock = make_udp_socket(&port);
    589         tmp = g_strdup_printf("udp:127.0.0.1:%d", port);
    590         chr = qemu_chr_new("client", tmp, NULL);
    591         g_assert_nonnull(chr);
    592 
    593         be = g_alloca(sizeof(CharBackend));
    594         qemu_chr_fe_init(be, chr, &error_abort);
    595     }
    596 
    597     d.chr = chr;
    598     qemu_chr_fe_set_handlers(be, socket_can_read_hello, socket_read_hello,
    599                              NULL, NULL, &d, NULL, true);
    600     ret = qemu_chr_write_all(chr, (uint8_t *)"hello", 5);
    601     g_assert_cmpint(ret, ==, 5);
    602 
    603     ret = recvfrom(sock, buf, sizeof(buf), 0,
    604                    (struct sockaddr *)&other, &alen);
    605     g_assert_cmpint(ret, ==, 5);
    606     ret = sendto(sock, buf, 5, 0, (struct sockaddr *)&other, alen);
    607     g_assert_cmpint(ret, ==, 5);
    608 
    609     main_loop();
    610 
    611     if (!reuse_chr) {
    612         close(sock);
    613         qemu_chr_fe_deinit(be, true);
    614     }
    615     g_free(tmp);
    616 }
    617 
    618 static void char_udp_test(void)
    619 {
    620     char_udp_test_internal(NULL, 0);
    621 }
    622 
    623 
    624 typedef struct {
    625     int event;
    626     bool got_pong;
    627     CharBackend *be;
    628 } CharSocketTestData;
    629 
    630 
    631 #define SOCKET_PING "Hello"
    632 #define SOCKET_PONG "World"
    633 
    634 typedef void (*char_socket_cb)(void *opaque, QEMUChrEvent event);
    635 
    636 static void
    637 char_socket_event(void *opaque, QEMUChrEvent event)
    638 {
    639     CharSocketTestData *data = opaque;
    640     data->event = event;
    641 }
    642 
    643 static void
    644 char_socket_event_with_error(void *opaque, QEMUChrEvent event)
    645 {
    646     static bool first_error;
    647     CharSocketTestData *data = opaque;
    648     CharBackend *be = data->be;
    649     data->event = event;
    650     switch (event) {
    651     case CHR_EVENT_OPENED:
    652         if (!first_error) {
    653             first_error = true;
    654             qemu_chr_fe_disconnect(be);
    655         }
    656         return;
    657     case CHR_EVENT_CLOSED:
    658         return;
    659     default:
    660         return;
    661     }
    662 }
    663 
    664 
    665 static void
    666 char_socket_read(void *opaque, const uint8_t *buf, int size)
    667 {
    668     CharSocketTestData *data = opaque;
    669     g_assert_cmpint(size, ==, sizeof(SOCKET_PONG));
    670     g_assert(memcmp(buf, SOCKET_PONG, size) == 0);
    671     data->got_pong = true;
    672 }
    673 
    674 
    675 static int
    676 char_socket_can_read(void *opaque)
    677 {
    678     return sizeof(SOCKET_PONG);
    679 }
    680 
    681 
    682 static char *
    683 char_socket_addr_to_opt_str(SocketAddress *addr, bool fd_pass,
    684                             const char *reconnect, bool is_listen)
    685 {
    686     if (fd_pass) {
    687         QIOChannelSocket *ioc = qio_channel_socket_new();
    688         int fd;
    689         char *optstr;
    690         g_assert(!reconnect);
    691         if (is_listen) {
    692             qio_channel_socket_listen_sync(ioc, addr, 1, &error_abort);
    693         } else {
    694             qio_channel_socket_connect_sync(ioc, addr, &error_abort);
    695         }
    696         fd = ioc->fd;
    697         ioc->fd = -1;
    698         optstr = g_strdup_printf("socket,id=cdev0,fd=%d%s",
    699                                  fd, is_listen ? ",server=on,wait=off" : "");
    700         object_unref(OBJECT(ioc));
    701         return optstr;
    702     } else {
    703         switch (addr->type) {
    704         case SOCKET_ADDRESS_TYPE_INET:
    705             return g_strdup_printf("socket,id=cdev0,host=%s,port=%s%s%s",
    706                                    addr->u.inet.host,
    707                                    addr->u.inet.port,
    708                                    reconnect ? reconnect : "",
    709                                    is_listen ? ",server=on,wait=off" : "");
    710 
    711         case SOCKET_ADDRESS_TYPE_UNIX:
    712             return g_strdup_printf("socket,id=cdev0,path=%s%s%s",
    713                                    addr->u.q_unix.path,
    714                                    reconnect ? reconnect : "",
    715                                    is_listen ? ",server=on,wait=off" : "");
    716 
    717         default:
    718             g_assert_not_reached();
    719         }
    720     }
    721 }
    722 
    723 
    724 static int
    725 char_socket_ping_pong(QIOChannel *ioc, Error **errp)
    726 {
    727     char greeting[sizeof(SOCKET_PING)];
    728     const char *response = SOCKET_PONG;
    729 
    730     int ret;
    731     ret = qio_channel_read_all(ioc, greeting, sizeof(greeting), errp);
    732     if (ret != 0) {
    733         object_unref(OBJECT(ioc));
    734         return -1;
    735     }
    736 
    737     g_assert(memcmp(greeting, SOCKET_PING, sizeof(greeting)) == 0);
    738 
    739     qio_channel_write_all(ioc, response, sizeof(SOCKET_PONG), errp);
    740     object_unref(OBJECT(ioc));
    741     return 0;
    742 }
    743 
    744 
    745 static gpointer
    746 char_socket_server_client_thread(gpointer data)
    747 {
    748     SocketAddress *addr = data;
    749     QIOChannelSocket *ioc = qio_channel_socket_new();
    750 
    751     qio_channel_socket_connect_sync(ioc, addr, &error_abort);
    752 
    753     char_socket_ping_pong(QIO_CHANNEL(ioc), &error_abort);
    754 
    755     return NULL;
    756 }
    757 
    758 
    759 typedef struct {
    760     SocketAddress *addr;
    761     bool wait_connected;
    762     bool fd_pass;
    763 } CharSocketServerTestConfig;
    764 
    765 
    766 static void char_socket_server_test(gconstpointer opaque)
    767 {
    768     const CharSocketServerTestConfig *config = opaque;
    769     Chardev *chr;
    770     CharBackend be = {0};
    771     CharSocketTestData data = {0};
    772     QObject *qaddr;
    773     SocketAddress *addr;
    774     Visitor *v;
    775     QemuThread thread;
    776     int ret;
    777     bool reconnected = false;
    778     char *optstr;
    779     QemuOpts *opts;
    780 
    781     g_setenv("QTEST_SILENT_ERRORS", "1", 1);
    782     /*
    783      * We rely on config->addr containing "wait=off", otherwise
    784      * qemu_chr_new() will block until a client connects. We
    785      * can't spawn our client thread though, because until
    786      * qemu_chr_new() returns we don't know what TCP port was
    787      * allocated by the OS
    788      */
    789     optstr = char_socket_addr_to_opt_str(config->addr,
    790                                          config->fd_pass,
    791                                          NULL,
    792                                          true);
    793     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
    794                                    optstr, true);
    795     g_assert_nonnull(opts);
    796     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
    797     qemu_opts_del(opts);
    798     g_assert_nonnull(chr);
    799     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
    800 
    801     qaddr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
    802     g_assert_nonnull(qaddr);
    803 
    804     v = qobject_input_visitor_new(qaddr);
    805     visit_type_SocketAddress(v, "addr", &addr, &error_abort);
    806     visit_free(v);
    807     qobject_unref(qaddr);
    808 
    809     qemu_chr_fe_init(&be, chr, &error_abort);
    810 
    811  reconnect:
    812     data.event = -1;
    813     data.be = &be;
    814     qemu_chr_fe_set_handlers(&be, NULL, NULL,
    815                              char_socket_event, NULL,
    816                              &data, NULL, true);
    817     g_assert(data.event == -1);
    818 
    819     /*
    820      * Kick off a thread to act as the "remote" client
    821      * which just plays ping-pong with us
    822      */
    823     qemu_thread_create(&thread, "client",
    824                        char_socket_server_client_thread,
    825                        addr, QEMU_THREAD_JOINABLE);
    826     g_assert(data.event == -1);
    827 
    828     if (config->wait_connected) {
    829         /* Synchronously accept a connection */
    830         qemu_chr_wait_connected(chr, &error_abort);
    831     } else {
    832         /*
    833          * Asynchronously accept a connection when the evnt
    834          * loop reports the listener socket as readable
    835          */
    836         while (data.event == -1) {
    837             main_loop_wait(false);
    838         }
    839     }
    840     g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
    841     g_assert(data.event == CHR_EVENT_OPENED);
    842     data.event = -1;
    843 
    844     /* Send a greeting to the client */
    845     ret = qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING,
    846                                 sizeof(SOCKET_PING));
    847     g_assert_cmpint(ret, ==, sizeof(SOCKET_PING));
    848     g_assert(data.event == -1);
    849 
    850     /* Setup a callback to receive the reply to our greeting */
    851     qemu_chr_fe_set_handlers(&be, char_socket_can_read,
    852                              char_socket_read,
    853                              char_socket_event, NULL,
    854                              &data, NULL, true);
    855     g_assert(data.event == CHR_EVENT_OPENED);
    856     data.event = -1;
    857 
    858     /* Wait for the client to go away */
    859     while (data.event == -1) {
    860         main_loop_wait(false);
    861     }
    862     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
    863     g_assert(data.event == CHR_EVENT_CLOSED);
    864     g_assert(data.got_pong);
    865 
    866     qemu_thread_join(&thread);
    867 
    868     if (!reconnected) {
    869         reconnected = true;
    870         goto reconnect;
    871     }
    872 
    873     qapi_free_SocketAddress(addr);
    874     object_unparent(OBJECT(chr));
    875     g_free(optstr);
    876     g_unsetenv("QTEST_SILENT_ERRORS");
    877 }
    878 
    879 
    880 static gpointer
    881 char_socket_client_server_thread(gpointer data)
    882 {
    883     QIOChannelSocket *ioc = data;
    884     QIOChannelSocket *cioc;
    885 
    886 retry:
    887     cioc = qio_channel_socket_accept(ioc, &error_abort);
    888     g_assert_nonnull(cioc);
    889 
    890     if (char_socket_ping_pong(QIO_CHANNEL(cioc), NULL) != 0) {
    891         goto retry;
    892     }
    893 
    894     return NULL;
    895 }
    896 
    897 
    898 typedef struct {
    899     SocketAddress *addr;
    900     const char *reconnect;
    901     bool wait_connected;
    902     bool fd_pass;
    903     char_socket_cb event_cb;
    904 } CharSocketClientTestConfig;
    905 
    906 static void char_socket_client_dupid_test(gconstpointer opaque)
    907 {
    908     const CharSocketClientTestConfig *config = opaque;
    909     QIOChannelSocket *ioc;
    910     char *optstr;
    911     Chardev *chr1, *chr2;
    912     SocketAddress *addr;
    913     QemuOpts *opts;
    914     Error *local_err = NULL;
    915 
    916     /*
    917      * Setup a listener socket and determine get its address
    918      * so we know the TCP port for the client later
    919      */
    920     ioc = qio_channel_socket_new();
    921     g_assert_nonnull(ioc);
    922     qio_channel_socket_listen_sync(ioc, config->addr, 1, &error_abort);
    923     addr = qio_channel_socket_get_local_address(ioc, &error_abort);
    924     g_assert_nonnull(addr);
    925 
    926     /*
    927      * Populate the chardev address based on what the server
    928      * is actually listening on
    929      */
    930     optstr = char_socket_addr_to_opt_str(addr,
    931                                          config->fd_pass,
    932                                          config->reconnect,
    933                                          false);
    934 
    935     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
    936                                    optstr, true);
    937     g_assert_nonnull(opts);
    938     chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort);
    939     g_assert_nonnull(chr1);
    940     qemu_chr_wait_connected(chr1, &error_abort);
    941 
    942     chr2 = qemu_chr_new_from_opts(opts, NULL, &local_err);
    943     g_assert_null(chr2);
    944     error_free_or_abort(&local_err);
    945 
    946     object_unref(OBJECT(ioc));
    947     qemu_opts_del(opts);
    948     object_unparent(OBJECT(chr1));
    949     qapi_free_SocketAddress(addr);
    950     g_free(optstr);
    951 }
    952 
    953 static void char_socket_client_test(gconstpointer opaque)
    954 {
    955     const CharSocketClientTestConfig *config = opaque;
    956     const char_socket_cb event_cb = config->event_cb;
    957     QIOChannelSocket *ioc;
    958     char *optstr;
    959     Chardev *chr;
    960     CharBackend be = {0};
    961     CharSocketTestData data = {0};
    962     SocketAddress *addr;
    963     QemuThread thread;
    964     int ret;
    965     bool reconnected = false;
    966     QemuOpts *opts;
    967 
    968     /*
    969      * Setup a listener socket and determine get its address
    970      * so we know the TCP port for the client later
    971      */
    972     ioc = qio_channel_socket_new();
    973     g_assert_nonnull(ioc);
    974     qio_channel_socket_listen_sync(ioc, config->addr, 1, &error_abort);
    975     addr = qio_channel_socket_get_local_address(ioc, &error_abort);
    976     g_assert_nonnull(addr);
    977 
    978     /*
    979      * Kick off a thread to act as the "remote" client
    980      * which just plays ping-pong with us
    981      */
    982     qemu_thread_create(&thread, "client",
    983                        char_socket_client_server_thread,
    984                        ioc, QEMU_THREAD_JOINABLE);
    985 
    986     /*
    987      * Populate the chardev address based on what the server
    988      * is actually listening on
    989      */
    990     optstr = char_socket_addr_to_opt_str(addr,
    991                                          config->fd_pass,
    992                                          config->reconnect,
    993                                          false);
    994 
    995     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
    996                                    optstr, true);
    997     g_assert_nonnull(opts);
    998     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
    999     qemu_opts_del(opts);
   1000     g_assert_nonnull(chr);
   1001 
   1002     if (config->reconnect) {
   1003         /*
   1004          * If reconnect is set, the connection will be
   1005          * established in a background thread and we won't
   1006          * see the "connected" status updated until we
   1007          * run the main event loop, or call qemu_chr_wait_connected
   1008          */
   1009         g_assert(!object_property_get_bool(OBJECT(chr), "connected",
   1010                                            &error_abort));
   1011     } else {
   1012         g_assert(object_property_get_bool(OBJECT(chr), "connected",
   1013                                           &error_abort));
   1014     }
   1015 
   1016     qemu_chr_fe_init(&be, chr, &error_abort);
   1017 
   1018  reconnect:
   1019     data.event = -1;
   1020     data.be = &be;
   1021     qemu_chr_fe_set_handlers(&be, NULL, NULL,
   1022                              event_cb, NULL,
   1023                              &data, NULL, true);
   1024     if (config->reconnect) {
   1025         g_assert(data.event == -1);
   1026     } else {
   1027         g_assert(data.event == CHR_EVENT_OPENED);
   1028     }
   1029 
   1030     if (config->wait_connected) {
   1031         /*
   1032          * Synchronously wait for the connection to complete
   1033          * This should be a no-op if reconnect is not set.
   1034          */
   1035         qemu_chr_wait_connected(chr, &error_abort);
   1036     } else {
   1037         /*
   1038          * Asynchronously wait for the connection to be reported
   1039          * as complete when the background thread reports its
   1040          * status.
   1041          * The loop will short-circuit if reconnect was set
   1042          */
   1043         while (data.event == -1) {
   1044             main_loop_wait(false);
   1045         }
   1046     }
   1047     g_assert(data.event == CHR_EVENT_OPENED);
   1048     data.event = -1;
   1049     g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
   1050 
   1051     /* Send a greeting to the server */
   1052     ret = qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING,
   1053                                 sizeof(SOCKET_PING));
   1054     g_assert_cmpint(ret, ==, sizeof(SOCKET_PING));
   1055     g_assert(data.event == -1);
   1056 
   1057     /* Setup a callback to receive the reply to our greeting */
   1058     qemu_chr_fe_set_handlers(&be, char_socket_can_read,
   1059                              char_socket_read,
   1060                              event_cb, NULL,
   1061                              &data, NULL, true);
   1062     g_assert(data.event == CHR_EVENT_OPENED);
   1063     data.event = -1;
   1064 
   1065     /* Wait for the server to go away */
   1066     while (data.event == -1) {
   1067         main_loop_wait(false);
   1068     }
   1069     g_assert(data.event == CHR_EVENT_CLOSED);
   1070     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
   1071     g_assert(data.got_pong);
   1072     qemu_thread_join(&thread);
   1073 
   1074     if (config->reconnect && !reconnected) {
   1075         reconnected = true;
   1076         qemu_thread_create(&thread, "client",
   1077                            char_socket_client_server_thread,
   1078                            ioc, QEMU_THREAD_JOINABLE);
   1079         goto reconnect;
   1080     }
   1081 
   1082     object_unref(OBJECT(ioc));
   1083     object_unparent(OBJECT(chr));
   1084     qapi_free_SocketAddress(addr);
   1085     g_free(optstr);
   1086 }
   1087 
   1088 static void
   1089 count_closed_event(void *opaque, QEMUChrEvent event)
   1090 {
   1091     int *count = opaque;
   1092     if (event == CHR_EVENT_CLOSED) {
   1093         (*count)++;
   1094     }
   1095 }
   1096 
   1097 static void
   1098 char_socket_discard_read(void *opaque, const uint8_t *buf, int size)
   1099 {
   1100 }
   1101 
   1102 static void char_socket_server_two_clients_test(gconstpointer opaque)
   1103 {
   1104     SocketAddress *incoming_addr = (gpointer) opaque;
   1105     Chardev *chr;
   1106     CharBackend be = {0};
   1107     QObject *qaddr;
   1108     SocketAddress *addr;
   1109     Visitor *v;
   1110     char *optstr;
   1111     QemuOpts *opts;
   1112     QIOChannelSocket *ioc1, *ioc2;
   1113     int closed = 0;
   1114 
   1115     g_setenv("QTEST_SILENT_ERRORS", "1", 1);
   1116     /*
   1117      * We rely on addr containing "wait=off", otherwise
   1118      * qemu_chr_new() will block until a client connects. We
   1119      * can't spawn our client thread though, because until
   1120      * qemu_chr_new() returns we don't know what TCP port was
   1121      * allocated by the OS
   1122      */
   1123     optstr = char_socket_addr_to_opt_str(incoming_addr,
   1124                                          false,
   1125                                          NULL,
   1126                                          true);
   1127     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
   1128                                    optstr, true);
   1129     g_assert_nonnull(opts);
   1130     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
   1131     qemu_opts_del(opts);
   1132     g_assert_nonnull(chr);
   1133     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
   1134 
   1135     qaddr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
   1136     g_assert_nonnull(qaddr);
   1137 
   1138     v = qobject_input_visitor_new(qaddr);
   1139     visit_type_SocketAddress(v, "addr", &addr, &error_abort);
   1140     visit_free(v);
   1141     qobject_unref(qaddr);
   1142 
   1143     qemu_chr_fe_init(&be, chr, &error_abort);
   1144 
   1145     qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
   1146                              count_closed_event, NULL,
   1147                              &closed, NULL, true);
   1148 
   1149     ioc1 = qio_channel_socket_new();
   1150     qio_channel_socket_connect_sync(ioc1, addr, &error_abort);
   1151     qemu_chr_wait_connected(chr, &error_abort);
   1152 
   1153     /* switch the chardev to another context */
   1154     GMainContext *ctx = g_main_context_new();
   1155     qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
   1156                              count_closed_event, NULL,
   1157                              &closed, ctx, true);
   1158 
   1159     /* Start a second connection while the first is still connected.
   1160      * It will be placed in the listen() backlog, and connect() will
   1161      * succeed immediately.
   1162      */
   1163     ioc2 = qio_channel_socket_new();
   1164     qio_channel_socket_connect_sync(ioc2, addr, &error_abort);
   1165 
   1166     object_unref(OBJECT(ioc1));
   1167     /* The two connections should now be processed serially.  */
   1168     while (g_main_context_iteration(ctx, TRUE)) {
   1169         if (closed == 1 && ioc2) {
   1170             object_unref(OBJECT(ioc2));
   1171             ioc2 = NULL;
   1172         }
   1173         if (closed == 2) {
   1174             break;
   1175         }
   1176     }
   1177 
   1178     qapi_free_SocketAddress(addr);
   1179     object_unparent(OBJECT(chr));
   1180     g_main_context_unref(ctx);
   1181     g_free(optstr);
   1182     g_unsetenv("QTEST_SILENT_ERRORS");
   1183 }
   1184 
   1185 
   1186 #if defined(HAVE_CHARDEV_SERIAL) && !defined(WIN32)
   1187 static void char_serial_test(void)
   1188 {
   1189     QemuOpts *opts;
   1190     Chardev *chr;
   1191 
   1192     opts = qemu_opts_create(qemu_find_opts("chardev"), "serial-id",
   1193                             1, &error_abort);
   1194     qemu_opt_set(opts, "backend", "serial", &error_abort);
   1195     qemu_opt_set(opts, "path", "/dev/null", &error_abort);
   1196 
   1197     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
   1198     g_assert_nonnull(chr);
   1199     /* TODO: add more tests with a pty */
   1200     object_unparent(OBJECT(chr));
   1201 
   1202     qemu_opts_del(opts);
   1203 }
   1204 #endif
   1205 
   1206 #ifndef _WIN32
   1207 static void char_file_fifo_test(void)
   1208 {
   1209     Chardev *chr;
   1210     CharBackend be;
   1211     char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
   1212     char *fifo = g_build_filename(tmp_path, "fifo", NULL);
   1213     char *out = g_build_filename(tmp_path, "out", NULL);
   1214     ChardevFile file = { .in = fifo,
   1215                          .has_in = true,
   1216                          .out = out };
   1217     ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
   1218                                .u.file.data = &file };
   1219     FeHandler fe = { 0, };
   1220     int fd, ret;
   1221 
   1222     if (mkfifo(fifo, 0600) < 0) {
   1223         abort();
   1224     }
   1225 
   1226     fd = open(fifo, O_RDWR);
   1227     ret = write(fd, "fifo-in", 8);
   1228     g_assert_cmpint(ret, ==, 8);
   1229 
   1230     chr = qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend,
   1231                            NULL, &error_abort);
   1232 
   1233     qemu_chr_fe_init(&be, chr, &error_abort);
   1234     qemu_chr_fe_set_handlers(&be,
   1235                              fe_can_read,
   1236                              fe_read,
   1237                              fe_event,
   1238                              NULL,
   1239                              &fe, NULL, true);
   1240 
   1241     g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK);
   1242     qmp_chardev_send_break("label-foo", NULL);
   1243     g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK);
   1244     qmp_chardev_send_break("label-file", NULL);
   1245     g_assert_cmpint(fe.last_event, ==, CHR_EVENT_BREAK);
   1246 
   1247     main_loop();
   1248 
   1249     close(fd);
   1250 
   1251     g_assert_cmpint(fe.read_count, ==, 8);
   1252     g_assert_cmpstr(fe.read_buf, ==, "fifo-in");
   1253 
   1254     qemu_chr_fe_deinit(&be, true);
   1255 
   1256     g_unlink(fifo);
   1257     g_free(fifo);
   1258     g_unlink(out);
   1259     g_free(out);
   1260     g_rmdir(tmp_path);
   1261     g_free(tmp_path);
   1262 }
   1263 #endif
   1264 
   1265 static void char_file_test_internal(Chardev *ext_chr, const char *filepath)
   1266 {
   1267     char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
   1268     char *out;
   1269     Chardev *chr;
   1270     char *contents = NULL;
   1271     ChardevFile file = {};
   1272     ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
   1273                                .u.file.data = &file };
   1274     gsize length;
   1275     int ret;
   1276 
   1277     if (ext_chr) {
   1278         chr = ext_chr;
   1279         out = g_strdup(filepath);
   1280         file.out = out;
   1281     } else {
   1282         out = g_build_filename(tmp_path, "out", NULL);
   1283         file.out = out;
   1284         chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend,
   1285                                NULL, &error_abort);
   1286     }
   1287     ret = qemu_chr_write_all(chr, (uint8_t *)"hello!", 6);
   1288     g_assert_cmpint(ret, ==, 6);
   1289 
   1290     ret = g_file_get_contents(out, &contents, &length, NULL);
   1291     g_assert(ret == TRUE);
   1292     g_assert_cmpint(length, ==, 6);
   1293     g_assert(strncmp(contents, "hello!", 6) == 0);
   1294 
   1295     if (!ext_chr) {
   1296         object_unparent(OBJECT(chr));
   1297         g_unlink(out);
   1298     }
   1299     g_free(contents);
   1300     g_rmdir(tmp_path);
   1301     g_free(tmp_path);
   1302     g_free(out);
   1303 }
   1304 
   1305 static void char_file_test(void)
   1306 {
   1307     char_file_test_internal(NULL, NULL);
   1308 }
   1309 
   1310 static void char_null_test(void)
   1311 {
   1312     Error *err = NULL;
   1313     Chardev *chr;
   1314     CharBackend be;
   1315     int ret;
   1316 
   1317     chr = qemu_chr_find("label-null");
   1318     g_assert_null(chr);
   1319 
   1320     chr = qemu_chr_new("label-null", "null", NULL);
   1321     chr = qemu_chr_find("label-null");
   1322     g_assert_nonnull(chr);
   1323 
   1324     g_assert(qemu_chr_has_feature(chr,
   1325                  QEMU_CHAR_FEATURE_FD_PASS) == false);
   1326     g_assert(qemu_chr_has_feature(chr,
   1327                  QEMU_CHAR_FEATURE_RECONNECTABLE) == false);
   1328 
   1329     /* check max avail */
   1330     qemu_chr_fe_init(&be, chr, &error_abort);
   1331     qemu_chr_fe_init(&be, chr, &err);
   1332     error_free_or_abort(&err);
   1333 
   1334     /* deinit & reinit */
   1335     qemu_chr_fe_deinit(&be, false);
   1336     qemu_chr_fe_init(&be, chr, &error_abort);
   1337 
   1338     qemu_chr_fe_set_open(&be, true);
   1339 
   1340     qemu_chr_fe_set_handlers(&be,
   1341                              fe_can_read,
   1342                              fe_read,
   1343                              fe_event,
   1344                              NULL,
   1345                              NULL, NULL, true);
   1346 
   1347     ret = qemu_chr_fe_write(&be, (void *)"buf", 4);
   1348     g_assert_cmpint(ret, ==, 4);
   1349 
   1350     qemu_chr_fe_deinit(&be, true);
   1351 }
   1352 
   1353 static void char_invalid_test(void)
   1354 {
   1355     Chardev *chr;
   1356     g_setenv("QTEST_SILENT_ERRORS", "1", 1);
   1357     chr = qemu_chr_new("label-invalid", "invalid", NULL);
   1358     g_assert_null(chr);
   1359     g_unsetenv("QTEST_SILENT_ERRORS");
   1360 }
   1361 
   1362 static int chardev_change(void *opaque)
   1363 {
   1364     return 0;
   1365 }
   1366 
   1367 static int chardev_change_denied(void *opaque)
   1368 {
   1369     return -1;
   1370 }
   1371 
   1372 static void char_hotswap_test(void)
   1373 {
   1374     char *chr_args;
   1375     Chardev *chr;
   1376     CharBackend be;
   1377 
   1378     gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
   1379     char *filename = g_build_filename(tmp_path, "file", NULL);
   1380     ChardevFile file = { .out = filename };
   1381     ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
   1382                                .u.file.data = &file };
   1383     ChardevReturn *ret;
   1384 
   1385     int port;
   1386     int sock = make_udp_socket(&port);
   1387     g_assert_cmpint(sock, >, 0);
   1388 
   1389     chr_args = g_strdup_printf("udp:127.0.0.1:%d", port);
   1390 
   1391     chr = qemu_chr_new("chardev", chr_args, NULL);
   1392     qemu_chr_fe_init(&be, chr, &error_abort);
   1393 
   1394     /* check that chardev operates correctly */
   1395     char_udp_test_internal(chr, sock);
   1396 
   1397     /* set the handler that denies the hotswap */
   1398     qemu_chr_fe_set_handlers(&be, NULL, NULL,
   1399                              NULL, chardev_change_denied, NULL, NULL, true);
   1400 
   1401     /* now, change is denied and has to keep the old backend operating */
   1402     ret = qmp_chardev_change("chardev", &backend, NULL);
   1403     g_assert(!ret);
   1404     g_assert(be.chr == chr);
   1405 
   1406     char_udp_test_internal(chr, sock);
   1407 
   1408     /* now allow the change */
   1409     qemu_chr_fe_set_handlers(&be, NULL, NULL,
   1410                              NULL, chardev_change, NULL, NULL, true);
   1411 
   1412     /* has to succeed now */
   1413     ret = qmp_chardev_change("chardev", &backend, &error_abort);
   1414     g_assert(be.chr != chr);
   1415 
   1416     close(sock);
   1417     chr = be.chr;
   1418 
   1419     /* run the file chardev test */
   1420     char_file_test_internal(chr, filename);
   1421 
   1422     object_unparent(OBJECT(chr));
   1423 
   1424     qapi_free_ChardevReturn(ret);
   1425     g_unlink(filename);
   1426     g_free(filename);
   1427     g_rmdir(tmp_path);
   1428     g_free(tmp_path);
   1429     g_free(chr_args);
   1430 }
   1431 
   1432 static SocketAddress tcpaddr = {
   1433     .type = SOCKET_ADDRESS_TYPE_INET,
   1434     .u.inet.host = (char *)"127.0.0.1",
   1435     .u.inet.port = (char *)"0",
   1436 };
   1437 #ifndef WIN32
   1438 static SocketAddress unixaddr = {
   1439     .type = SOCKET_ADDRESS_TYPE_UNIX,
   1440     .u.q_unix.path = (char *)"test-char.sock",
   1441 };
   1442 #endif
   1443 
   1444 int main(int argc, char **argv)
   1445 {
   1446     bool has_ipv4, has_ipv6;
   1447 
   1448     qemu_init_main_loop(&error_abort);
   1449     socket_init();
   1450 
   1451     g_test_init(&argc, &argv, NULL);
   1452 
   1453     if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) {
   1454         g_printerr("socket_check_protocol_support() failed\n");
   1455         goto end;
   1456     }
   1457 
   1458     module_call_init(MODULE_INIT_QOM);
   1459     qemu_add_opts(&qemu_chardev_opts);
   1460 
   1461     g_test_add_func("/char/null", char_null_test);
   1462     g_test_add_func("/char/invalid", char_invalid_test);
   1463     g_test_add_func("/char/ringbuf", char_ringbuf_test);
   1464     g_test_add_func("/char/mux", char_mux_test);
   1465 #ifdef _WIN32
   1466     g_test_add_func("/char/console/subprocess", char_console_test_subprocess);
   1467     g_test_add_func("/char/console", char_console_test);
   1468 #endif
   1469     g_test_add_func("/char/stdio/subprocess", char_stdio_test_subprocess);
   1470     g_test_add_func("/char/stdio", char_stdio_test);
   1471 #ifndef _WIN32
   1472     g_test_add_func("/char/pipe", char_pipe_test);
   1473 #endif
   1474     g_test_add_func("/char/file", char_file_test);
   1475 #ifndef _WIN32
   1476     g_test_add_func("/char/file-fifo", char_file_fifo_test);
   1477 #endif
   1478 
   1479 #define SOCKET_SERVER_TEST(name, addr)                                  \
   1480     static CharSocketServerTestConfig server1 ## name =                 \
   1481         { addr, false, false };                                         \
   1482     static CharSocketServerTestConfig server2 ## name =                 \
   1483         { addr, true, false };                                          \
   1484     static CharSocketServerTestConfig server3 ## name =                 \
   1485         { addr, false, true };                                          \
   1486     static CharSocketServerTestConfig server4 ## name =                 \
   1487         { addr, true, true };                                           \
   1488     g_test_add_data_func("/char/socket/server/mainloop/" # name,        \
   1489                          &server1 ##name, char_socket_server_test);     \
   1490     g_test_add_data_func("/char/socket/server/wait-conn/" # name,       \
   1491                          &server2 ##name, char_socket_server_test);     \
   1492     g_test_add_data_func("/char/socket/server/mainloop-fdpass/" # name, \
   1493                          &server3 ##name, char_socket_server_test);     \
   1494     g_test_add_data_func("/char/socket/server/wait-conn-fdpass/" # name, \
   1495                          &server4 ##name, char_socket_server_test)
   1496 
   1497 #define SOCKET_CLIENT_TEST(name, addr)                                  \
   1498     static CharSocketClientTestConfig client1 ## name =                 \
   1499         { addr, NULL, false, false, char_socket_event };                \
   1500     static CharSocketClientTestConfig client2 ## name =                 \
   1501         { addr, NULL, true, false, char_socket_event };                 \
   1502     static CharSocketClientTestConfig client3 ## name =                 \
   1503         { addr, ",reconnect=1", false, false, char_socket_event };      \
   1504     static CharSocketClientTestConfig client4 ## name =                 \
   1505         { addr, ",reconnect=1", true, false, char_socket_event };       \
   1506     static CharSocketClientTestConfig client5 ## name =                 \
   1507         { addr, NULL, false, true, char_socket_event };                 \
   1508     static CharSocketClientTestConfig client6 ## name =                 \
   1509         { addr, NULL, true, true, char_socket_event };                  \
   1510     static CharSocketClientTestConfig client7 ## name =                 \
   1511         { addr, ",reconnect=1", true, false,                            \
   1512             char_socket_event_with_error };                             \
   1513     static CharSocketClientTestConfig client8 ## name =                 \
   1514         { addr, ",reconnect=1", false, false, char_socket_event };      \
   1515     g_test_add_data_func("/char/socket/client/mainloop/" # name,        \
   1516                          &client1 ##name, char_socket_client_test);     \
   1517     g_test_add_data_func("/char/socket/client/wait-conn/" # name,       \
   1518                          &client2 ##name, char_socket_client_test);     \
   1519     g_test_add_data_func("/char/socket/client/mainloop-reconnect/" # name, \
   1520                          &client3 ##name, char_socket_client_test);     \
   1521     g_test_add_data_func("/char/socket/client/wait-conn-reconnect/" # name, \
   1522                          &client4 ##name, char_socket_client_test);     \
   1523     g_test_add_data_func("/char/socket/client/mainloop-fdpass/" # name, \
   1524                          &client5 ##name, char_socket_client_test);     \
   1525     g_test_add_data_func("/char/socket/client/wait-conn-fdpass/" # name, \
   1526                          &client6 ##name, char_socket_client_test);     \
   1527     g_test_add_data_func("/char/socket/client/reconnect-error/" # name, \
   1528                          &client7 ##name, char_socket_client_test);     \
   1529     g_test_add_data_func("/char/socket/client/dupid-reconnect/" # name, \
   1530                          &client8 ##name, char_socket_client_dupid_test)
   1531 
   1532     if (has_ipv4) {
   1533         SOCKET_SERVER_TEST(tcp, &tcpaddr);
   1534         SOCKET_CLIENT_TEST(tcp, &tcpaddr);
   1535         g_test_add_data_func("/char/socket/server/two-clients/tcp", &tcpaddr,
   1536                              char_socket_server_two_clients_test);
   1537     }
   1538 #ifndef WIN32
   1539     SOCKET_SERVER_TEST(unix, &unixaddr);
   1540     SOCKET_CLIENT_TEST(unix, &unixaddr);
   1541     g_test_add_data_func("/char/socket/server/two-clients/unix", &unixaddr,
   1542                          char_socket_server_two_clients_test);
   1543 #endif
   1544 
   1545     g_test_add_func("/char/udp", char_udp_test);
   1546 #if defined(HAVE_CHARDEV_SERIAL) && !defined(WIN32)
   1547     g_test_add_func("/char/serial", char_serial_test);
   1548 #endif
   1549     g_test_add_func("/char/hotswap", char_hotswap_test);
   1550     g_test_add_func("/char/websocket", char_websock_test);
   1551 
   1552 end:
   1553     return g_test_run();
   1554 }