xref: /qemu/tests/unit/test-char.c (revision a8b5c10c7147ebc992de12fdc3f25a219f5c742f)
1 #include "qemu/osdep.h"
2 #include <glib/gstdio.h>
3 
4 #include "qapi/error.h"
5 #include "qemu/config-file.h"
6 #include "qemu/module.h"
7 #include "qemu/option.h"
8 #include "qemu/sockets.h"
9 #include "chardev/char-fe.h"
10 #include "system/system.h"
11 #include "qapi/error.h"
12 #include "qapi/qapi-commands-char.h"
13 #include "qobject/qdict.h"
14 #include "qom/qom-qobject.h"
15 #include "io/channel-socket.h"
16 #include "qapi/qobject-input-visitor.h"
17 #include "qapi/qapi-visit-sockets.h"
18 #include "socket-helpers.h"
19 
20 static bool quit;
21 
22 typedef struct FeHandler {
23     int read_count;
24     bool is_open;
25     int openclose_count;
26     bool openclose_mismatch;
27     int last_event;
28     char read_buf[128];
29 } FeHandler;
30 
main_loop(void)31 static void main_loop(void)
32 {
33     quit = false;
34     do {
35         main_loop_wait(false);
36     } while (!quit);
37 }
38 
fe_can_read(void * opaque)39 static int fe_can_read(void *opaque)
40 {
41     FeHandler *h = opaque;
42 
43     return sizeof(h->read_buf) - h->read_count;
44 }
45 
fe_read(void * opaque,const uint8_t * buf,int size)46 static void fe_read(void *opaque, const uint8_t *buf, int size)
47 {
48     FeHandler *h = opaque;
49 
50     g_assert_cmpint(size, <=, fe_can_read(opaque));
51 
52     memcpy(h->read_buf + h->read_count, buf, size);
53     h->read_count += size;
54     quit = true;
55 }
56 
fe_event(void * opaque,QEMUChrEvent event)57 static void fe_event(void *opaque, QEMUChrEvent event)
58 {
59     FeHandler *h = opaque;
60     bool new_open_state;
61 
62     h->last_event = event;
63     switch (event) {
64     case CHR_EVENT_BREAK:
65         break;
66     case CHR_EVENT_OPENED:
67     case CHR_EVENT_CLOSED:
68         h->openclose_count++;
69         new_open_state = (event == CHR_EVENT_OPENED);
70         if (h->is_open == new_open_state) {
71             h->openclose_mismatch = true;
72         }
73         h->is_open = new_open_state;
74         /* fallthrough */
75     default:
76         quit = true;
77         break;
78     }
79 }
80 
81 #ifdef _WIN32
char_console_test_subprocess(void)82 static void char_console_test_subprocess(void)
83 {
84     QemuOpts *opts;
85     Chardev *chr;
86 
87     opts = qemu_opts_create(qemu_find_opts("chardev"), "console-label",
88                             1, &error_abort);
89     qemu_opt_set(opts, "backend", "console", &error_abort);
90 
91     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
92     g_assert_nonnull(chr);
93 
94     qemu_chr_write_all(chr, (const uint8_t *)"CONSOLE", 7);
95 
96     qemu_opts_del(opts);
97     object_unparent(OBJECT(chr));
98 }
99 
char_console_test(void)100 static void char_console_test(void)
101 {
102     g_test_trap_subprocess("/char/console/subprocess", 0, 0);
103     g_test_trap_assert_passed();
104     g_test_trap_assert_stdout("CONSOLE");
105 }
106 #endif
char_stdio_test_subprocess(void)107 static void char_stdio_test_subprocess(void)
108 {
109     Chardev *chr;
110     CharBackend be;
111     int ret;
112 
113     chr = qemu_chr_new("label", "stdio", NULL);
114     g_assert_nonnull(chr);
115 
116     qemu_chr_fe_init(&be, chr, &error_abort);
117     qemu_chr_fe_set_open(&be, true);
118     ret = qemu_chr_fe_write(&be, (void *)"buf", 4);
119     g_assert_cmpint(ret, ==, 4);
120 
121     qemu_chr_fe_deinit(&be, true);
122 }
123 
char_stdio_test(void)124 static void char_stdio_test(void)
125 {
126     g_test_trap_subprocess("/char/stdio/subprocess", 0, 0);
127     g_test_trap_assert_passed();
128     g_test_trap_assert_stdout("buf");
129 }
130 
char_ringbuf_test(void)131 static void char_ringbuf_test(void)
132 {
133     QemuOpts *opts;
134     Chardev *chr;
135     CharBackend be;
136     char *data;
137     int ret;
138 
139     opts = qemu_opts_create(qemu_find_opts("chardev"), "ringbuf-label",
140                             1, &error_abort);
141     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
142 
143     qemu_opt_set(opts, "size", "5", &error_abort);
144     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
145     g_assert_null(chr);
146     qemu_opts_del(opts);
147 
148     opts = qemu_opts_create(qemu_find_opts("chardev"), "ringbuf-label",
149                             1, &error_abort);
150     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
151     qemu_opt_set(opts, "size", "2", &error_abort);
152     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
153     g_assert_nonnull(chr);
154     qemu_opts_del(opts);
155 
156     qemu_chr_fe_init(&be, chr, &error_abort);
157     ret = qemu_chr_fe_write(&be, (void *)"buff", 4);
158     g_assert_cmpint(ret, ==, 4);
159 
160     data = qmp_ringbuf_read("ringbuf-label", 4, false, 0, &error_abort);
161     g_assert_cmpstr(data, ==, "ff");
162     g_free(data);
163 
164     data = qmp_ringbuf_read("ringbuf-label", 4, false, 0, &error_abort);
165     g_assert_cmpstr(data, ==, "");
166     g_free(data);
167 
168     qemu_chr_fe_deinit(&be, true);
169 
170     /* check alias */
171     opts = qemu_opts_create(qemu_find_opts("chardev"), "memory-label",
172                             1, &error_abort);
173     qemu_opt_set(opts, "backend", "memory", &error_abort);
174     qemu_opt_set(opts, "size", "2", &error_abort);
175     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
176     g_assert_nonnull(chr);
177     object_unparent(OBJECT(chr));
178     qemu_opts_del(opts);
179 }
180 
char_mux_test(void)181 static void char_mux_test(void)
182 {
183     QemuOpts *opts;
184     Chardev *chr, *base;
185     char *data;
186     FeHandler h1 = { 0, false, 0, false, }, h2 = { 0, false, 0, false, };
187     CharBackend chr_be1, chr_be2;
188     Error *error = NULL;
189 
190     /* Create mux and chardev to be immediately removed */
191     opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
192                             1, &error_abort);
193     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
194     qemu_opt_set(opts, "size", "128", &error_abort);
195     qemu_opt_set(opts, "mux", "on", &error_abort);
196     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
197     g_assert_nonnull(chr);
198     qemu_opts_del(opts);
199 
200     /* Remove just created mux and chardev */
201     qmp_chardev_remove("mux-label", &error_abort);
202     qmp_chardev_remove("mux-label-base", &error_abort);
203 
204     opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
205                             1, &error_abort);
206     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
207     qemu_opt_set(opts, "size", "128", &error_abort);
208     qemu_opt_set(opts, "mux", "on", &error_abort);
209     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
210     g_assert_nonnull(chr);
211     qemu_opts_del(opts);
212 
213     qemu_chr_fe_init(&chr_be1, chr, &error_abort);
214     qemu_chr_fe_set_handlers(&chr_be1,
215                              fe_can_read,
216                              fe_read,
217                              fe_event,
218                              NULL,
219                              &h1,
220                              NULL, true);
221 
222     qemu_chr_fe_init(&chr_be2, chr, &error_abort);
223     qemu_chr_fe_set_handlers(&chr_be2,
224                              fe_can_read,
225                              fe_read,
226                              fe_event,
227                              NULL,
228                              &h2,
229                              NULL, true);
230     qemu_chr_fe_take_focus(&chr_be2);
231 
232     base = qemu_chr_find("mux-label-base");
233     g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);
234 
235     qemu_chr_be_write(base, (void *)"hello", 6);
236     g_assert_cmpint(h1.read_count, ==, 0);
237     g_assert_cmpint(h2.read_count, ==, 6);
238     g_assert_cmpstr(h2.read_buf, ==, "hello");
239     h2.read_count = 0;
240 
241     g_assert_cmpint(h1.last_event, !=, 42); /* should be MUX_OUT or OPENED */
242     g_assert_cmpint(h2.last_event, !=, 42); /* should be MUX_IN or OPENED */
243     /* sending event on the base broadcast to all fe, historical reasons? */
244     qemu_chr_be_event(base, 42);
245     g_assert_cmpint(h1.last_event, ==, 42);
246     g_assert_cmpint(h2.last_event, ==, 42);
247     qemu_chr_be_event(chr, -1);
248     g_assert_cmpint(h1.last_event, ==, 42);
249     g_assert_cmpint(h2.last_event, ==, -1);
250 
251     /* switch focus */
252     qemu_chr_be_write(base, (void *)"\1b", 2);
253     g_assert_cmpint(h1.last_event, ==, 42);
254     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_BREAK);
255 
256     qemu_chr_be_write(base, (void *)"\1c", 2);
257     g_assert_cmpint(h1.last_event, ==, CHR_EVENT_MUX_IN);
258     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
259     qemu_chr_be_event(chr, -1);
260     g_assert_cmpint(h1.last_event, ==, -1);
261     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
262 
263     qemu_chr_be_write(base, (void *)"hello", 6);
264     g_assert_cmpint(h2.read_count, ==, 0);
265     g_assert_cmpint(h1.read_count, ==, 6);
266     g_assert_cmpstr(h1.read_buf, ==, "hello");
267     h1.read_count = 0;
268 
269     qemu_chr_be_write(base, (void *)"\1b", 2);
270     g_assert_cmpint(h1.last_event, ==, CHR_EVENT_BREAK);
271     g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
272 
273     /* open/close state and corresponding events */
274     g_assert_true(qemu_chr_fe_backend_open(&chr_be1));
275     g_assert_true(qemu_chr_fe_backend_open(&chr_be2));
276     g_assert_true(h1.is_open);
277     g_assert_false(h1.openclose_mismatch);
278     g_assert_true(h2.is_open);
279     g_assert_false(h2.openclose_mismatch);
280 
281     h1.openclose_count = h2.openclose_count = 0;
282 
283     qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
284                              NULL, NULL, false);
285     qemu_chr_fe_set_handlers(&chr_be2, NULL, NULL, NULL, NULL,
286                              NULL, NULL, false);
287     g_assert_cmpint(h1.openclose_count, ==, 0);
288     g_assert_cmpint(h2.openclose_count, ==, 0);
289 
290     h1.is_open = h2.is_open = false;
291     qemu_chr_fe_set_handlers(&chr_be1,
292                              NULL,
293                              NULL,
294                              fe_event,
295                              NULL,
296                              &h1,
297                              NULL, false);
298     qemu_chr_fe_set_handlers(&chr_be2,
299                              NULL,
300                              NULL,
301                              fe_event,
302                              NULL,
303                              &h2,
304                              NULL, false);
305     g_assert_cmpint(h1.openclose_count, ==, 1);
306     g_assert_false(h1.openclose_mismatch);
307     g_assert_cmpint(h2.openclose_count, ==, 1);
308     g_assert_false(h2.openclose_mismatch);
309 
310     qemu_chr_be_event(base, CHR_EVENT_CLOSED);
311     qemu_chr_be_event(base, CHR_EVENT_OPENED);
312     g_assert_cmpint(h1.openclose_count, ==, 3);
313     g_assert_false(h1.openclose_mismatch);
314     g_assert_cmpint(h2.openclose_count, ==, 3);
315     g_assert_false(h2.openclose_mismatch);
316 
317     qemu_chr_fe_set_handlers(&chr_be2,
318                              fe_can_read,
319                              fe_read,
320                              fe_event,
321                              NULL,
322                              &h2,
323                              NULL, false);
324     qemu_chr_fe_set_handlers(&chr_be1,
325                              fe_can_read,
326                              fe_read,
327                              fe_event,
328                              NULL,
329                              &h1,
330                              NULL, false);
331 
332     /* remove first handler */
333     qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
334                              NULL, NULL, true);
335     qemu_chr_be_write(base, (void *)"hello", 6);
336     g_assert_cmpint(h1.read_count, ==, 0);
337     g_assert_cmpint(h2.read_count, ==, 0);
338 
339     qemu_chr_be_write(base, (void *)"\1c", 2);
340     qemu_chr_be_write(base, (void *)"hello", 6);
341     g_assert_cmpint(h1.read_count, ==, 0);
342     g_assert_cmpint(h2.read_count, ==, 6);
343     g_assert_cmpstr(h2.read_buf, ==, "hello");
344     h2.read_count = 0;
345 
346     /* print help */
347     qemu_chr_be_write(base, (void *)"\1?", 2);
348     data = qmp_ringbuf_read("mux-label-base", 128, false, 0, &error_abort);
349     g_assert_cmpint(strlen(data), !=, 0);
350     g_free(data);
351 
352     qemu_chr_fe_deinit(&chr_be1, false);
353 
354     qmp_chardev_remove("mux-label", &error);
355     g_assert_cmpstr(error_get_pretty(error), ==, "Chardev 'mux-label' is busy");
356     error_free(error);
357 
358     qemu_chr_fe_deinit(&chr_be2, false);
359     qmp_chardev_remove("mux-label", &error_abort);
360 }
361 
char_hub_test(void)362 static void char_hub_test(void)
363 {
364     QemuOpts *opts;
365     Chardev *hub, *chr1, *chr2, *base;
366     char *data;
367     FeHandler h = { 0, false, 0, false, };
368     Error *error = NULL;
369     CharBackend chr_be;
370     int ret, i;
371 
372 #define RB_SIZE 128
373 
374     /*
375      * Create invalid hub
376      * 1. Create hub without a 'chardevs.N' defined (expect error)
377      */
378     opts = qemu_opts_create(qemu_find_opts("chardev"), "hub0",
379                             1, &error_abort);
380     qemu_opt_set(opts, "backend", "hub", &error_abort);
381     hub = qemu_chr_new_from_opts(opts, NULL, &error);
382     g_assert_cmpstr(error_get_pretty(error), ==,
383                     "hub: 'chardevs' list is not defined");
384     error_free(error);
385     error = NULL;
386     qemu_opts_del(opts);
387 
388     /*
389      * Create invalid hub
390      * 1. Create chardev with embedded mux: 'mux=on'
391      * 2. Create hub which refers mux
392      * 3. Create hub which refers chardev already attached
393      *    to the mux (already in use, expect error)
394      */
395     opts = qemu_opts_create(qemu_find_opts("chardev"), "chr0",
396                             1, &error_abort);
397     qemu_opt_set(opts, "mux", "on", &error_abort);
398     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
399     qemu_opt_set(opts, "size", stringify(RB_SIZE), &error_abort);
400     base = qemu_chr_new_from_opts(opts, NULL, &error_abort);
401     g_assert_nonnull(base);
402     qemu_opts_del(opts);
403 
404     opts = qemu_opts_create(qemu_find_opts("chardev"), "hub0",
405                             1, &error_abort);
406     qemu_opt_set(opts, "backend", "hub", &error_abort);
407     qemu_opt_set(opts, "chardevs.0", "chr0", &error_abort);
408     hub = qemu_chr_new_from_opts(opts, NULL, &error);
409     g_assert_cmpstr(error_get_pretty(error), ==,
410                     "hub: multiplexers and hub devices can't be "
411                     "stacked, check chardev 'chr0', chardev should "
412                     "not be a hub device or have 'mux=on' enabled");
413     error_free(error);
414     error = NULL;
415     qemu_opts_del(opts);
416 
417     opts = qemu_opts_create(qemu_find_opts("chardev"), "hub0",
418                             1, &error_abort);
419     qemu_opt_set(opts, "backend", "hub", &error_abort);
420     qemu_opt_set(opts, "chardevs.0", "chr0-base", &error_abort);
421     hub = qemu_chr_new_from_opts(opts, NULL, &error);
422     g_assert_cmpstr(error_get_pretty(error), ==,
423                     "chardev 'chr0-base' is already in use");
424     error_free(error);
425     error = NULL;
426     qemu_opts_del(opts);
427 
428     /* Finalize chr0 */
429     qmp_chardev_remove("chr0", &error_abort);
430 
431     /*
432      * Create invalid hub with more than maximum allowed backends
433      * 1. Create more than maximum allowed 'chardevs.%d' options for
434      *    hub (expect error)
435      */
436     opts = qemu_opts_create(qemu_find_opts("chardev"), "hub0",
437                             1, &error_abort);
438     for (i = 0; i < 10; i++) {
439         char key[32], val[32];
440 
441         snprintf(key, sizeof(key), "chardevs.%d", i);
442         snprintf(val, sizeof(val), "chr%d", i);
443         qemu_opt_set(opts, key, val, &error);
444         if (error) {
445             char buf[64];
446 
447             snprintf(buf, sizeof(buf), "Invalid parameter 'chardevs.%d'", i);
448             g_assert_cmpstr(error_get_pretty(error), ==, buf);
449             error_free(error);
450             break;
451         }
452     }
453     g_assert_nonnull(error);
454     error = NULL;
455     qemu_opts_del(opts);
456 
457     /*
458      * Create hub with 2 backend chardevs and 1 frontend and perform
459      * data aggregation
460      * 1. Create 2 ringbuf backend chardevs
461      * 2. Create 1 frontend
462      * 3. Create hub which refers 2 backend chardevs
463      * 4. Attach hub to a frontend
464      * 5. Attach hub to a frontend second time (expect error)
465      * 6. Perform data aggregation
466      * 7. Remove chr1 ("chr1 is busy", expect error)
467      * 8. Remove hub0 ("hub0 is busy", expect error);
468      * 9. Finilize frontend, hub and backend chardevs in correct order
469      */
470 
471     /* Create first chardev */
472     opts = qemu_opts_create(qemu_find_opts("chardev"), "chr1",
473                             1, &error_abort);
474     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
475     qemu_opt_set(opts, "size", stringify(RB_SIZE), &error_abort);
476     chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort);
477     g_assert_nonnull(chr1);
478     qemu_opts_del(opts);
479 
480     /* Create second chardev */
481     opts = qemu_opts_create(qemu_find_opts("chardev"), "chr2",
482                             1, &error_abort);
483     qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
484     qemu_opt_set(opts, "size", stringify(RB_SIZE), &error_abort);
485     chr2 = qemu_chr_new_from_opts(opts, NULL, &error_abort);
486     g_assert_nonnull(chr2);
487     qemu_opts_del(opts);
488 
489     /* Create hub0 and refer 2 backend chardevs */
490     opts = qemu_opts_create(qemu_find_opts("chardev"), "hub0",
491                             1, &error_abort);
492     qemu_opt_set(opts, "backend", "hub", &error_abort);
493     qemu_opt_set(opts, "chardevs.0", "chr1", &error_abort);
494     qemu_opt_set(opts, "chardevs.1", "chr2", &error_abort);
495     hub = qemu_chr_new_from_opts(opts, NULL, &error_abort);
496     g_assert_nonnull(hub);
497     qemu_opts_del(opts);
498 
499     /* Attach hub to a frontend */
500     qemu_chr_fe_init(&chr_be, hub, &error_abort);
501     qemu_chr_fe_set_handlers(&chr_be,
502                              fe_can_read,
503                              fe_read,
504                              fe_event,
505                              NULL,
506                              &h,
507                              NULL, true);
508 
509     /* Fails second time */
510     qemu_chr_fe_init(&chr_be, hub, &error);
511     g_assert_cmpstr(error_get_pretty(error), ==, "chardev 'hub0' is already in use");
512     error_free(error);
513     error = NULL;
514 
515     /* Write to backend, chr1 */
516     base = qemu_chr_find("chr1");
517     g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);
518 
519     qemu_chr_be_write(base, (void *)"hello", 6);
520     g_assert_cmpint(h.read_count, ==, 6);
521     g_assert_cmpstr(h.read_buf, ==, "hello");
522     h.read_count = 0;
523 
524     /* Write to backend, chr2 */
525     base = qemu_chr_find("chr2");
526     g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);
527 
528     qemu_chr_be_write(base, (void *)"olleh", 6);
529     g_assert_cmpint(h.read_count, ==, 6);
530     g_assert_cmpstr(h.read_buf, ==, "olleh");
531     h.read_count = 0;
532 
533     /* Write to frontend, chr_be */
534     ret = qemu_chr_fe_write(&chr_be, (void *)"heyhey", 6);
535     g_assert_cmpint(ret, ==, 6);
536 
537     data = qmp_ringbuf_read("chr1", RB_SIZE, false, 0, &error_abort);
538     g_assert_cmpint(strlen(data), ==, 6);
539     g_assert_cmpstr(data, ==, "heyhey");
540     g_free(data);
541 
542     data = qmp_ringbuf_read("chr2", RB_SIZE, false, 0, &error_abort);
543     g_assert_cmpint(strlen(data), ==, 6);
544     g_assert_cmpstr(data, ==, "heyhey");
545     g_free(data);
546 
547     /* Can't be removed, depends on hub0 */
548     qmp_chardev_remove("chr1", &error);
549     g_assert_cmpstr(error_get_pretty(error), ==, "Chardev 'chr1' is busy");
550     error_free(error);
551     error = NULL;
552 
553     /* Can't be removed, depends on frontend chr_be */
554     qmp_chardev_remove("hub0", &error);
555     g_assert_cmpstr(error_get_pretty(error), ==, "Chardev 'hub0' is busy");
556     error_free(error);
557     error = NULL;
558 
559     /* Finalize frontend */
560     qemu_chr_fe_deinit(&chr_be, false);
561 
562     /* Finalize hub0 */
563     qmp_chardev_remove("hub0", &error_abort);
564 
565     /* Finalize backend chardevs */
566     qmp_chardev_remove("chr1", &error_abort);
567     qmp_chardev_remove("chr2", &error_abort);
568 
569 #ifndef _WIN32
570     /*
571      * Create 3 backend chardevs to simulate EAGAIN and watcher.
572      * Mainly copied from char_pipe_test().
573      * 1. Create 2 ringbuf backend chardevs
574      * 2. Create 1 pipe backend chardev
575      * 3. Create 1 frontend
576      * 4. Create hub which refers 2 backend chardevs
577      * 5. Attach hub to a frontend
578      * 6. Perform data aggregation and check watcher
579      * 7. Finilize frontend, hub and backend chardevs in correct order
580      */
581     {
582         gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
583         gchar *in, *out, *pipe = g_build_filename(tmp_path, "pipe", NULL);
584         Chardev *chr3;
585         int fd, len;
586         char buf[128];
587 
588         in = g_strdup_printf("%s.in", pipe);
589         if (mkfifo(in, 0600) < 0) {
590             abort();
591         }
592         out = g_strdup_printf("%s.out", pipe);
593         if (mkfifo(out, 0600) < 0) {
594             abort();
595         }
596 
597         /* Create first chardev */
598         opts = qemu_opts_create(qemu_find_opts("chardev"), "chr1",
599                                 1, &error_abort);
600         qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
601         qemu_opt_set(opts, "size", stringify(RB_SIZE), &error_abort);
602         chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort);
603         g_assert_nonnull(chr1);
604         qemu_opts_del(opts);
605 
606         /* Create second chardev */
607         opts = qemu_opts_create(qemu_find_opts("chardev"), "chr2",
608                                 1, &error_abort);
609         qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
610         qemu_opt_set(opts, "size", stringify(RB_SIZE), &error_abort);
611         chr2 = qemu_chr_new_from_opts(opts, NULL, &error_abort);
612         g_assert_nonnull(chr2);
613         qemu_opts_del(opts);
614 
615         /* Create third chardev */
616         opts = qemu_opts_create(qemu_find_opts("chardev"), "chr3",
617                                 1, &error_abort);
618         qemu_opt_set(opts, "backend", "pipe", &error_abort);
619         qemu_opt_set(opts, "path", pipe, &error_abort);
620         chr3 = qemu_chr_new_from_opts(opts, NULL, &error_abort);
621         g_assert_nonnull(chr3);
622 
623         /* Create hub0 and refer 3 backend chardevs */
624         opts = qemu_opts_create(qemu_find_opts("chardev"), "hub0",
625                                 1, &error_abort);
626         qemu_opt_set(opts, "backend", "hub", &error_abort);
627         qemu_opt_set(opts, "chardevs.0", "chr1", &error_abort);
628         qemu_opt_set(opts, "chardevs.1", "chr2", &error_abort);
629         qemu_opt_set(opts, "chardevs.2", "chr3", &error_abort);
630         hub = qemu_chr_new_from_opts(opts, NULL, &error_abort);
631         g_assert_nonnull(hub);
632         qemu_opts_del(opts);
633 
634         /* Attach hub to a frontend */
635         qemu_chr_fe_init(&chr_be, hub, &error_abort);
636         qemu_chr_fe_set_handlers(&chr_be,
637                                  fe_can_read,
638                                  fe_read,
639                                  fe_event,
640                                  NULL,
641                                  &h,
642                                  NULL, true);
643 
644         /* Write to frontend, chr_be */
645         ret = qemu_chr_fe_write(&chr_be, (void *)"thisis", 6);
646         g_assert_cmpint(ret, ==, 6);
647 
648         data = qmp_ringbuf_read("chr1", RB_SIZE, false, 0, &error_abort);
649         g_assert_cmpint(strlen(data), ==, 6);
650         g_assert_cmpstr(data, ==, "thisis");
651         g_free(data);
652 
653         data = qmp_ringbuf_read("chr2", RB_SIZE, false, 0, &error_abort);
654         g_assert_cmpint(strlen(data), ==, 6);
655         g_assert_cmpstr(data, ==, "thisis");
656         g_free(data);
657 
658         fd = open(out, O_RDWR);
659         ret = read(fd, buf, sizeof(buf));
660         g_assert_cmpint(ret, ==, 6);
661         buf[ret] = 0;
662         g_assert_cmpstr(buf, ==, "thisis");
663         close(fd);
664 
665         /* Add watch. 0 indicates no watches if nothing to wait for */
666         ret = qemu_chr_fe_add_watch(&chr_be, G_IO_OUT | G_IO_HUP,
667                                     NULL, NULL);
668         g_assert_cmpint(ret, ==, 0);
669 
670         /*
671          * Write to frontend, chr_be, until EAGAIN. Make sure length is
672          * power of two to fit nicely the whole pipe buffer.
673          */
674         len = 0;
675         while ((ret = qemu_chr_fe_write(&chr_be, (void *)"thisisit", 8))
676                != -1) {
677             len += ret;
678         }
679         g_assert_cmpint(errno, ==, EAGAIN);
680 
681         /* Further all writes should cause EAGAIN */
682         ret = qemu_chr_fe_write(&chr_be, (void *)"b", 1);
683         g_assert_cmpint(ret, ==, -1);
684         g_assert_cmpint(errno, ==, EAGAIN);
685 
686         /*
687          * Add watch. Non 0 indicates we have a blocked chardev, which
688          * can wakes us up when write is possible.
689          */
690         ret = qemu_chr_fe_add_watch(&chr_be, G_IO_OUT | G_IO_HUP,
691                                     NULL, NULL);
692         g_assert_cmpint(ret, !=, 0);
693         g_source_remove(ret);
694 
695         /* Drain pipe and ring buffers */
696         fd = open(out, O_RDWR);
697         while ((ret = read(fd, buf, MIN(sizeof(buf), len))) != -1 && len > 0) {
698             len -= ret;
699         }
700         close(fd);
701 
702         data = qmp_ringbuf_read("chr1", RB_SIZE, false, 0, &error_abort);
703         g_assert_cmpint(strlen(data), ==, 128);
704         g_free(data);
705 
706         data = qmp_ringbuf_read("chr2", RB_SIZE, false, 0, &error_abort);
707         g_assert_cmpint(strlen(data), ==, 128);
708         g_free(data);
709 
710         /*
711          * Now we are good to go, first repeat "lost" sequence, which
712          * was already consumed and drained by the ring buffers, but
713          * pipe have not recieved that yet.
714          */
715         ret = qemu_chr_fe_write(&chr_be, (void *)"thisisit", 8);
716         g_assert_cmpint(ret, ==, 8);
717 
718         ret = qemu_chr_fe_write(&chr_be, (void *)"streamisrestored", 16);
719         g_assert_cmpint(ret, ==, 16);
720 
721         data = qmp_ringbuf_read("chr1", RB_SIZE, false, 0, &error_abort);
722         g_assert_cmpint(strlen(data), ==, 16);
723         /* Only last 16 bytes, see big comment above */
724         g_assert_cmpstr(data, ==, "streamisrestored");
725         g_free(data);
726 
727         data = qmp_ringbuf_read("chr2", RB_SIZE, false, 0, &error_abort);
728         g_assert_cmpint(strlen(data), ==, 16);
729         /* Only last 16 bytes, see big comment above */
730         g_assert_cmpstr(data, ==, "streamisrestored");
731         g_free(data);
732 
733         fd = open(out, O_RDWR);
734         ret = read(fd, buf, sizeof(buf));
735         g_assert_cmpint(ret, ==, 24);
736         buf[ret] = 0;
737         /* Both 8 and 16 bytes */
738         g_assert_cmpstr(buf, ==, "thisisitstreamisrestored");
739         close(fd);
740 
741         g_free(in);
742         g_free(out);
743         g_free(tmp_path);
744         g_free(pipe);
745 
746         /* Finalize frontend */
747         qemu_chr_fe_deinit(&chr_be, false);
748 
749         /* Finalize hub0 */
750         qmp_chardev_remove("hub0", &error_abort);
751 
752         /* Finalize backend chardevs */
753         qmp_chardev_remove("chr1", &error_abort);
754         qmp_chardev_remove("chr2", &error_abort);
755         qmp_chardev_remove("chr3", &error_abort);
756     }
757 #endif
758 }
759 
websock_server_read(void * opaque,const uint8_t * buf,int size)760 static void websock_server_read(void *opaque, const uint8_t *buf, int size)
761 {
762     g_assert_cmpint(size, ==, 5);
763     g_assert(memcmp(buf, "world", size) == 0);
764     quit = true;
765 }
766 
767 
websock_server_can_read(void * opaque)768 static int websock_server_can_read(void *opaque)
769 {
770     return 10;
771 }
772 
773 
websock_check_http_headers(char * buf,int size)774 static bool websock_check_http_headers(char *buf, int size)
775 {
776     int i;
777     const char *ans[] = { "HTTP/1.1 101 Switching Protocols\r\n",
778                           "Server: QEMU VNC\r\n",
779                           "Upgrade: websocket\r\n",
780                           "Connection: Upgrade\r\n",
781                           "Sec-WebSocket-Accept:",
782                           "Sec-WebSocket-Protocol: binary\r\n" };
783 
784     for (i = 0; i < 6; i++) {
785         if (g_strstr_len(buf, size, ans[i]) == NULL) {
786             return false;
787         }
788     }
789 
790     return true;
791 }
792 
793 
websock_client_read(void * opaque,const uint8_t * buf,int size)794 static void websock_client_read(void *opaque, const uint8_t *buf, int size)
795 {
796     const uint8_t ping[] = { 0x89, 0x85,                  /* Ping header */
797                              0x07, 0x77, 0x9e, 0xf9,      /* Masking key */
798                              0x6f, 0x12, 0xf2, 0x95, 0x68 /* "hello" */ };
799 
800     const uint8_t binary[] = { 0x82, 0x85,                  /* Binary header */
801                                0x74, 0x90, 0xb9, 0xdf,      /* Masking key */
802                                0x03, 0xff, 0xcb, 0xb3, 0x10 /* "world" */ };
803     Chardev *chr_client = opaque;
804 
805     if (websock_check_http_headers((char *) buf, size)) {
806         qemu_chr_fe_write(chr_client->be, ping, sizeof(ping));
807     } else if (buf[0] == 0x8a && buf[1] == 0x05) {
808         g_assert(strncmp((char *) buf + 2, "hello", 5) == 0);
809         qemu_chr_fe_write(chr_client->be, binary, sizeof(binary));
810     } else {
811         g_assert(buf[0] == 0x88 && buf[1] == 0x16);
812         g_assert(strncmp((char *) buf + 4, "peer requested close", 10) == 0);
813         quit = true;
814     }
815 }
816 
817 
websock_client_can_read(void * opaque)818 static int websock_client_can_read(void *opaque)
819 {
820     return 4096;
821 }
822 
823 
char_websock_test(void)824 static void char_websock_test(void)
825 {
826     QObject *addr;
827     QDict *qdict;
828     const char *port;
829     char *tmp;
830     char *handshake_port;
831     CharBackend be;
832     CharBackend client_be;
833     Chardev *chr_client;
834     Chardev *chr = qemu_chr_new("server",
835                                 "websocket:127.0.0.1:0,server=on,wait=off", NULL);
836     const char handshake[] = "GET / HTTP/1.1\r\n"
837                              "Upgrade: websocket\r\n"
838                              "Connection: Upgrade\r\n"
839                              "Host: localhost:%s\r\n"
840                              "Origin: http://localhost:%s\r\n"
841                              "Sec-WebSocket-Key: o9JHNiS3/0/0zYE1wa3yIw==\r\n"
842                              "Sec-WebSocket-Version: 13\r\n"
843                              "Sec-WebSocket-Protocol: binary\r\n\r\n";
844     const uint8_t close[] = { 0x88, 0x82,             /* Close header */
845                               0xef, 0xaa, 0xc5, 0x97, /* Masking key */
846                               0xec, 0x42              /* Status code */ };
847 
848     addr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
849     qdict = qobject_to(QDict, addr);
850     port = qdict_get_str(qdict, "port");
851     tmp = g_strdup_printf("tcp:127.0.0.1:%s", port);
852     handshake_port = g_strdup_printf(handshake, port, port);
853     qobject_unref(qdict);
854 
855     qemu_chr_fe_init(&be, chr, &error_abort);
856     qemu_chr_fe_set_handlers(&be, websock_server_can_read, websock_server_read,
857                              NULL, NULL, chr, NULL, true);
858 
859     chr_client = qemu_chr_new("client", tmp, NULL);
860     qemu_chr_fe_init(&client_be, chr_client, &error_abort);
861     qemu_chr_fe_set_handlers(&client_be, websock_client_can_read,
862                              websock_client_read,
863                              NULL, NULL, chr_client, NULL, true);
864     g_free(tmp);
865 
866     qemu_chr_write_all(chr_client,
867                        (uint8_t *) handshake_port,
868                        strlen(handshake_port));
869     g_free(handshake_port);
870     main_loop();
871 
872     g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
873     g_assert(object_property_get_bool(OBJECT(chr_client),
874                                       "connected", &error_abort));
875 
876     qemu_chr_write_all(chr_client, close, sizeof(close));
877     main_loop();
878 
879     object_unparent(OBJECT(chr_client));
880     object_unparent(OBJECT(chr));
881 }
882 
883 
884 #ifndef _WIN32
char_pipe_test(void)885 static void char_pipe_test(void)
886 {
887     gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
888     gchar *tmp, *in, *out, *pipe = g_build_filename(tmp_path, "pipe", NULL);
889     Chardev *chr;
890     CharBackend be;
891     int ret, fd;
892     char buf[10];
893     FeHandler fe = { 0, };
894 
895     in = g_strdup_printf("%s.in", pipe);
896     if (mkfifo(in, 0600) < 0) {
897         abort();
898     }
899     out = g_strdup_printf("%s.out", pipe);
900     if (mkfifo(out, 0600) < 0) {
901         abort();
902     }
903 
904     tmp = g_strdup_printf("pipe:%s", pipe);
905     chr = qemu_chr_new("pipe", tmp, NULL);
906     g_assert_nonnull(chr);
907     g_free(tmp);
908 
909     qemu_chr_fe_init(&be, chr, &error_abort);
910 
911     ret = qemu_chr_fe_write(&be, (void *)"pipe-out", 9);
912     g_assert_cmpint(ret, ==, 9);
913 
914     fd = open(out, O_RDWR);
915     ret = read(fd, buf, sizeof(buf));
916     g_assert_cmpint(ret, ==, 9);
917     g_assert_cmpstr(buf, ==, "pipe-out");
918     close(fd);
919 
920     fd = open(in, O_WRONLY);
921     ret = write(fd, "pipe-in", 8);
922     g_assert_cmpint(ret, ==, 8);
923     close(fd);
924 
925     qemu_chr_fe_set_handlers(&be,
926                              fe_can_read,
927                              fe_read,
928                              fe_event,
929                              NULL,
930                              &fe,
931                              NULL, true);
932 
933     main_loop();
934 
935     g_assert_cmpint(fe.read_count, ==, 8);
936     g_assert_cmpstr(fe.read_buf, ==, "pipe-in");
937 
938     qemu_chr_fe_deinit(&be, true);
939 
940     g_assert(g_unlink(in) == 0);
941     g_assert(g_unlink(out) == 0);
942     g_assert(g_rmdir(tmp_path) == 0);
943     g_free(in);
944     g_free(out);
945     g_free(tmp_path);
946     g_free(pipe);
947 }
948 #endif
949 
950 typedef struct SocketIdleData {
951     GMainLoop *loop;
952     Chardev *chr;
953     bool conn_expected;
954     CharBackend *be;
955     CharBackend *client_be;
956 } SocketIdleData;
957 
958 
socket_read_hello(void * opaque,const uint8_t * buf,int size)959 static void socket_read_hello(void *opaque, const uint8_t *buf, int size)
960 {
961     g_assert_cmpint(size, ==, 5);
962     g_assert(strncmp((char *)buf, "hello", 5) == 0);
963 
964     quit = true;
965 }
966 
socket_can_read_hello(void * opaque)967 static int socket_can_read_hello(void *opaque)
968 {
969     return 10;
970 }
971 
make_udp_socket(int * port)972 static int make_udp_socket(int *port)
973 {
974     struct sockaddr_in addr = { 0, };
975     socklen_t alen = sizeof(addr);
976     int ret, sock = qemu_socket(PF_INET, SOCK_DGRAM, 0);
977 
978     g_assert_cmpint(sock, >=, 0);
979     addr.sin_family = AF_INET ;
980     addr.sin_addr.s_addr = htonl(INADDR_ANY);
981     addr.sin_port = 0;
982     ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
983     g_assert_cmpint(ret, ==, 0);
984     ret = getsockname(sock, (struct sockaddr *)&addr, &alen);
985     g_assert_cmpint(ret, ==, 0);
986 
987     *port = ntohs(addr.sin_port);
988     return sock;
989 }
990 
char_udp_test_internal(Chardev * reuse_chr,int sock)991 static void char_udp_test_internal(Chardev *reuse_chr, int sock)
992 {
993     struct sockaddr_in other;
994     SocketIdleData d = { 0, };
995     Chardev *chr;
996     CharBackend stack_be, *be = &stack_be;
997     socklen_t alen = sizeof(other);
998     int ret;
999     char buf[10];
1000     char *tmp = NULL;
1001 
1002     if (reuse_chr) {
1003         chr = reuse_chr;
1004         be = chr->be;
1005     } else {
1006         int port;
1007         sock = make_udp_socket(&port);
1008         tmp = g_strdup_printf("udp:127.0.0.1:%d", port);
1009         chr = qemu_chr_new("client", tmp, NULL);
1010         g_assert_nonnull(chr);
1011 
1012         qemu_chr_fe_init(be, chr, &error_abort);
1013     }
1014 
1015     d.chr = chr;
1016     qemu_chr_fe_set_handlers(be, socket_can_read_hello, socket_read_hello,
1017                              NULL, NULL, &d, NULL, true);
1018     ret = qemu_chr_write_all(chr, (uint8_t *)"hello", 5);
1019     g_assert_cmpint(ret, ==, 5);
1020 
1021     ret = recvfrom(sock, buf, sizeof(buf), 0,
1022                    (struct sockaddr *)&other, &alen);
1023     g_assert_cmpint(ret, ==, 5);
1024     ret = sendto(sock, buf, 5, 0, (struct sockaddr *)&other, alen);
1025     g_assert_cmpint(ret, ==, 5);
1026 
1027     main_loop();
1028 
1029     if (!reuse_chr) {
1030         close(sock);
1031         qemu_chr_fe_deinit(be, true);
1032     }
1033     g_free(tmp);
1034 }
1035 
char_udp_test(void)1036 static void char_udp_test(void)
1037 {
1038     char_udp_test_internal(NULL, 0);
1039 }
1040 
1041 
1042 typedef struct {
1043     int event;
1044     bool got_pong;
1045     CharBackend *be;
1046 } CharSocketTestData;
1047 
1048 
1049 #define SOCKET_PING "Hello"
1050 #define SOCKET_PONG "World"
1051 
1052 typedef void (*char_socket_cb)(void *opaque, QEMUChrEvent event);
1053 
1054 static void
char_socket_event(void * opaque,QEMUChrEvent event)1055 char_socket_event(void *opaque, QEMUChrEvent event)
1056 {
1057     CharSocketTestData *data = opaque;
1058     data->event = event;
1059 }
1060 
1061 static void
char_socket_event_with_error(void * opaque,QEMUChrEvent event)1062 char_socket_event_with_error(void *opaque, QEMUChrEvent event)
1063 {
1064     static bool first_error;
1065     CharSocketTestData *data = opaque;
1066     CharBackend *be = data->be;
1067     data->event = event;
1068     switch (event) {
1069     case CHR_EVENT_OPENED:
1070         if (!first_error) {
1071             first_error = true;
1072             qemu_chr_fe_disconnect(be);
1073         }
1074         return;
1075     case CHR_EVENT_CLOSED:
1076         return;
1077     default:
1078         return;
1079     }
1080 }
1081 
1082 
1083 static void
char_socket_read(void * opaque,const uint8_t * buf,int size)1084 char_socket_read(void *opaque, const uint8_t *buf, int size)
1085 {
1086     CharSocketTestData *data = opaque;
1087     g_assert_cmpint(size, ==, sizeof(SOCKET_PONG));
1088     g_assert(memcmp(buf, SOCKET_PONG, size) == 0);
1089     data->got_pong = true;
1090 }
1091 
1092 
1093 static int
char_socket_can_read(void * opaque)1094 char_socket_can_read(void *opaque)
1095 {
1096     return sizeof(SOCKET_PONG);
1097 }
1098 
1099 
1100 static char *
char_socket_addr_to_opt_str(SocketAddress * addr,bool fd_pass,const char * reconnect,bool is_listen)1101 char_socket_addr_to_opt_str(SocketAddress *addr, bool fd_pass,
1102                             const char *reconnect, bool is_listen)
1103 {
1104     if (fd_pass) {
1105         QIOChannelSocket *ioc = qio_channel_socket_new();
1106         int fd;
1107         char *optstr;
1108         g_assert(!reconnect);
1109         if (is_listen) {
1110             qio_channel_socket_listen_sync(ioc, addr, 1, &error_abort);
1111         } else {
1112             qio_channel_socket_connect_sync(ioc, addr, &error_abort);
1113         }
1114         fd = ioc->fd;
1115         ioc->fd = -1;
1116         optstr = g_strdup_printf("socket,id=cdev0,fd=%d%s",
1117                                  fd, is_listen ? ",server=on,wait=off" : "");
1118         object_unref(OBJECT(ioc));
1119         return optstr;
1120     } else {
1121         switch (addr->type) {
1122         case SOCKET_ADDRESS_TYPE_INET:
1123             return g_strdup_printf("socket,id=cdev0,host=%s,port=%s%s%s",
1124                                    addr->u.inet.host,
1125                                    addr->u.inet.port,
1126                                    reconnect ? reconnect : "",
1127                                    is_listen ? ",server=on,wait=off" : "");
1128 
1129         case SOCKET_ADDRESS_TYPE_UNIX:
1130             return g_strdup_printf("socket,id=cdev0,path=%s%s%s",
1131                                    addr->u.q_unix.path,
1132                                    reconnect ? reconnect : "",
1133                                    is_listen ? ",server=on,wait=off" : "");
1134 
1135         default:
1136             g_assert_not_reached();
1137         }
1138     }
1139 }
1140 
1141 
1142 static int
char_socket_ping_pong(QIOChannel * ioc,Error ** errp)1143 char_socket_ping_pong(QIOChannel *ioc, Error **errp)
1144 {
1145     char greeting[sizeof(SOCKET_PING)];
1146     const char *response = SOCKET_PONG;
1147 
1148     int ret;
1149     ret = qio_channel_read_all(ioc, greeting, sizeof(greeting), errp);
1150     if (ret != 0) {
1151         object_unref(OBJECT(ioc));
1152         return -1;
1153     }
1154 
1155     g_assert(memcmp(greeting, SOCKET_PING, sizeof(greeting)) == 0);
1156 
1157     qio_channel_write_all(ioc, response, sizeof(SOCKET_PONG), errp);
1158     object_unref(OBJECT(ioc));
1159     return 0;
1160 }
1161 
1162 
1163 static gpointer
char_socket_server_client_thread(gpointer data)1164 char_socket_server_client_thread(gpointer data)
1165 {
1166     SocketAddress *addr = data;
1167     QIOChannelSocket *ioc = qio_channel_socket_new();
1168 
1169     qio_channel_socket_connect_sync(ioc, addr, &error_abort);
1170 
1171     char_socket_ping_pong(QIO_CHANNEL(ioc), &error_abort);
1172 
1173     return NULL;
1174 }
1175 
1176 
1177 typedef struct {
1178     SocketAddress *addr;
1179     bool wait_connected;
1180     bool fd_pass;
1181 } CharSocketServerTestConfig;
1182 
1183 
char_socket_server_test(gconstpointer opaque)1184 static void char_socket_server_test(gconstpointer opaque)
1185 {
1186     const CharSocketServerTestConfig *config = opaque;
1187     Chardev *chr;
1188     CharBackend be = {0};
1189     CharSocketTestData data = {0};
1190     QObject *qaddr;
1191     SocketAddress *addr;
1192     Visitor *v;
1193     QemuThread thread;
1194     int ret;
1195     bool reconnected = false;
1196     char *optstr;
1197     QemuOpts *opts;
1198 
1199     g_setenv("QTEST_SILENT_ERRORS", "1", 1);
1200     /*
1201      * We rely on config->addr containing "wait=off", otherwise
1202      * qemu_chr_new() will block until a client connects. We
1203      * can't spawn our client thread though, because until
1204      * qemu_chr_new() returns we don't know what TCP port was
1205      * allocated by the OS
1206      */
1207     optstr = char_socket_addr_to_opt_str(config->addr,
1208                                          config->fd_pass,
1209                                          NULL,
1210                                          true);
1211     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
1212                                    optstr, true);
1213     g_assert_nonnull(opts);
1214     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
1215     qemu_opts_del(opts);
1216     g_assert_nonnull(chr);
1217     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
1218 
1219     qaddr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
1220     g_assert_nonnull(qaddr);
1221 
1222     v = qobject_input_visitor_new(qaddr);
1223     visit_type_SocketAddress(v, "addr", &addr, &error_abort);
1224     visit_free(v);
1225     qobject_unref(qaddr);
1226 
1227     qemu_chr_fe_init(&be, chr, &error_abort);
1228 
1229  reconnect:
1230     data.event = -1;
1231     data.be = &be;
1232     qemu_chr_fe_set_handlers(&be, NULL, NULL,
1233                              char_socket_event, NULL,
1234                              &data, NULL, true);
1235     g_assert(data.event == -1);
1236 
1237     /*
1238      * Kick off a thread to act as the "remote" client
1239      * which just plays ping-pong with us
1240      */
1241     qemu_thread_create(&thread, "client",
1242                        char_socket_server_client_thread,
1243                        addr, QEMU_THREAD_JOINABLE);
1244     g_assert(data.event == -1);
1245 
1246     if (config->wait_connected) {
1247         /* Synchronously accept a connection */
1248         qemu_chr_wait_connected(chr, &error_abort);
1249     } else {
1250         /*
1251          * Asynchronously accept a connection when the evnt
1252          * loop reports the listener socket as readable
1253          */
1254         while (data.event == -1) {
1255             main_loop_wait(false);
1256         }
1257     }
1258     g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
1259     g_assert(data.event == CHR_EVENT_OPENED);
1260     data.event = -1;
1261 
1262     /* Send a greeting to the client */
1263     ret = qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING,
1264                                 sizeof(SOCKET_PING));
1265     g_assert_cmpint(ret, ==, sizeof(SOCKET_PING));
1266     g_assert(data.event == -1);
1267 
1268     /* Setup a callback to receive the reply to our greeting */
1269     qemu_chr_fe_set_handlers(&be, char_socket_can_read,
1270                              char_socket_read,
1271                              char_socket_event, NULL,
1272                              &data, NULL, true);
1273     g_assert(data.event == CHR_EVENT_OPENED);
1274     data.event = -1;
1275 
1276     /* Wait for the client to go away */
1277     while (data.event == -1) {
1278         main_loop_wait(false);
1279     }
1280     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
1281     g_assert(data.event == CHR_EVENT_CLOSED);
1282     g_assert(data.got_pong);
1283 
1284     qemu_thread_join(&thread);
1285 
1286     if (!reconnected) {
1287         reconnected = true;
1288         goto reconnect;
1289     }
1290 
1291     qapi_free_SocketAddress(addr);
1292     object_unparent(OBJECT(chr));
1293     g_free(optstr);
1294     g_unsetenv("QTEST_SILENT_ERRORS");
1295 }
1296 
1297 
1298 static gpointer
char_socket_client_server_thread(gpointer data)1299 char_socket_client_server_thread(gpointer data)
1300 {
1301     QIOChannelSocket *ioc = data;
1302     QIOChannelSocket *cioc;
1303 
1304 retry:
1305     cioc = qio_channel_socket_accept(ioc, &error_abort);
1306     g_assert_nonnull(cioc);
1307 
1308     if (char_socket_ping_pong(QIO_CHANNEL(cioc), NULL) != 0) {
1309         goto retry;
1310     }
1311 
1312     return NULL;
1313 }
1314 
1315 
1316 typedef struct {
1317     SocketAddress *addr;
1318     const char *reconnect;
1319     bool wait_connected;
1320     bool fd_pass;
1321     char_socket_cb event_cb;
1322 } CharSocketClientTestConfig;
1323 
char_socket_client_dupid_test(gconstpointer opaque)1324 static void char_socket_client_dupid_test(gconstpointer opaque)
1325 {
1326     const CharSocketClientTestConfig *config = opaque;
1327     QIOChannelSocket *ioc;
1328     char *optstr;
1329     Chardev *chr1, *chr2;
1330     SocketAddress *addr;
1331     QemuOpts *opts;
1332     Error *local_err = NULL;
1333 
1334     /*
1335      * Setup a listener socket and determine get its address
1336      * so we know the TCP port for the client later
1337      */
1338     ioc = qio_channel_socket_new();
1339     g_assert_nonnull(ioc);
1340     qio_channel_socket_listen_sync(ioc, config->addr, 1, &error_abort);
1341     addr = qio_channel_socket_get_local_address(ioc, &error_abort);
1342     g_assert_nonnull(addr);
1343 
1344     /*
1345      * Populate the chardev address based on what the server
1346      * is actually listening on
1347      */
1348     optstr = char_socket_addr_to_opt_str(addr,
1349                                          config->fd_pass,
1350                                          config->reconnect,
1351                                          false);
1352 
1353     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
1354                                    optstr, true);
1355     g_assert_nonnull(opts);
1356     chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort);
1357     g_assert_nonnull(chr1);
1358     qemu_chr_wait_connected(chr1, &error_abort);
1359 
1360     chr2 = qemu_chr_new_from_opts(opts, NULL, &local_err);
1361     g_assert_null(chr2);
1362     error_free_or_abort(&local_err);
1363 
1364     object_unref(OBJECT(ioc));
1365     qemu_opts_del(opts);
1366     object_unparent(OBJECT(chr1));
1367     qapi_free_SocketAddress(addr);
1368     g_free(optstr);
1369 }
1370 
char_socket_client_test(gconstpointer opaque)1371 static void char_socket_client_test(gconstpointer opaque)
1372 {
1373     const CharSocketClientTestConfig *config = opaque;
1374     const char_socket_cb event_cb = config->event_cb;
1375     QIOChannelSocket *ioc;
1376     char *optstr;
1377     Chardev *chr;
1378     CharBackend be = {0};
1379     CharSocketTestData data = {0};
1380     SocketAddress *addr;
1381     QemuThread thread;
1382     int ret;
1383     bool reconnected = false;
1384     QemuOpts *opts;
1385 
1386     /*
1387      * Setup a listener socket and determine get its address
1388      * so we know the TCP port for the client later
1389      */
1390     ioc = qio_channel_socket_new();
1391     g_assert_nonnull(ioc);
1392     qio_channel_socket_listen_sync(ioc, config->addr, 1, &error_abort);
1393     addr = qio_channel_socket_get_local_address(ioc, &error_abort);
1394     g_assert_nonnull(addr);
1395 
1396     /*
1397      * Kick off a thread to act as the "remote" client
1398      * which just plays ping-pong with us
1399      */
1400     qemu_thread_create(&thread, "client",
1401                        char_socket_client_server_thread,
1402                        ioc, QEMU_THREAD_JOINABLE);
1403 
1404     /*
1405      * Populate the chardev address based on what the server
1406      * is actually listening on
1407      */
1408     optstr = char_socket_addr_to_opt_str(addr,
1409                                          config->fd_pass,
1410                                          config->reconnect,
1411                                          false);
1412 
1413     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
1414                                    optstr, true);
1415     g_assert_nonnull(opts);
1416     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
1417     qemu_opts_del(opts);
1418     g_assert_nonnull(chr);
1419 
1420     if (config->reconnect) {
1421         /*
1422          * If reconnect is set, the connection will be
1423          * established in a background thread and we won't
1424          * see the "connected" status updated until we
1425          * run the main event loop, or call qemu_chr_wait_connected
1426          */
1427         g_assert(!object_property_get_bool(OBJECT(chr), "connected",
1428                                            &error_abort));
1429     } else {
1430         g_assert(object_property_get_bool(OBJECT(chr), "connected",
1431                                           &error_abort));
1432     }
1433 
1434     qemu_chr_fe_init(&be, chr, &error_abort);
1435 
1436  reconnect:
1437     data.event = -1;
1438     data.be = &be;
1439     qemu_chr_fe_set_handlers(&be, NULL, NULL,
1440                              event_cb, NULL,
1441                              &data, NULL, true);
1442     if (config->reconnect) {
1443         g_assert(data.event == -1);
1444     } else {
1445         g_assert(data.event == CHR_EVENT_OPENED);
1446     }
1447 
1448     if (config->wait_connected) {
1449         /*
1450          * Synchronously wait for the connection to complete
1451          * This should be a no-op if reconnect is not set.
1452          */
1453         qemu_chr_wait_connected(chr, &error_abort);
1454     } else {
1455         /*
1456          * Asynchronously wait for the connection to be reported
1457          * as complete when the background thread reports its
1458          * status.
1459          * The loop will short-circuit if reconnect was set
1460          */
1461         while (data.event == -1) {
1462             main_loop_wait(false);
1463         }
1464     }
1465     g_assert(data.event == CHR_EVENT_OPENED);
1466     data.event = -1;
1467     g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
1468 
1469     /* Send a greeting to the server */
1470     ret = qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING,
1471                                 sizeof(SOCKET_PING));
1472     g_assert_cmpint(ret, ==, sizeof(SOCKET_PING));
1473     g_assert(data.event == -1);
1474 
1475     /* Setup a callback to receive the reply to our greeting */
1476     qemu_chr_fe_set_handlers(&be, char_socket_can_read,
1477                              char_socket_read,
1478                              event_cb, NULL,
1479                              &data, NULL, true);
1480     g_assert(data.event == CHR_EVENT_OPENED);
1481     data.event = -1;
1482 
1483     /* Wait for the server to go away */
1484     while (data.event == -1) {
1485         main_loop_wait(false);
1486     }
1487     g_assert(data.event == CHR_EVENT_CLOSED);
1488     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
1489     g_assert(data.got_pong);
1490     qemu_thread_join(&thread);
1491 
1492     if (config->reconnect && !reconnected) {
1493         reconnected = true;
1494         qemu_thread_create(&thread, "client",
1495                            char_socket_client_server_thread,
1496                            ioc, QEMU_THREAD_JOINABLE);
1497         goto reconnect;
1498     }
1499 
1500     object_unref(OBJECT(ioc));
1501     object_unparent(OBJECT(chr));
1502     qapi_free_SocketAddress(addr);
1503     g_free(optstr);
1504 }
1505 
1506 static void
count_closed_event(void * opaque,QEMUChrEvent event)1507 count_closed_event(void *opaque, QEMUChrEvent event)
1508 {
1509     int *count = opaque;
1510     if (event == CHR_EVENT_CLOSED) {
1511         (*count)++;
1512     }
1513 }
1514 
1515 static void
char_socket_discard_read(void * opaque,const uint8_t * buf,int size)1516 char_socket_discard_read(void *opaque, const uint8_t *buf, int size)
1517 {
1518 }
1519 
char_socket_server_two_clients_test(gconstpointer opaque)1520 static void char_socket_server_two_clients_test(gconstpointer opaque)
1521 {
1522     SocketAddress *incoming_addr = (gpointer) opaque;
1523     Chardev *chr;
1524     CharBackend be = {0};
1525     QObject *qaddr;
1526     SocketAddress *addr;
1527     Visitor *v;
1528     char *optstr;
1529     QemuOpts *opts;
1530     QIOChannelSocket *ioc1, *ioc2;
1531     int closed = 0;
1532 
1533     g_setenv("QTEST_SILENT_ERRORS", "1", 1);
1534     /*
1535      * We rely on addr containing "wait=off", otherwise
1536      * qemu_chr_new() will block until a client connects. We
1537      * can't spawn our client thread though, because until
1538      * qemu_chr_new() returns we don't know what TCP port was
1539      * allocated by the OS
1540      */
1541     optstr = char_socket_addr_to_opt_str(incoming_addr,
1542                                          false,
1543                                          NULL,
1544                                          true);
1545     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
1546                                    optstr, true);
1547     g_assert_nonnull(opts);
1548     chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
1549     qemu_opts_del(opts);
1550     g_assert_nonnull(chr);
1551     g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
1552 
1553     qaddr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
1554     g_assert_nonnull(qaddr);
1555 
1556     v = qobject_input_visitor_new(qaddr);
1557     visit_type_SocketAddress(v, "addr", &addr, &error_abort);
1558     visit_free(v);
1559     qobject_unref(qaddr);
1560 
1561     qemu_chr_fe_init(&be, chr, &error_abort);
1562 
1563     qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
1564                              count_closed_event, NULL,
1565                              &closed, NULL, true);
1566 
1567     ioc1 = qio_channel_socket_new();
1568     qio_channel_socket_connect_sync(ioc1, addr, &error_abort);
1569     qemu_chr_wait_connected(chr, &error_abort);
1570 
1571     /* switch the chardev to another context */
1572     GMainContext *ctx = g_main_context_new();
1573     qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
1574                              count_closed_event, NULL,
1575                              &closed, ctx, true);
1576 
1577     /* Start a second connection while the first is still connected.
1578      * It will be placed in the listen() backlog, and connect() will
1579      * succeed immediately.
1580      */
1581     ioc2 = qio_channel_socket_new();
1582     qio_channel_socket_connect_sync(ioc2, addr, &error_abort);
1583 
1584     object_unref(OBJECT(ioc1));
1585     /* The two connections should now be processed serially.  */
1586     while (g_main_context_iteration(ctx, TRUE)) {
1587         if (closed == 1 && ioc2) {
1588             object_unref(OBJECT(ioc2));
1589             ioc2 = NULL;
1590         }
1591         if (closed == 2) {
1592             break;
1593         }
1594     }
1595 
1596     qapi_free_SocketAddress(addr);
1597     object_unparent(OBJECT(chr));
1598     g_main_context_unref(ctx);
1599     g_free(optstr);
1600     g_unsetenv("QTEST_SILENT_ERRORS");
1601 }
1602 
1603 
1604 #if defined(HAVE_CHARDEV_SERIAL) && !defined(WIN32)
char_serial_test(void)1605 static void char_serial_test(void)
1606 {
1607     QemuOpts *opts;
1608     Chardev *chr;
1609 
1610     opts = qemu_opts_create(qemu_find_opts("chardev"), "serial-id",
1611                             1, &error_abort);
1612     qemu_opt_set(opts, "backend", "serial", &error_abort);
1613     qemu_opt_set(opts, "path", "/dev/null", &error_abort);
1614 
1615     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
1616     g_assert_nonnull(chr);
1617     /* TODO: add more tests with a pty */
1618     object_unparent(OBJECT(chr));
1619 
1620     qemu_opts_del(opts);
1621 }
1622 #endif
1623 
1624 #if defined(HAVE_CHARDEV_PARALLEL) && !defined(WIN32)
char_parallel_test(void)1625 static void char_parallel_test(void)
1626 {
1627     QemuOpts *opts;
1628     Chardev *chr;
1629 
1630     opts = qemu_opts_create(qemu_find_opts("chardev"), "parallel-id",
1631                             1, &error_abort);
1632     qemu_opt_set(opts, "backend", "parallel", &error_abort);
1633     qemu_opt_set(opts, "path", "/dev/null", &error_abort);
1634 
1635     chr = qemu_chr_new_from_opts(opts, NULL, NULL);
1636 #ifdef __linux__
1637     /* fails to PPCLAIM, see qemu_chr_open_pp_fd() */
1638     g_assert_null(chr);
1639 #else
1640     g_assert_nonnull(chr);
1641     object_unparent(OBJECT(chr));
1642 #endif
1643 
1644     qemu_opts_del(opts);
1645 }
1646 #endif
1647 
1648 #ifndef _WIN32
char_file_fifo_test(void)1649 static void char_file_fifo_test(void)
1650 {
1651     Chardev *chr;
1652     CharBackend be;
1653     char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
1654     char *fifo = g_build_filename(tmp_path, "fifo", NULL);
1655     char *out = g_build_filename(tmp_path, "out", NULL);
1656     ChardevFile file = { .in = fifo,
1657                          .out = out };
1658     ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
1659                                .u.file.data = &file };
1660     FeHandler fe = { 0, };
1661     int fd, ret;
1662 
1663     if (mkfifo(fifo, 0600) < 0) {
1664         abort();
1665     }
1666 
1667     fd = open(fifo, O_RDWR);
1668     ret = write(fd, "fifo-in", 8);
1669     g_assert_cmpint(ret, ==, 8);
1670 
1671     chr = qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend,
1672                            NULL, &error_abort);
1673 
1674     qemu_chr_fe_init(&be, chr, &error_abort);
1675     qemu_chr_fe_set_handlers(&be,
1676                              fe_can_read,
1677                              fe_read,
1678                              fe_event,
1679                              NULL,
1680                              &fe, NULL, true);
1681 
1682     g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK);
1683     qmp_chardev_send_break("label-foo", NULL);
1684     g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK);
1685     qmp_chardev_send_break("label-file", NULL);
1686     g_assert_cmpint(fe.last_event, ==, CHR_EVENT_BREAK);
1687 
1688     main_loop();
1689 
1690     close(fd);
1691 
1692     g_assert_cmpint(fe.read_count, ==, 8);
1693     g_assert_cmpstr(fe.read_buf, ==, "fifo-in");
1694 
1695     qemu_chr_fe_deinit(&be, true);
1696 
1697     g_unlink(fifo);
1698     g_free(fifo);
1699     g_unlink(out);
1700     g_free(out);
1701     g_rmdir(tmp_path);
1702     g_free(tmp_path);
1703 }
1704 #endif
1705 
char_file_test_internal(Chardev * ext_chr,const char * filepath)1706 static void char_file_test_internal(Chardev *ext_chr, const char *filepath)
1707 {
1708     char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
1709     char *out;
1710     Chardev *chr;
1711     char *contents = NULL;
1712     ChardevFile file = {};
1713     ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
1714                                .u.file.data = &file };
1715     gsize length;
1716     int ret;
1717 
1718     if (ext_chr) {
1719         chr = ext_chr;
1720         out = g_strdup(filepath);
1721         file.out = out;
1722     } else {
1723         out = g_build_filename(tmp_path, "out", NULL);
1724         file.out = out;
1725         chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend,
1726                                NULL, &error_abort);
1727     }
1728     ret = qemu_chr_write_all(chr, (uint8_t *)"hello!", 6);
1729     g_assert_cmpint(ret, ==, 6);
1730 
1731     ret = g_file_get_contents(out, &contents, &length, NULL);
1732     g_assert(ret == TRUE);
1733     g_assert_cmpint(length, ==, 6);
1734     g_assert(strncmp(contents, "hello!", 6) == 0);
1735 
1736     if (!ext_chr) {
1737         object_unparent(OBJECT(chr));
1738         g_unlink(out);
1739     }
1740     g_free(contents);
1741     g_rmdir(tmp_path);
1742     g_free(tmp_path);
1743     g_free(out);
1744 }
1745 
char_file_test(void)1746 static void char_file_test(void)
1747 {
1748     char_file_test_internal(NULL, NULL);
1749 }
1750 
char_null_test(void)1751 static void char_null_test(void)
1752 {
1753     Error *err = NULL;
1754     Chardev *chr;
1755     CharBackend be;
1756     int ret;
1757 
1758     chr = qemu_chr_find("label-null");
1759     g_assert_null(chr);
1760 
1761     chr = qemu_chr_new("label-null", "null", NULL);
1762     chr = qemu_chr_find("label-null");
1763     g_assert_nonnull(chr);
1764 
1765     g_assert(qemu_chr_has_feature(chr,
1766                  QEMU_CHAR_FEATURE_FD_PASS) == false);
1767     g_assert(qemu_chr_has_feature(chr,
1768                  QEMU_CHAR_FEATURE_RECONNECTABLE) == false);
1769 
1770     /* check max avail */
1771     qemu_chr_fe_init(&be, chr, &error_abort);
1772     qemu_chr_fe_init(&be, chr, &err);
1773     error_free_or_abort(&err);
1774 
1775     /* deinit & reinit */
1776     qemu_chr_fe_deinit(&be, false);
1777     qemu_chr_fe_init(&be, chr, &error_abort);
1778 
1779     qemu_chr_fe_set_open(&be, true);
1780 
1781     qemu_chr_fe_set_handlers(&be,
1782                              fe_can_read,
1783                              fe_read,
1784                              fe_event,
1785                              NULL,
1786                              NULL, NULL, true);
1787 
1788     ret = qemu_chr_fe_write(&be, (void *)"buf", 4);
1789     g_assert_cmpint(ret, ==, 4);
1790 
1791     qemu_chr_fe_deinit(&be, true);
1792 }
1793 
char_invalid_test(void)1794 static void char_invalid_test(void)
1795 {
1796     Chardev *chr;
1797     g_setenv("QTEST_SILENT_ERRORS", "1", 1);
1798     chr = qemu_chr_new("label-invalid", "invalid", NULL);
1799     g_assert_null(chr);
1800     g_unsetenv("QTEST_SILENT_ERRORS");
1801 }
1802 
chardev_change(void * opaque)1803 static int chardev_change(void *opaque)
1804 {
1805     return 0;
1806 }
1807 
chardev_change_denied(void * opaque)1808 static int chardev_change_denied(void *opaque)
1809 {
1810     return -1;
1811 }
1812 
char_hotswap_test(void)1813 static void char_hotswap_test(void)
1814 {
1815     char *chr_args;
1816     Chardev *chr;
1817     CharBackend be;
1818 
1819     gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
1820     char *filename = g_build_filename(tmp_path, "file", NULL);
1821     ChardevFile file = { .out = filename };
1822     ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
1823                                .u.file.data = &file };
1824     ChardevReturn *ret;
1825 
1826     int port;
1827     int sock = make_udp_socket(&port);
1828     g_assert_cmpint(sock, >=, 0);
1829 
1830     chr_args = g_strdup_printf("udp:127.0.0.1:%d", port);
1831 
1832     chr = qemu_chr_new("chardev", chr_args, NULL);
1833     qemu_chr_fe_init(&be, chr, &error_abort);
1834 
1835     /* check that chardev operates correctly */
1836     char_udp_test_internal(chr, sock);
1837 
1838     /* set the handler that denies the hotswap */
1839     qemu_chr_fe_set_handlers(&be, NULL, NULL,
1840                              NULL, chardev_change_denied, NULL, NULL, true);
1841 
1842     /* now, change is denied and has to keep the old backend operating */
1843     ret = qmp_chardev_change("chardev", &backend, NULL);
1844     g_assert(!ret);
1845     g_assert(be.chr == chr);
1846 
1847     char_udp_test_internal(chr, sock);
1848 
1849     /* now allow the change */
1850     qemu_chr_fe_set_handlers(&be, NULL, NULL,
1851                              NULL, chardev_change, NULL, NULL, true);
1852 
1853     /* has to succeed now */
1854     ret = qmp_chardev_change("chardev", &backend, &error_abort);
1855     g_assert(be.chr != chr);
1856 
1857     close(sock);
1858     chr = be.chr;
1859 
1860     /* run the file chardev test */
1861     char_file_test_internal(chr, filename);
1862 
1863     object_unparent(OBJECT(chr));
1864 
1865     qapi_free_ChardevReturn(ret);
1866     g_unlink(filename);
1867     g_free(filename);
1868     g_rmdir(tmp_path);
1869     g_free(tmp_path);
1870     g_free(chr_args);
1871 }
1872 
1873 static SocketAddress tcpaddr = {
1874     .type = SOCKET_ADDRESS_TYPE_INET,
1875     .u.inet.host = (char *)"127.0.0.1",
1876     .u.inet.port = (char *)"0",
1877 };
1878 #ifndef WIN32
1879 static SocketAddress unixaddr = {
1880     .type = SOCKET_ADDRESS_TYPE_UNIX,
1881     .u.q_unix.path = (char *)"test-char.sock",
1882 };
1883 #endif
1884 
main(int argc,char ** argv)1885 int main(int argc, char **argv)
1886 {
1887     bool has_ipv4, has_ipv6;
1888 
1889     qemu_init_main_loop(&error_abort);
1890     socket_init();
1891 
1892     g_test_init(&argc, &argv, NULL);
1893 
1894     if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) {
1895         g_printerr("socket_check_protocol_support() failed\n");
1896         goto end;
1897     }
1898 
1899     module_call_init(MODULE_INIT_QOM);
1900     qemu_add_opts(&qemu_chardev_opts);
1901 
1902     g_test_add_func("/char/null", char_null_test);
1903     g_test_add_func("/char/invalid", char_invalid_test);
1904     g_test_add_func("/char/ringbuf", char_ringbuf_test);
1905     g_test_add_func("/char/mux", char_mux_test);
1906     g_test_add_func("/char/hub", char_hub_test);
1907 #ifdef _WIN32
1908     g_test_add_func("/char/console/subprocess", char_console_test_subprocess);
1909     g_test_add_func("/char/console", char_console_test);
1910 #endif
1911     g_test_add_func("/char/stdio/subprocess", char_stdio_test_subprocess);
1912     g_test_add_func("/char/stdio", char_stdio_test);
1913 #ifndef _WIN32
1914     g_test_add_func("/char/pipe", char_pipe_test);
1915 #endif
1916     g_test_add_func("/char/file", char_file_test);
1917 #ifndef _WIN32
1918     g_test_add_func("/char/file-fifo", char_file_fifo_test);
1919 #endif
1920 
1921 #define SOCKET_SERVER_TEST(name, addr)                                  \
1922     static CharSocketServerTestConfig server1 ## name =                 \
1923         { addr, false, false };                                         \
1924     static CharSocketServerTestConfig server2 ## name =                 \
1925         { addr, true, false };                                          \
1926     static CharSocketServerTestConfig server3 ## name =                 \
1927         { addr, false, true };                                          \
1928     static CharSocketServerTestConfig server4 ## name =                 \
1929         { addr, true, true };                                           \
1930     g_test_add_data_func("/char/socket/server/mainloop/" # name,        \
1931                          &server1 ##name, char_socket_server_test);     \
1932     g_test_add_data_func("/char/socket/server/wait-conn/" # name,       \
1933                          &server2 ##name, char_socket_server_test);     \
1934     g_test_add_data_func("/char/socket/server/mainloop-fdpass/" # name, \
1935                          &server3 ##name, char_socket_server_test);     \
1936     g_test_add_data_func("/char/socket/server/wait-conn-fdpass/" # name, \
1937                          &server4 ##name, char_socket_server_test)
1938 
1939 #define SOCKET_CLIENT_TEST(name, addr)                                  \
1940     static CharSocketClientTestConfig client1 ## name =                 \
1941         { addr, NULL, false, false, char_socket_event };                \
1942     static CharSocketClientTestConfig client2 ## name =                 \
1943         { addr, NULL, true, false, char_socket_event };                 \
1944     static CharSocketClientTestConfig client3 ## name =                 \
1945         { addr, ",reconnect-ms=1000", false, false, char_socket_event }; \
1946     static CharSocketClientTestConfig client4 ## name =                 \
1947         { addr, ",reconnect-ms=1000", true, false, char_socket_event }; \
1948     static CharSocketClientTestConfig client5 ## name =                 \
1949         { addr, NULL, false, true, char_socket_event };                 \
1950     static CharSocketClientTestConfig client6 ## name =                 \
1951         { addr, NULL, true, true, char_socket_event };                  \
1952     static CharSocketClientTestConfig client7 ## name =                 \
1953         { addr, ",reconnect-ms=1000", true, false,                      \
1954             char_socket_event_with_error };                             \
1955     static CharSocketClientTestConfig client8 ## name =                 \
1956         { addr, ",reconnect-ms=1000", false, false, char_socket_event };\
1957     g_test_add_data_func("/char/socket/client/mainloop/" # name,        \
1958                          &client1 ##name, char_socket_client_test);     \
1959     g_test_add_data_func("/char/socket/client/wait-conn/" # name,       \
1960                          &client2 ##name, char_socket_client_test);     \
1961     g_test_add_data_func("/char/socket/client/mainloop-reconnect/" # name, \
1962                          &client3 ##name, char_socket_client_test);     \
1963     g_test_add_data_func("/char/socket/client/wait-conn-reconnect/" # name, \
1964                          &client4 ##name, char_socket_client_test);     \
1965     g_test_add_data_func("/char/socket/client/mainloop-fdpass/" # name, \
1966                          &client5 ##name, char_socket_client_test);     \
1967     g_test_add_data_func("/char/socket/client/wait-conn-fdpass/" # name, \
1968                          &client6 ##name, char_socket_client_test);     \
1969     g_test_add_data_func("/char/socket/client/reconnect-error/" # name, \
1970                          &client7 ##name, char_socket_client_test);     \
1971     g_test_add_data_func("/char/socket/client/dupid-reconnect/" # name, \
1972                          &client8 ##name, char_socket_client_dupid_test)
1973 
1974     if (has_ipv4) {
1975         SOCKET_SERVER_TEST(tcp, &tcpaddr);
1976         SOCKET_CLIENT_TEST(tcp, &tcpaddr);
1977         g_test_add_data_func("/char/socket/server/two-clients/tcp", &tcpaddr,
1978                              char_socket_server_two_clients_test);
1979     }
1980 #ifndef WIN32
1981     SOCKET_SERVER_TEST(unix, &unixaddr);
1982     SOCKET_CLIENT_TEST(unix, &unixaddr);
1983     g_test_add_data_func("/char/socket/server/two-clients/unix", &unixaddr,
1984                          char_socket_server_two_clients_test);
1985 #endif
1986 
1987     g_test_add_func("/char/udp", char_udp_test);
1988 #if defined(HAVE_CHARDEV_SERIAL) && !defined(WIN32)
1989     g_test_add_func("/char/serial", char_serial_test);
1990 #endif
1991 #if defined(HAVE_CHARDEV_PARALLEL) && !defined(WIN32)
1992     g_test_add_func("/char/parallel", char_parallel_test);
1993 #endif
1994     g_test_add_func("/char/hotswap", char_hotswap_test);
1995     g_test_add_func("/char/websocket", char_websock_test);
1996 
1997 end:
1998     return g_test_run();
1999 }
2000