xref: /openbmc/qemu/chardev/char.c (revision 795c40b8)
1 /*
2  * QEMU System Emulator
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "qemu/osdep.h"
25 #include "qemu-common.h"
26 #include "qemu/cutils.h"
27 #include "monitor/monitor.h"
28 #include "sysemu/sysemu.h"
29 #include "qemu/config-file.h"
30 #include "qemu/error-report.h"
31 #include "sysemu/char.h"
32 #include "qmp-commands.h"
33 #include "qapi-visit.h"
34 #include "sysemu/replay.h"
35 #include "qemu/help_option.h"
36 
37 #include "char-mux.h"
38 #include "char-io.h"
39 #include "char-parallel.h"
40 #include "char-serial.h"
41 
42 /***********************************************************/
43 /* character device */
44 
45 static Object *get_chardevs_root(void)
46 {
47     return container_get(object_get_root(), "/chardevs");
48 }
49 
50 void qemu_chr_be_event(Chardev *s, int event)
51 {
52     CharBackend *be = s->be;
53 
54     /* Keep track if the char device is open */
55     switch (event) {
56         case CHR_EVENT_OPENED:
57             s->be_open = 1;
58             break;
59         case CHR_EVENT_CLOSED:
60             s->be_open = 0;
61             break;
62     }
63 
64     if (!be || !be->chr_event) {
65         return;
66     }
67 
68     be->chr_event(be->opaque, event);
69 }
70 
71 /* Not reporting errors from writing to logfile, as logs are
72  * defined to be "best effort" only */
73 static void qemu_chr_fe_write_log(Chardev *s,
74                                   const uint8_t *buf, size_t len)
75 {
76     size_t done = 0;
77     ssize_t ret;
78 
79     if (s->logfd < 0) {
80         return;
81     }
82 
83     while (done < len) {
84     retry:
85         ret = write(s->logfd, buf + done, len - done);
86         if (ret == -1 && errno == EAGAIN) {
87             g_usleep(100);
88             goto retry;
89         }
90 
91         if (ret <= 0) {
92             return;
93         }
94         done += ret;
95     }
96 }
97 
98 static int qemu_chr_fe_write_buffer(Chardev *s,
99                                     const uint8_t *buf, int len, int *offset)
100 {
101     ChardevClass *cc = CHARDEV_GET_CLASS(s);
102     int res = 0;
103     *offset = 0;
104 
105     qemu_mutex_lock(&s->chr_write_lock);
106     while (*offset < len) {
107     retry:
108         res = cc->chr_write(s, buf + *offset, len - *offset);
109         if (res < 0 && errno == EAGAIN) {
110             g_usleep(100);
111             goto retry;
112         }
113 
114         if (res <= 0) {
115             break;
116         }
117 
118         *offset += res;
119     }
120     if (*offset > 0) {
121         qemu_chr_fe_write_log(s, buf, *offset);
122     }
123     qemu_mutex_unlock(&s->chr_write_lock);
124 
125     return res;
126 }
127 
128 static bool qemu_chr_replay(Chardev *chr)
129 {
130     return qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
131 }
132 
133 int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
134 {
135     Chardev *s = be->chr;
136     ChardevClass *cc;
137     int ret;
138 
139     if (!s) {
140         return 0;
141     }
142 
143     if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
144         int offset;
145         replay_char_write_event_load(&ret, &offset);
146         assert(offset <= len);
147         qemu_chr_fe_write_buffer(s, buf, offset, &offset);
148         return ret;
149     }
150 
151     cc = CHARDEV_GET_CLASS(s);
152     qemu_mutex_lock(&s->chr_write_lock);
153     ret = cc->chr_write(s, buf, len);
154 
155     if (ret > 0) {
156         qemu_chr_fe_write_log(s, buf, ret);
157     }
158 
159     qemu_mutex_unlock(&s->chr_write_lock);
160 
161     if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
162         replay_char_write_event_save(ret, ret < 0 ? 0 : ret);
163     }
164 
165     return ret;
166 }
167 
168 int qemu_chr_write_all(Chardev *s, const uint8_t *buf, int len)
169 {
170     int offset;
171     int res;
172 
173     if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
174         replay_char_write_event_load(&res, &offset);
175         assert(offset <= len);
176         qemu_chr_fe_write_buffer(s, buf, offset, &offset);
177         return res;
178     }
179 
180     res = qemu_chr_fe_write_buffer(s, buf, len, &offset);
181 
182     if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
183         replay_char_write_event_save(res, offset);
184     }
185 
186     if (res < 0) {
187         return res;
188     }
189     return offset;
190 }
191 
192 int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
193 {
194     Chardev *s = be->chr;
195 
196     if (!s) {
197         return 0;
198     }
199 
200     return qemu_chr_write_all(s, buf, len);
201 }
202 
203 int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
204 {
205     Chardev *s = be->chr;
206     int offset = 0, counter = 10;
207     int res;
208 
209     if (!s || !CHARDEV_GET_CLASS(s)->chr_sync_read) {
210         return 0;
211     }
212 
213     if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
214         return replay_char_read_all_load(buf);
215     }
216 
217     while (offset < len) {
218     retry:
219         res = CHARDEV_GET_CLASS(s)->chr_sync_read(s, buf + offset,
220                                                   len - offset);
221         if (res == -1 && errno == EAGAIN) {
222             g_usleep(100);
223             goto retry;
224         }
225 
226         if (res == 0) {
227             break;
228         }
229 
230         if (res < 0) {
231             if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
232                 replay_char_read_all_save_error(res);
233             }
234             return res;
235         }
236 
237         offset += res;
238 
239         if (!counter--) {
240             break;
241         }
242     }
243 
244     if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
245         replay_char_read_all_save_buf(buf, offset);
246     }
247     return offset;
248 }
249 
250 int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg)
251 {
252     Chardev *s = be->chr;
253     int res;
254 
255     if (!s || !CHARDEV_GET_CLASS(s)->chr_ioctl || qemu_chr_replay(s)) {
256         res = -ENOTSUP;
257     } else {
258         res = CHARDEV_GET_CLASS(s)->chr_ioctl(s, cmd, arg);
259     }
260 
261     return res;
262 }
263 
264 int qemu_chr_be_can_write(Chardev *s)
265 {
266     CharBackend *be = s->be;
267 
268     if (!be || !be->chr_can_read) {
269         return 0;
270     }
271 
272     return be->chr_can_read(be->opaque);
273 }
274 
275 void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len)
276 {
277     CharBackend *be = s->be;
278 
279     if (be && be->chr_read) {
280         be->chr_read(be->opaque, buf, len);
281     }
282 }
283 
284 void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len)
285 {
286     if (qemu_chr_replay(s)) {
287         if (replay_mode == REPLAY_MODE_PLAY) {
288             return;
289         }
290         replay_chr_be_write(s, buf, len);
291     } else {
292         qemu_chr_be_write_impl(s, buf, len);
293     }
294 }
295 
296 int qemu_chr_fe_get_msgfd(CharBackend *be)
297 {
298     Chardev *s = be->chr;
299     int fd;
300     int res = (qemu_chr_fe_get_msgfds(be, &fd, 1) == 1) ? fd : -1;
301     if (s && qemu_chr_replay(s)) {
302         error_report("Replay: get msgfd is not supported "
303                      "for serial devices yet");
304         exit(1);
305     }
306     return res;
307 }
308 
309 int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len)
310 {
311     Chardev *s = be->chr;
312 
313     if (!s) {
314         return -1;
315     }
316 
317     return CHARDEV_GET_CLASS(s)->get_msgfds ?
318         CHARDEV_GET_CLASS(s)->get_msgfds(s, fds, len) : -1;
319 }
320 
321 int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num)
322 {
323     Chardev *s = be->chr;
324 
325     if (!s) {
326         return -1;
327     }
328 
329     return CHARDEV_GET_CLASS(s)->set_msgfds ?
330         CHARDEV_GET_CLASS(s)->set_msgfds(s, fds, num) : -1;
331 }
332 
333 int qemu_chr_add_client(Chardev *s, int fd)
334 {
335     return CHARDEV_GET_CLASS(s)->chr_add_client ?
336         CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1;
337 }
338 
339 void qemu_chr_fe_accept_input(CharBackend *be)
340 {
341     Chardev *s = be->chr;
342 
343     if (!s) {
344         return;
345     }
346 
347     if (CHARDEV_GET_CLASS(s)->chr_accept_input) {
348         CHARDEV_GET_CLASS(s)->chr_accept_input(s);
349     }
350     qemu_notify_event();
351 }
352 
353 void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
354 {
355     char buf[CHR_READ_BUF_LEN];
356     va_list ap;
357     va_start(ap, fmt);
358     vsnprintf(buf, sizeof(buf), fmt, ap);
359     /* XXX this blocks entire thread. Rewrite to use
360      * qemu_chr_fe_write and background I/O callbacks */
361     qemu_chr_fe_write_all(be, (uint8_t *)buf, strlen(buf));
362     va_end(ap);
363 }
364 
365 static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
366                            bool *be_opened, Error **errp)
367 {
368     ChardevClass *cc = CHARDEV_GET_CLASS(chr);
369     /* Any ChardevCommon member would work */
370     ChardevCommon *common = backend ? backend->u.null.data : NULL;
371 
372     if (common && common->has_logfile) {
373         int flags = O_WRONLY | O_CREAT;
374         if (common->has_logappend &&
375             common->logappend) {
376             flags |= O_APPEND;
377         } else {
378             flags |= O_TRUNC;
379         }
380         chr->logfd = qemu_open(common->logfile, flags, 0666);
381         if (chr->logfd < 0) {
382             error_setg_errno(errp, errno,
383                              "Unable to open logfile %s",
384                              common->logfile);
385             return;
386         }
387     }
388 
389     if (cc->open) {
390         cc->open(chr, backend, be_opened, errp);
391     }
392 }
393 
394 static void char_init(Object *obj)
395 {
396     Chardev *chr = CHARDEV(obj);
397 
398     chr->logfd = -1;
399     qemu_mutex_init(&chr->chr_write_lock);
400 }
401 
402 static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
403 {
404     return len;
405 }
406 
407 static void char_class_init(ObjectClass *oc, void *data)
408 {
409     ChardevClass *cc = CHARDEV_CLASS(oc);
410 
411     cc->chr_write = null_chr_write;
412 }
413 
414 static void char_finalize(Object *obj)
415 {
416     Chardev *chr = CHARDEV(obj);
417 
418     if (chr->be) {
419         chr->be->chr = NULL;
420     }
421     g_free(chr->filename);
422     g_free(chr->label);
423     if (chr->logfd != -1) {
424         close(chr->logfd);
425     }
426     qemu_mutex_destroy(&chr->chr_write_lock);
427 }
428 
429 static const TypeInfo char_type_info = {
430     .name = TYPE_CHARDEV,
431     .parent = TYPE_OBJECT,
432     .instance_size = sizeof(Chardev),
433     .instance_init = char_init,
434     .instance_finalize = char_finalize,
435     .abstract = true,
436     .class_size = sizeof(ChardevClass),
437     .class_init = char_class_init,
438 };
439 
440 /**
441  * Called after processing of default and command-line-specified
442  * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
443  * to a mux chardev. This is done here to ensure that
444  * output/prompts/banners are only displayed for the FE that has
445  * focus when initial command-line processing/machine init is
446  * completed.
447  *
448  * After this point, any new FE attached to any new or existing
449  * mux will receive CHR_EVENT_OPENED notifications for the BE
450  * immediately.
451  */
452 static int open_muxes(Object *child, void *opaque)
453 {
454     if (CHARDEV_IS_MUX(child)) {
455         /* send OPENED to all already-attached FEs */
456         mux_chr_send_all_event(CHARDEV(child), CHR_EVENT_OPENED);
457         /* mark mux as OPENED so any new FEs will immediately receive
458          * OPENED event
459          */
460         qemu_chr_be_event(CHARDEV(child), CHR_EVENT_OPENED);
461     }
462 
463     return 0;
464 }
465 
466 static void muxes_realize_done(Notifier *notifier, void *unused)
467 {
468     muxes_realized = true;
469     object_child_foreach(get_chardevs_root(), open_muxes, NULL);
470 }
471 
472 static Notifier muxes_realize_notify = {
473     .notify = muxes_realize_done,
474 };
475 
476 Chardev *qemu_chr_fe_get_driver(CharBackend *be)
477 {
478     return be->chr;
479 }
480 
481 bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
482 {
483     int tag = 0;
484 
485     if (CHARDEV_IS_MUX(s)) {
486         MuxChardev *d = MUX_CHARDEV(s);
487 
488         if (d->mux_cnt >= MAX_MUX) {
489             goto unavailable;
490         }
491 
492         d->backends[d->mux_cnt] = b;
493         tag = d->mux_cnt++;
494     } else if (s->be) {
495         goto unavailable;
496     } else {
497         s->be = b;
498     }
499 
500     b->fe_open = false;
501     b->tag = tag;
502     b->chr = s;
503     return true;
504 
505 unavailable:
506     error_setg(errp, QERR_DEVICE_IN_USE, s->label);
507     return false;
508 }
509 
510 static bool qemu_chr_is_busy(Chardev *s)
511 {
512     if (CHARDEV_IS_MUX(s)) {
513         MuxChardev *d = MUX_CHARDEV(s);
514         return d->mux_cnt >= 0;
515     } else {
516         return s->be != NULL;
517     }
518 }
519 
520 void qemu_chr_fe_deinit(CharBackend *b)
521 {
522     assert(b);
523 
524     if (b->chr) {
525         qemu_chr_fe_set_handlers(b, NULL, NULL, NULL, NULL, NULL, true);
526         if (b->chr->be == b) {
527             b->chr->be = NULL;
528         }
529         if (CHARDEV_IS_MUX(b->chr)) {
530             MuxChardev *d = MUX_CHARDEV(b->chr);
531             d->backends[b->tag] = NULL;
532         }
533         b->chr = NULL;
534     }
535 }
536 
537 void qemu_chr_fe_set_handlers(CharBackend *b,
538                               IOCanReadHandler *fd_can_read,
539                               IOReadHandler *fd_read,
540                               IOEventHandler *fd_event,
541                               void *opaque,
542                               GMainContext *context,
543                               bool set_open)
544 {
545     Chardev *s;
546     ChardevClass *cc;
547     int fe_open;
548 
549     s = b->chr;
550     if (!s) {
551         return;
552     }
553 
554     cc = CHARDEV_GET_CLASS(s);
555     if (!opaque && !fd_can_read && !fd_read && !fd_event) {
556         fe_open = 0;
557         remove_fd_in_watch(s);
558     } else {
559         fe_open = 1;
560     }
561     b->chr_can_read = fd_can_read;
562     b->chr_read = fd_read;
563     b->chr_event = fd_event;
564     b->opaque = opaque;
565     if (cc->chr_update_read_handler) {
566         cc->chr_update_read_handler(s, context);
567     }
568 
569     if (set_open) {
570         qemu_chr_fe_set_open(b, fe_open);
571     }
572 
573     if (fe_open) {
574         qemu_chr_fe_take_focus(b);
575         /* We're connecting to an already opened device, so let's make sure we
576            also get the open event */
577         if (s->be_open) {
578             qemu_chr_be_event(s, CHR_EVENT_OPENED);
579         }
580     }
581 
582     if (CHARDEV_IS_MUX(s)) {
583         mux_chr_set_handlers(s, context);
584     }
585 }
586 
587 void qemu_chr_fe_take_focus(CharBackend *b)
588 {
589     if (!b->chr) {
590         return;
591     }
592 
593     if (CHARDEV_IS_MUX(b->chr)) {
594         mux_set_focus(b->chr, b->tag);
595     }
596 }
597 
598 int qemu_chr_wait_connected(Chardev *chr, Error **errp)
599 {
600     ChardevClass *cc = CHARDEV_GET_CLASS(chr);
601 
602     if (cc->chr_wait_connected) {
603         return cc->chr_wait_connected(chr, errp);
604     }
605 
606     return 0;
607 }
608 
609 int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp)
610 {
611     if (!be->chr) {
612         error_setg(errp, "missing associated backend");
613         return -1;
614     }
615 
616     return qemu_chr_wait_connected(be->chr, errp);
617 }
618 
619 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
620 {
621     char host[65], port[33], width[8], height[8];
622     int pos;
623     const char *p;
624     QemuOpts *opts;
625     Error *local_err = NULL;
626 
627     opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
628     if (local_err) {
629         error_report_err(local_err);
630         return NULL;
631     }
632 
633     if (strstart(filename, "mon:", &p)) {
634         filename = p;
635         qemu_opt_set(opts, "mux", "on", &error_abort);
636         if (strcmp(filename, "stdio") == 0) {
637             /* Monitor is muxed to stdio: do not exit on Ctrl+C by default
638              * but pass it to the guest.  Handle this only for compat syntax,
639              * for -chardev syntax we have special option for this.
640              * This is what -nographic did, redirecting+muxing serial+monitor
641              * to stdio causing Ctrl+C to be passed to guest. */
642             qemu_opt_set(opts, "signal", "off", &error_abort);
643         }
644     }
645 
646     if (strcmp(filename, "null")    == 0 ||
647         strcmp(filename, "pty")     == 0 ||
648         strcmp(filename, "msmouse") == 0 ||
649         strcmp(filename, "wctablet") == 0 ||
650         strcmp(filename, "braille") == 0 ||
651         strcmp(filename, "testdev") == 0 ||
652         strcmp(filename, "stdio")   == 0) {
653         qemu_opt_set(opts, "backend", filename, &error_abort);
654         return opts;
655     }
656     if (strstart(filename, "vc", &p)) {
657         qemu_opt_set(opts, "backend", "vc", &error_abort);
658         if (*p == ':') {
659             if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
660                 /* pixels */
661                 qemu_opt_set(opts, "width", width, &error_abort);
662                 qemu_opt_set(opts, "height", height, &error_abort);
663             } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
664                 /* chars */
665                 qemu_opt_set(opts, "cols", width, &error_abort);
666                 qemu_opt_set(opts, "rows", height, &error_abort);
667             } else {
668                 goto fail;
669             }
670         }
671         return opts;
672     }
673     if (strcmp(filename, "con:") == 0) {
674         qemu_opt_set(opts, "backend", "console", &error_abort);
675         return opts;
676     }
677     if (strstart(filename, "COM", NULL)) {
678         qemu_opt_set(opts, "backend", "serial", &error_abort);
679         qemu_opt_set(opts, "path", filename, &error_abort);
680         return opts;
681     }
682     if (strstart(filename, "file:", &p)) {
683         qemu_opt_set(opts, "backend", "file", &error_abort);
684         qemu_opt_set(opts, "path", p, &error_abort);
685         return opts;
686     }
687     if (strstart(filename, "pipe:", &p)) {
688         qemu_opt_set(opts, "backend", "pipe", &error_abort);
689         qemu_opt_set(opts, "path", p, &error_abort);
690         return opts;
691     }
692     if (strstart(filename, "tcp:", &p) ||
693         strstart(filename, "telnet:", &p) ||
694         strstart(filename, "tn3270:", &p)) {
695         if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
696             host[0] = 0;
697             if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
698                 goto fail;
699         }
700         qemu_opt_set(opts, "backend", "socket", &error_abort);
701         qemu_opt_set(opts, "host", host, &error_abort);
702         qemu_opt_set(opts, "port", port, &error_abort);
703         if (p[pos] == ',') {
704             qemu_opts_do_parse(opts, p+pos+1, NULL, &local_err);
705             if (local_err) {
706                 error_report_err(local_err);
707                 goto fail;
708             }
709         }
710         if (strstart(filename, "telnet:", &p)) {
711             qemu_opt_set(opts, "telnet", "on", &error_abort);
712         } else if (strstart(filename, "tn3270:", &p)) {
713             qemu_opt_set(opts, "tn3270", "on", &error_abort);
714         }
715         return opts;
716     }
717     if (strstart(filename, "udp:", &p)) {
718         qemu_opt_set(opts, "backend", "udp", &error_abort);
719         if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
720             host[0] = 0;
721             if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
722                 goto fail;
723             }
724         }
725         qemu_opt_set(opts, "host", host, &error_abort);
726         qemu_opt_set(opts, "port", port, &error_abort);
727         if (p[pos] == '@') {
728             p += pos + 1;
729             if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
730                 host[0] = 0;
731                 if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
732                     goto fail;
733                 }
734             }
735             qemu_opt_set(opts, "localaddr", host, &error_abort);
736             qemu_opt_set(opts, "localport", port, &error_abort);
737         }
738         return opts;
739     }
740     if (strstart(filename, "unix:", &p)) {
741         qemu_opt_set(opts, "backend", "socket", &error_abort);
742         qemu_opts_do_parse(opts, p, "path", &local_err);
743         if (local_err) {
744             error_report_err(local_err);
745             goto fail;
746         }
747         return opts;
748     }
749     if (strstart(filename, "/dev/parport", NULL) ||
750         strstart(filename, "/dev/ppi", NULL)) {
751         qemu_opt_set(opts, "backend", "parport", &error_abort);
752         qemu_opt_set(opts, "path", filename, &error_abort);
753         return opts;
754     }
755     if (strstart(filename, "/dev/", NULL)) {
756         qemu_opt_set(opts, "backend", "tty", &error_abort);
757         qemu_opt_set(opts, "path", filename, &error_abort);
758         return opts;
759     }
760 
761 fail:
762     qemu_opts_del(opts);
763     return NULL;
764 }
765 
766 void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
767 {
768     const char *logfile = qemu_opt_get(opts, "logfile");
769 
770     backend->has_logfile = logfile != NULL;
771     backend->logfile = g_strdup(logfile);
772 
773     backend->has_logappend = true;
774     backend->logappend = qemu_opt_get_bool(opts, "logappend", false);
775 }
776 
777 static const ChardevClass *char_get_class(const char *driver, Error **errp)
778 {
779     ObjectClass *oc;
780     const ChardevClass *cc;
781     char *typename = g_strdup_printf("chardev-%s", driver);
782 
783     oc = object_class_by_name(typename);
784     g_free(typename);
785 
786     if (!object_class_dynamic_cast(oc, TYPE_CHARDEV)) {
787         error_setg(errp, "'%s' is not a valid char driver name", driver);
788         return NULL;
789     }
790 
791     if (object_class_is_abstract(oc)) {
792         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
793                    "abstract device type");
794         return NULL;
795     }
796 
797     cc = CHARDEV_CLASS(oc);
798     if (cc->internal) {
799         error_setg(errp, "'%s' is not a valid char driver name", driver);
800         return NULL;
801     }
802 
803     return cc;
804 }
805 
806 static const struct ChardevAlias {
807     const char *typename;
808     const char *alias;
809 } chardev_alias_table[] = {
810 #ifdef HAVE_CHARDEV_PARPORT
811     { "parallel", "parport" },
812 #endif
813 #ifdef HAVE_CHARDEV_SERIAL
814     { "serial", "tty" },
815 #endif
816 };
817 
818 typedef struct ChadevClassFE {
819     void (*fn)(const char *name, void *opaque);
820     void *opaque;
821 } ChadevClassFE;
822 
823 static void
824 chardev_class_foreach(ObjectClass *klass, void *opaque)
825 {
826     ChadevClassFE *fe = opaque;
827 
828     assert(g_str_has_prefix(object_class_get_name(klass), "chardev-"));
829     if (CHARDEV_CLASS(klass)->internal) {
830         return;
831     }
832 
833     fe->fn(object_class_get_name(klass) + 8, fe->opaque);
834 }
835 
836 static void
837 chardev_name_foreach(void (*fn)(const char *name, void *opaque), void *opaque)
838 {
839     ChadevClassFE fe = { .fn = fn, .opaque = opaque };
840     int i;
841 
842     object_class_foreach(chardev_class_foreach, TYPE_CHARDEV, false, &fe);
843 
844     for (i = 0; i < ARRAY_SIZE(chardev_alias_table); i++) {
845         fn(chardev_alias_table[i].alias, opaque);
846     }
847 }
848 
849 static void
850 help_string_append(const char *name, void *opaque)
851 {
852     GString *str = opaque;
853 
854     g_string_append_printf(str, "\n%s", name);
855 }
856 
857 Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
858                                 Error **errp)
859 {
860     Error *local_err = NULL;
861     const ChardevClass *cc;
862     Chardev *chr;
863     int i;
864     ChardevBackend *backend = NULL;
865     const char *name = qemu_opt_get(opts, "backend");
866     const char *id = qemu_opts_id(opts);
867     char *bid = NULL;
868 
869     if (name == NULL) {
870         error_setg(errp, "chardev: \"%s\" missing backend",
871                    qemu_opts_id(opts));
872         return NULL;
873     }
874 
875     if (is_help_option(name)) {
876         GString *str = g_string_new("");
877 
878         chardev_name_foreach(help_string_append, str);
879 
880         error_report("Available chardev backend types: %s", str->str);
881         g_string_free(str, true);
882         exit(0);
883     }
884 
885     if (id == NULL) {
886         error_setg(errp, "chardev: no id specified");
887         return NULL;
888     }
889 
890     for (i = 0; i < ARRAY_SIZE(chardev_alias_table); i++) {
891         if (g_strcmp0(chardev_alias_table[i].alias, name) == 0) {
892             name = chardev_alias_table[i].typename;
893             break;
894         }
895     }
896 
897     cc = char_get_class(name, errp);
898     if (cc == NULL) {
899         return NULL;
900     }
901 
902     backend = g_new0(ChardevBackend, 1);
903     backend->type = CHARDEV_BACKEND_KIND_NULL;
904 
905     if (qemu_opt_get_bool(opts, "mux", 0)) {
906         bid = g_strdup_printf("%s-base", id);
907     }
908 
909     chr = NULL;
910     if (cc->parse) {
911         cc->parse(opts, backend, &local_err);
912         if (local_err) {
913             error_propagate(errp, local_err);
914             goto out;
915         }
916     } else {
917         ChardevCommon *ccom = g_new0(ChardevCommon, 1);
918         qemu_chr_parse_common(opts, ccom);
919         backend->u.null.data = ccom; /* Any ChardevCommon member would work */
920     }
921 
922     chr = qemu_chardev_new(bid ? bid : id,
923                            object_class_get_name(OBJECT_CLASS(cc)),
924                            backend, errp);
925 
926     if (chr == NULL) {
927         goto out;
928     }
929 
930     if (bid) {
931         Chardev *mux;
932         qapi_free_ChardevBackend(backend);
933         backend = g_new0(ChardevBackend, 1);
934         backend->type = CHARDEV_BACKEND_KIND_MUX;
935         backend->u.mux.data = g_new0(ChardevMux, 1);
936         backend->u.mux.data->chardev = g_strdup(bid);
937         mux = qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, errp);
938         if (mux == NULL) {
939             object_unparent(OBJECT(chr));
940             chr = NULL;
941             goto out;
942         }
943         chr = mux;
944     }
945 
946 out:
947     qapi_free_ChardevBackend(backend);
948     g_free(bid);
949     return chr;
950 }
951 
952 Chardev *qemu_chr_new_noreplay(const char *label, const char *filename)
953 {
954     const char *p;
955     Chardev *chr;
956     QemuOpts *opts;
957     Error *err = NULL;
958 
959     if (strstart(filename, "chardev:", &p)) {
960         return qemu_chr_find(p);
961     }
962 
963     opts = qemu_chr_parse_compat(label, filename);
964     if (!opts)
965         return NULL;
966 
967     chr = qemu_chr_new_from_opts(opts, &err);
968     if (err) {
969         error_report_err(err);
970     }
971     if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
972         monitor_init(chr, MONITOR_USE_READLINE);
973     }
974     qemu_opts_del(opts);
975     return chr;
976 }
977 
978 Chardev *qemu_chr_new(const char *label, const char *filename)
979 {
980     Chardev *chr;
981     chr = qemu_chr_new_noreplay(label, filename);
982     if (chr) {
983         if (replay_mode != REPLAY_MODE_NONE) {
984             qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
985         }
986         if (qemu_chr_replay(chr) && CHARDEV_GET_CLASS(chr)->chr_ioctl) {
987             error_report("Replay: ioctl is not supported "
988                          "for serial devices yet");
989         }
990         replay_register_char_driver(chr);
991     }
992     return chr;
993 }
994 
995 void qemu_chr_fe_set_echo(CharBackend *be, bool echo)
996 {
997     Chardev *chr = be->chr;
998 
999     if (chr && CHARDEV_GET_CLASS(chr)->chr_set_echo) {
1000         CHARDEV_GET_CLASS(chr)->chr_set_echo(chr, echo);
1001     }
1002 }
1003 
1004 void qemu_chr_fe_set_open(CharBackend *be, int fe_open)
1005 {
1006     Chardev *chr = be->chr;
1007 
1008     if (!chr) {
1009         return;
1010     }
1011 
1012     if (be->fe_open == fe_open) {
1013         return;
1014     }
1015     be->fe_open = fe_open;
1016     if (CHARDEV_GET_CLASS(chr)->chr_set_fe_open) {
1017         CHARDEV_GET_CLASS(chr)->chr_set_fe_open(chr, fe_open);
1018     }
1019 }
1020 
1021 guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
1022                             GIOFunc func, void *user_data)
1023 {
1024     Chardev *s = be->chr;
1025     GSource *src;
1026     guint tag;
1027 
1028     if (!s || CHARDEV_GET_CLASS(s)->chr_add_watch == NULL) {
1029         return 0;
1030     }
1031 
1032     src = CHARDEV_GET_CLASS(s)->chr_add_watch(s, cond);
1033     if (!src) {
1034         return 0;
1035     }
1036 
1037     g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
1038     tag = g_source_attach(src, NULL);
1039     g_source_unref(src);
1040 
1041     return tag;
1042 }
1043 
1044 void qemu_chr_fe_disconnect(CharBackend *be)
1045 {
1046     Chardev *chr = be->chr;
1047 
1048     if (chr && CHARDEV_GET_CLASS(chr)->chr_disconnect) {
1049         CHARDEV_GET_CLASS(chr)->chr_disconnect(chr);
1050     }
1051 }
1052 
1053 static int qmp_query_chardev_foreach(Object *obj, void *data)
1054 {
1055     Chardev *chr = CHARDEV(obj);
1056     ChardevInfoList **list = data;
1057     ChardevInfoList *info = g_malloc0(sizeof(*info));
1058 
1059     info->value = g_malloc0(sizeof(*info->value));
1060     info->value->label = g_strdup(chr->label);
1061     info->value->filename = g_strdup(chr->filename);
1062     info->value->frontend_open = chr->be && chr->be->fe_open;
1063 
1064     info->next = *list;
1065     *list = info;
1066 
1067     return 0;
1068 }
1069 
1070 ChardevInfoList *qmp_query_chardev(Error **errp)
1071 {
1072     ChardevInfoList *chr_list = NULL;
1073 
1074     object_child_foreach(get_chardevs_root(),
1075                          qmp_query_chardev_foreach, &chr_list);
1076 
1077     return chr_list;
1078 }
1079 
1080 static void
1081 qmp_prepend_backend(const char *name, void *opaque)
1082 {
1083     ChardevBackendInfoList **list = opaque;
1084     ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
1085 
1086     info->value = g_malloc0(sizeof(*info->value));
1087     info->value->name = g_strdup(name);
1088     info->next = *list;
1089     *list = info;
1090 }
1091 
1092 ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
1093 {
1094     ChardevBackendInfoList *backend_list = NULL;
1095 
1096     chardev_name_foreach(qmp_prepend_backend, &backend_list);
1097 
1098     return backend_list;
1099 }
1100 
1101 Chardev *qemu_chr_find(const char *name)
1102 {
1103     Object *obj = object_resolve_path_component(get_chardevs_root(), name);
1104 
1105     return obj ? CHARDEV(obj) : NULL;
1106 }
1107 
1108 QemuOptsList qemu_chardev_opts = {
1109     .name = "chardev",
1110     .implied_opt_name = "backend",
1111     .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
1112     .desc = {
1113         {
1114             .name = "backend",
1115             .type = QEMU_OPT_STRING,
1116         },{
1117             .name = "path",
1118             .type = QEMU_OPT_STRING,
1119         },{
1120             .name = "host",
1121             .type = QEMU_OPT_STRING,
1122         },{
1123             .name = "port",
1124             .type = QEMU_OPT_STRING,
1125         },{
1126             .name = "localaddr",
1127             .type = QEMU_OPT_STRING,
1128         },{
1129             .name = "localport",
1130             .type = QEMU_OPT_STRING,
1131         },{
1132             .name = "to",
1133             .type = QEMU_OPT_NUMBER,
1134         },{
1135             .name = "ipv4",
1136             .type = QEMU_OPT_BOOL,
1137         },{
1138             .name = "ipv6",
1139             .type = QEMU_OPT_BOOL,
1140         },{
1141             .name = "wait",
1142             .type = QEMU_OPT_BOOL,
1143         },{
1144             .name = "server",
1145             .type = QEMU_OPT_BOOL,
1146         },{
1147             .name = "delay",
1148             .type = QEMU_OPT_BOOL,
1149         },{
1150             .name = "reconnect",
1151             .type = QEMU_OPT_NUMBER,
1152         },{
1153             .name = "telnet",
1154             .type = QEMU_OPT_BOOL,
1155         },{
1156             .name = "tn3270",
1157             .type = QEMU_OPT_BOOL,
1158         },{
1159             .name = "tls-creds",
1160             .type = QEMU_OPT_STRING,
1161         },{
1162             .name = "width",
1163             .type = QEMU_OPT_NUMBER,
1164         },{
1165             .name = "height",
1166             .type = QEMU_OPT_NUMBER,
1167         },{
1168             .name = "cols",
1169             .type = QEMU_OPT_NUMBER,
1170         },{
1171             .name = "rows",
1172             .type = QEMU_OPT_NUMBER,
1173         },{
1174             .name = "mux",
1175             .type = QEMU_OPT_BOOL,
1176         },{
1177             .name = "signal",
1178             .type = QEMU_OPT_BOOL,
1179         },{
1180             .name = "name",
1181             .type = QEMU_OPT_STRING,
1182         },{
1183             .name = "debug",
1184             .type = QEMU_OPT_NUMBER,
1185         },{
1186             .name = "size",
1187             .type = QEMU_OPT_SIZE,
1188         },{
1189             .name = "chardev",
1190             .type = QEMU_OPT_STRING,
1191         },{
1192             .name = "append",
1193             .type = QEMU_OPT_BOOL,
1194         },{
1195             .name = "logfile",
1196             .type = QEMU_OPT_STRING,
1197         },{
1198             .name = "logappend",
1199             .type = QEMU_OPT_BOOL,
1200         },
1201         { /* end of list */ }
1202     },
1203 };
1204 
1205 bool qemu_chr_has_feature(Chardev *chr,
1206                           ChardevFeature feature)
1207 {
1208     return test_bit(feature, chr->features);
1209 }
1210 
1211 void qemu_chr_set_feature(Chardev *chr,
1212                            ChardevFeature feature)
1213 {
1214     return set_bit(feature, chr->features);
1215 }
1216 
1217 Chardev *qemu_chardev_new(const char *id, const char *typename,
1218                           ChardevBackend *backend,
1219                           Error **errp)
1220 {
1221     Object *obj;
1222     Chardev *chr = NULL;
1223     Error *local_err = NULL;
1224     bool be_opened = true;
1225 
1226     assert(g_str_has_prefix(typename, "chardev-"));
1227 
1228     obj = object_new(typename);
1229     chr = CHARDEV(obj);
1230     chr->label = g_strdup(id);
1231 
1232     qemu_char_open(chr, backend, &be_opened, &local_err);
1233     if (local_err) {
1234         goto end;
1235     }
1236 
1237     if (!chr->filename) {
1238         chr->filename = g_strdup(typename + 8);
1239     }
1240     if (be_opened) {
1241         qemu_chr_be_event(chr, CHR_EVENT_OPENED);
1242     }
1243 
1244     if (id) {
1245         object_property_add_child(get_chardevs_root(), id, obj, &local_err);
1246         if (local_err) {
1247             goto end;
1248         }
1249         object_unref(obj);
1250     }
1251 
1252 end:
1253     if (local_err) {
1254         error_propagate(errp, local_err);
1255         object_unref(obj);
1256         return NULL;
1257     }
1258 
1259     return chr;
1260 }
1261 
1262 ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
1263                                Error **errp)
1264 {
1265     const ChardevClass *cc;
1266     ChardevReturn *ret;
1267     Chardev *chr;
1268 
1269     cc = char_get_class(ChardevBackendKind_lookup[backend->type], errp);
1270     if (!cc) {
1271         return NULL;
1272     }
1273 
1274     chr = qemu_chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)),
1275                            backend, errp);
1276     if (!chr) {
1277         return NULL;
1278     }
1279 
1280     ret = g_new0(ChardevReturn, 1);
1281     if (CHARDEV_IS_PTY(chr)) {
1282         ret->pty = g_strdup(chr->filename + 4);
1283         ret->has_pty = true;
1284     }
1285 
1286     return ret;
1287 }
1288 
1289 void qmp_chardev_remove(const char *id, Error **errp)
1290 {
1291     Chardev *chr;
1292 
1293     chr = qemu_chr_find(id);
1294     if (chr == NULL) {
1295         error_setg(errp, "Chardev '%s' not found", id);
1296         return;
1297     }
1298     if (qemu_chr_is_busy(chr)) {
1299         error_setg(errp, "Chardev '%s' is busy", id);
1300         return;
1301     }
1302     if (qemu_chr_replay(chr)) {
1303         error_setg(errp,
1304             "Chardev '%s' cannot be unplugged in record/replay mode", id);
1305         return;
1306     }
1307     object_unparent(OBJECT(chr));
1308 }
1309 
1310 void qemu_chr_cleanup(void)
1311 {
1312     object_unparent(get_chardevs_root());
1313 }
1314 
1315 static void register_types(void)
1316 {
1317     type_register_static(&char_type_info);
1318 
1319     /* this must be done after machine init, since we register FEs with muxes
1320      * as part of realize functions like serial_isa_realizefn when -nographic
1321      * is specified
1322      */
1323     qemu_add_machine_init_done_notifier(&muxes_realize_notify);
1324 }
1325 
1326 type_init(register_types);
1327