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