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