]> git.proxmox.com Git - mirror_qemu.git/blame - chardev/char.c
char: move null chardev to its own file
[mirror_qemu.git] / chardev / char.c
CommitLineData
6f97dba0
AL
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 */
d38ea87a 24#include "qemu/osdep.h"
6f97dba0 25#include "qemu-common.h"
f348b6d1 26#include "qemu/cutils.h"
83c9089e 27#include "monitor/monitor.h"
9c17d615 28#include "sysemu/sysemu.h"
da31d594 29#include "sysemu/block-backend.h"
d49b6836 30#include "qemu/error-report.h"
1de7afc9 31#include "qemu/timer.h"
dccfcd0e 32#include "sysemu/char.h"
cf3ebac7 33#include "hw/usb.h"
c5a415a0 34#include "qmp-commands.h"
37f9e0a2 35#include "qapi/clone-visitor.h"
cfb429cb 36#include "qapi-visit.h"
e9cf2fe0 37#include "qemu/base64.h"
9894dc0c
DB
38#include "io/channel-socket.h"
39#include "io/channel-file.h"
a8fb5427 40#include "io/channel-tls.h"
33577b47 41#include "sysemu/replay.h"
517b3d40 42#include "qemu/help_option.h"
6f97dba0 43
6f97dba0
AL
44#include <zlib.h>
45
46#ifndef _WIN32
47#include <sys/times.h>
48#include <sys/wait.h>
49#include <termios.h>
6f97dba0 50#include <sys/ioctl.h>
24646c7e 51#include <sys/resource.h>
6f97dba0
AL
52#include <sys/socket.h>
53#include <netinet/in.h>
24646c7e 54#include <net/if.h>
24646c7e 55#include <arpa/inet.h>
6f97dba0
AL
56#include <netdb.h>
57#include <sys/select.h>
71e72a19 58#ifdef CONFIG_BSD
3294ce18
MT
59#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
60#include <dev/ppbus/ppi.h>
61#include <dev/ppbus/ppbconf.h>
c5e97233 62#elif defined(__DragonFly__)
c5e97233
BS
63#include <dev/misc/ppi/ppi.h>
64#include <bus/ppbus/ppbconf.h>
6f97dba0 65#endif
bbe813a2 66#else
6f97dba0 67#ifdef __linux__
6f97dba0
AL
68#include <linux/ppdev.h>
69#include <linux/parport.h>
70#endif
71#ifdef __sun__
6f97dba0
AL
72#include <sys/ethernet.h>
73#include <sys/sockio.h>
74#include <netinet/arp.h>
75#include <netinet/in.h>
76#include <netinet/in_systm.h>
77#include <netinet/ip.h>
78#include <netinet/ip_icmp.h> // must come after ip.h
79#include <netinet/udp.h>
80#include <netinet/tcp.h>
6f97dba0
AL
81#endif
82#endif
83#endif
84
1de7afc9 85#include "qemu/sockets.h"
cbcc6336 86#include "ui/qemu-spice.h"
6f97dba0 87
9bd7854e 88#define READ_BUF_LEN 4096
7b0bfdf5 89#define READ_RETRIES 10
c4095726 90#define TCP_MAX_FDS 16
9bd7854e 91
0ec7b3e7 92typedef struct MuxChardev MuxChardev;
6dfa8298 93
cfb429cb
CM
94/***********************************************************/
95/* Socket address helpers */
cfb429cb 96
0ff0fad2
DB
97static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
98 bool is_listen, bool is_telnet)
16cc4ffe 99{
130257dc 100 switch (addr->type) {
16cc4ffe 101 case SOCKET_ADDRESS_KIND_INET:
0ff0fad2 102 return g_strdup_printf("%s%s:%s:%s%s", prefix,
32bafa8f
EB
103 is_telnet ? "telnet" : "tcp",
104 addr->u.inet.data->host,
105 addr->u.inet.data->port,
106 is_listen ? ",server" : "");
16cc4ffe
CM
107 break;
108 case SOCKET_ADDRESS_KIND_UNIX:
0ff0fad2 109 return g_strdup_printf("%sunix:%s%s", prefix,
32bafa8f 110 addr->u.q_unix.data->path,
0ff0fad2 111 is_listen ? ",server" : "");
16cc4ffe
CM
112 break;
113 case SOCKET_ADDRESS_KIND_FD:
32bafa8f 114 return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.data->str,
0ff0fad2 115 is_listen ? ",server" : "");
16cc4ffe
CM
116 break;
117 default:
118 abort();
119 }
120}
121
0ff0fad2
DB
122static char *sockaddr_to_str(struct sockaddr_storage *ss, socklen_t ss_len,
123 struct sockaddr_storage *ps, socklen_t ps_len,
124 bool is_listen, bool is_telnet)
16cc4ffe 125{
01ca519f
CM
126 char shost[NI_MAXHOST], sserv[NI_MAXSERV];
127 char phost[NI_MAXHOST], pserv[NI_MAXSERV];
16cc4ffe
CM
128 const char *left = "", *right = "";
129
130 switch (ss->ss_family) {
131#ifndef _WIN32
132 case AF_UNIX:
0ff0fad2
DB
133 return g_strdup_printf("unix:%s%s",
134 ((struct sockaddr_un *)(ss))->sun_path,
135 is_listen ? ",server" : "");
16cc4ffe
CM
136#endif
137 case AF_INET6:
138 left = "[";
139 right = "]";
140 /* fall through */
141 case AF_INET:
01ca519f
CM
142 getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
143 sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
144 getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
145 pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
0ff0fad2
DB
146 return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
147 is_telnet ? "telnet" : "tcp",
148 left, shost, right, sserv,
149 is_listen ? ",server" : "",
150 left, phost, right, pserv);
16cc4ffe
CM
151
152 default:
0ff0fad2 153 return g_strdup_printf("unknown");
16cc4ffe
CM
154 }
155}
156
6f97dba0
AL
157/***********************************************************/
158/* character device */
159
0ec7b3e7 160static QTAILQ_HEAD(ChardevHead, Chardev) chardevs =
72cf2d4f 161 QTAILQ_HEAD_INITIALIZER(chardevs);
2970a6c9 162
0ec7b3e7 163void qemu_chr_be_event(Chardev *s, int event)
6f97dba0 164{
a4afa548
MAL
165 CharBackend *be = s->be;
166
73cdf3f2
AG
167 /* Keep track if the char device is open */
168 switch (event) {
169 case CHR_EVENT_OPENED:
16665b94 170 s->be_open = 1;
73cdf3f2
AG
171 break;
172 case CHR_EVENT_CLOSED:
16665b94 173 s->be_open = 0;
73cdf3f2
AG
174 break;
175 }
176
a4afa548 177 if (!be || !be->chr_event) {
6f97dba0 178 return;
a4afa548
MAL
179 }
180
181 be->chr_event(be->opaque, event);
6f97dba0
AL
182}
183
0ec7b3e7 184void qemu_chr_be_generic_open(Chardev *s)
6f97dba0 185{
bd5c51ee 186 qemu_chr_be_event(s, CHR_EVENT_OPENED);
6f97dba0
AL
187}
188
d0d7708b
DB
189
190/* Not reporting errors from writing to logfile, as logs are
191 * defined to be "best effort" only */
0ec7b3e7 192static void qemu_chr_fe_write_log(Chardev *s,
d0d7708b
DB
193 const uint8_t *buf, size_t len)
194{
195 size_t done = 0;
196 ssize_t ret;
197
198 if (s->logfd < 0) {
199 return;
200 }
201
202 while (done < len) {
53628efb
DB
203 retry:
204 ret = write(s->logfd, buf + done, len - done);
205 if (ret == -1 && errno == EAGAIN) {
206 g_usleep(100);
207 goto retry;
208 }
d0d7708b
DB
209
210 if (ret <= 0) {
211 return;
212 }
213 done += ret;
214 }
215}
216
0ec7b3e7
MAL
217static int qemu_chr_fe_write_buffer(Chardev *s,
218 const uint8_t *buf, int len, int *offset)
33577b47 219{
777357d7 220 ChardevClass *cc = CHARDEV_GET_CLASS(s);
33577b47
PD
221 int res = 0;
222 *offset = 0;
223
224 qemu_mutex_lock(&s->chr_write_lock);
225 while (*offset < len) {
53628efb 226 retry:
777357d7 227 res = cc->chr_write(s, buf + *offset, len - *offset);
53628efb
DB
228 if (res < 0 && errno == EAGAIN) {
229 g_usleep(100);
230 goto retry;
231 }
33577b47
PD
232
233 if (res <= 0) {
234 break;
235 }
236
237 *offset += res;
238 }
239 if (*offset > 0) {
240 qemu_chr_fe_write_log(s, buf, *offset);
241 }
242 qemu_mutex_unlock(&s->chr_write_lock);
243
244 return res;
245}
246
0ec7b3e7 247static bool qemu_chr_replay(Chardev *chr)
5ebd6703
MAL
248{
249 return qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
250}
251
5345fdb4 252int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
6f97dba0 253{
0ec7b3e7 254 Chardev *s = be->chr;
777357d7 255 ChardevClass *cc;
9005b2a7
PB
256 int ret;
257
fa394ed6
MAL
258 if (!s) {
259 return 0;
260 }
261
5ebd6703 262 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
33577b47
PD
263 int offset;
264 replay_char_write_event_load(&ret, &offset);
265 assert(offset <= len);
266 qemu_chr_fe_write_buffer(s, buf, offset, &offset);
267 return ret;
268 }
269
777357d7 270 cc = CHARDEV_GET_CLASS(s);
9005b2a7 271 qemu_mutex_lock(&s->chr_write_lock);
777357d7 272 ret = cc->chr_write(s, buf, len);
d0d7708b
DB
273
274 if (ret > 0) {
275 qemu_chr_fe_write_log(s, buf, ret);
276 }
277
9005b2a7 278 qemu_mutex_unlock(&s->chr_write_lock);
33577b47 279
5ebd6703 280 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
33577b47
PD
281 replay_char_write_event_save(ret, ret < 0 ? 0 : ret);
282 }
283
9005b2a7 284 return ret;
6f97dba0
AL
285}
286
0ec7b3e7 287static int qemu_chr_write_all(Chardev *s, const uint8_t *buf, int len)
cd18720a 288{
33577b47
PD
289 int offset;
290 int res;
cd18720a 291
5ebd6703 292 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
33577b47
PD
293 replay_char_write_event_load(&res, &offset);
294 assert(offset <= len);
295 qemu_chr_fe_write_buffer(s, buf, offset, &offset);
296 return res;
297 }
cd18720a 298
33577b47 299 res = qemu_chr_fe_write_buffer(s, buf, len, &offset);
cd18720a 300
5ebd6703 301 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
33577b47 302 replay_char_write_event_save(res, offset);
cd18720a
AL
303 }
304
9005b2a7
PB
305 if (res < 0) {
306 return res;
307 }
cd18720a
AL
308 return offset;
309}
310
5345fdb4 311int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
7b0bfdf5 312{
0ec7b3e7 313 Chardev *s = be->chr;
5345fdb4 314
fa394ed6
MAL
315 if (!s) {
316 return 0;
317 }
318
5345fdb4
MAL
319 return qemu_chr_write_all(s, buf, len);
320}
321
322int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
323{
0ec7b3e7 324 Chardev *s = be->chr;
7b0bfdf5
NN
325 int offset = 0, counter = 10;
326 int res;
327
777357d7 328 if (!s || !CHARDEV_GET_CLASS(s)->chr_sync_read) {
7b0bfdf5
NN
329 return 0;
330 }
fa394ed6 331
5ebd6703 332 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
33577b47
PD
333 return replay_char_read_all_load(buf);
334 }
7b0bfdf5
NN
335
336 while (offset < len) {
53628efb 337 retry:
777357d7
MAL
338 res = CHARDEV_GET_CLASS(s)->chr_sync_read(s, buf + offset,
339 len - offset);
53628efb
DB
340 if (res == -1 && errno == EAGAIN) {
341 g_usleep(100);
342 goto retry;
343 }
7b0bfdf5
NN
344
345 if (res == 0) {
346 break;
347 }
348
349 if (res < 0) {
5ebd6703 350 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
33577b47
PD
351 replay_char_read_all_save_error(res);
352 }
7b0bfdf5
NN
353 return res;
354 }
355
356 offset += res;
357
358 if (!counter--) {
359 break;
360 }
361 }
362
5ebd6703 363 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
33577b47
PD
364 replay_char_read_all_save_buf(buf, offset);
365 }
7b0bfdf5
NN
366 return offset;
367}
368
5345fdb4 369int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg)
6f97dba0 370{
0ec7b3e7 371 Chardev *s = be->chr;
33577b47 372 int res;
fa394ed6 373
777357d7 374 if (!s || !CHARDEV_GET_CLASS(s)->chr_ioctl || qemu_chr_replay(s)) {
33577b47
PD
375 res = -ENOTSUP;
376 } else {
777357d7 377 res = CHARDEV_GET_CLASS(s)->chr_ioctl(s, cmd, arg);
33577b47
PD
378 }
379
380 return res;
6f97dba0
AL
381}
382
0ec7b3e7 383int qemu_chr_be_can_write(Chardev *s)
6f97dba0 384{
a4afa548
MAL
385 CharBackend *be = s->be;
386
387 if (!be || !be->chr_can_read) {
6f97dba0 388 return 0;
a4afa548
MAL
389 }
390
391 return be->chr_can_read(be->opaque);
6f97dba0
AL
392}
393
0ec7b3e7 394void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len)
6f97dba0 395{
a4afa548
MAL
396 CharBackend *be = s->be;
397
398 if (be && be->chr_read) {
399 be->chr_read(be->opaque, buf, len);
ac310734 400 }
6f97dba0
AL
401}
402
0ec7b3e7 403void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len)
33577b47 404{
5ebd6703 405 if (qemu_chr_replay(s)) {
33577b47
PD
406 if (replay_mode == REPLAY_MODE_PLAY) {
407 return;
408 }
409 replay_chr_be_write(s, buf, len);
410 } else {
411 qemu_chr_be_write_impl(s, buf, len);
412 }
413}
414
5345fdb4 415int qemu_chr_fe_get_msgfd(CharBackend *be)
7d174059 416{
0ec7b3e7 417 Chardev *s = be->chr;
c76bf6bb 418 int fd;
5345fdb4 419 int res = (qemu_chr_fe_get_msgfds(be, &fd, 1) == 1) ? fd : -1;
5ebd6703 420 if (s && qemu_chr_replay(s)) {
776a32a0
MAL
421 error_report("Replay: get msgfd is not supported "
422 "for serial devices yet");
33577b47
PD
423 exit(1);
424 }
425 return res;
c76bf6bb
NN
426}
427
5345fdb4 428int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len)
c76bf6bb 429{
0ec7b3e7 430 Chardev *s = be->chr;
5345fdb4 431
fa394ed6
MAL
432 if (!s) {
433 return -1;
434 }
435
777357d7
MAL
436 return CHARDEV_GET_CLASS(s)->get_msgfds ?
437 CHARDEV_GET_CLASS(s)->get_msgfds(s, fds, len) : -1;
7d174059
MM
438}
439
5345fdb4 440int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num)
d39aac7a 441{
0ec7b3e7 442 Chardev *s = be->chr;
5345fdb4 443
fa394ed6
MAL
444 if (!s) {
445 return -1;
446 }
447
777357d7
MAL
448 return CHARDEV_GET_CLASS(s)->set_msgfds ?
449 CHARDEV_GET_CLASS(s)->set_msgfds(s, fds, num) : -1;
d39aac7a
NN
450}
451
0ec7b3e7 452int qemu_chr_add_client(Chardev *s, int fd)
13661089 453{
777357d7
MAL
454 return CHARDEV_GET_CLASS(s)->chr_add_client ?
455 CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1;
13661089
DB
456}
457
5345fdb4 458void qemu_chr_fe_accept_input(CharBackend *be)
6f97dba0 459{
0ec7b3e7 460 Chardev *s = be->chr;
5345fdb4 461
fa394ed6
MAL
462 if (!s) {
463 return;
464 }
465
777357d7
MAL
466 if (CHARDEV_GET_CLASS(s)->chr_accept_input) {
467 CHARDEV_GET_CLASS(s)->chr_accept_input(s);
b68e956a 468 }
98c8ee1d 469 qemu_notify_event();
6f97dba0
AL
470}
471
5345fdb4 472void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
6f97dba0 473{
9bd7854e 474 char buf[READ_BUF_LEN];
6f97dba0
AL
475 va_list ap;
476 va_start(ap, fmt);
477 vsnprintf(buf, sizeof(buf), fmt, ap);
90f998f5
DB
478 /* XXX this blocks entire thread. Rewrite to use
479 * qemu_chr_fe_write and background I/O callbacks */
5345fdb4 480 qemu_chr_fe_write_all(be, (uint8_t *)buf, strlen(buf));
6f97dba0
AL
481 va_end(ap);
482}
483
0ec7b3e7
MAL
484static void remove_fd_in_watch(Chardev *chr);
485static void mux_chr_set_handlers(Chardev *chr, GMainContext *context);
486static void mux_set_focus(Chardev *chr, int focus);
6dfa8298 487
777357d7
MAL
488static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
489 bool *be_opened, Error **errp)
6f97dba0 490{
777357d7
MAL
491 ChardevClass *cc = CHARDEV_GET_CLASS(chr);
492 /* Any ChardevCommon member would work */
493 ChardevCommon *common = backend ? backend->u.null.data : NULL;
494
495 if (common && common->has_logfile) {
496 int flags = O_WRONLY | O_CREAT;
497 if (common->has_logappend &&
498 common->logappend) {
499 flags |= O_APPEND;
500 } else {
501 flags |= O_TRUNC;
502 }
503 chr->logfd = qemu_open(common->logfile, flags, 0666);
504 if (chr->logfd < 0) {
505 error_setg_errno(errp, errno,
506 "Unable to open logfile %s",
507 common->logfile);
508 return;
509 }
510 }
511
512 if (cc->open) {
513 cc->open(chr, backend, be_opened, errp);
514 }
6f97dba0
AL
515}
516
777357d7 517static void char_init(Object *obj)
6f97dba0 518{
777357d7 519 Chardev *chr = CHARDEV(obj);
6f97dba0 520
777357d7
MAL
521 chr->logfd = -1;
522 qemu_mutex_init(&chr->chr_write_lock);
523}
524
eb314a94
MAL
525static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
526{
527 return len;
528}
529
530static void char_class_init(ObjectClass *oc, void *data)
531{
532 ChardevClass *cc = CHARDEV_CLASS(oc);
533
534 cc->chr_write = null_chr_write;
535}
536
777357d7
MAL
537static void char_finalize(Object *obj)
538{
539 Chardev *chr = CHARDEV(obj);
540
541 if (chr->be) {
542 chr->be->chr = NULL;
543 }
544 g_free(chr->filename);
545 g_free(chr->label);
546 if (chr->logfd != -1) {
547 close(chr->logfd);
d0d7708b 548 }
777357d7
MAL
549 qemu_mutex_destroy(&chr->chr_write_lock);
550}
551
552static const TypeInfo char_type_info = {
553 .name = TYPE_CHARDEV,
554 .parent = TYPE_OBJECT,
555 .instance_size = sizeof(Chardev),
556 .instance_init = char_init,
557 .instance_finalize = char_finalize,
558 .abstract = true,
559 .class_size = sizeof(ChardevClass),
eb314a94 560 .class_init = char_class_init,
777357d7
MAL
561};
562
6f97dba0 563/* MUX driver for serial I/O splitting */
6f97dba0
AL
564#define MAX_MUX 4
565#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
566#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
0ec7b3e7
MAL
567struct MuxChardev {
568 Chardev parent;
a4afa548 569 CharBackend *backends[MAX_MUX];
ecb672d1 570 CharBackend chr;
799f1f23 571 int focus;
6f97dba0
AL
572 int mux_cnt;
573 int term_got_escape;
574 int max_size;
a80bf99f
AL
575 /* Intermediate input buffer allows to catch escape sequences even if the
576 currently active device is not accepting any input - but only until it
577 is full as well. */
578 unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
579 int prod[MAX_MUX];
580 int cons[MAX_MUX];
2d22959d 581 int timestamps;
9005b2a7 582
0ec7b3e7 583 /* Protected by the Chardev chr_write_lock. */
4ab312f7 584 int linestart;
2d22959d 585 int64_t timestamps_start;
6dfa8298 586};
6f97dba0 587
777357d7
MAL
588#define MUX_CHARDEV(obj) OBJECT_CHECK(MuxChardev, (obj), TYPE_CHARDEV_MUX)
589
9005b2a7 590/* Called with chr_write_lock held. */
0ec7b3e7 591static int mux_chr_write(Chardev *chr, const uint8_t *buf, int len)
6f97dba0 592{
777357d7 593 MuxChardev *d = MUX_CHARDEV(chr);
6f97dba0 594 int ret;
2d22959d 595 if (!d->timestamps) {
5345fdb4 596 ret = qemu_chr_fe_write(&d->chr, buf, len);
6f97dba0
AL
597 } else {
598 int i;
599
600 ret = 0;
4ab312f7
JK
601 for (i = 0; i < len; i++) {
602 if (d->linestart) {
6f97dba0
AL
603 char buf1[64];
604 int64_t ti;
605 int secs;
606
bc72ad67 607 ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
2d22959d
JK
608 if (d->timestamps_start == -1)
609 d->timestamps_start = ti;
610 ti -= d->timestamps_start;
a4bb1db8 611 secs = ti / 1000;
6f97dba0
AL
612 snprintf(buf1, sizeof(buf1),
613 "[%02d:%02d:%02d.%03d] ",
614 secs / 3600,
615 (secs / 60) % 60,
616 secs % 60,
a4bb1db8 617 (int)(ti % 1000));
90f998f5
DB
618 /* XXX this blocks entire thread. Rewrite to use
619 * qemu_chr_fe_write and background I/O callbacks */
5345fdb4
MAL
620 qemu_chr_fe_write_all(&d->chr,
621 (uint8_t *)buf1, strlen(buf1));
4ab312f7
JK
622 d->linestart = 0;
623 }
5345fdb4 624 ret += qemu_chr_fe_write(&d->chr, buf + i, 1);
4ab312f7
JK
625 if (buf[i] == '\n') {
626 d->linestart = 1;
6f97dba0
AL
627 }
628 }
629 }
630 return ret;
631}
632
633static const char * const mux_help[] = {
634 "% h print this help\n\r",
635 "% x exit emulator\n\r",
636 "% s save disk data back to file (if -snapshot)\n\r",
86d10328 637 "% t toggle console timestamps\n\r",
6f97dba0
AL
638 "% b send break (magic sysrq)\n\r",
639 "% c switch between console and monitor\n\r",
640 "% % sends %\n\r",
641 NULL
642};
643
644int term_escape_char = 0x01; /* ctrl-a is used for escape */
0ec7b3e7 645static void mux_print_help(Chardev *chr)
6f97dba0
AL
646{
647 int i, j;
648 char ebuf[15] = "Escape-Char";
649 char cbuf[50] = "\n\r";
650
651 if (term_escape_char > 0 && term_escape_char < 26) {
652 snprintf(cbuf, sizeof(cbuf), "\n\r");
653 snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
654 } else {
655 snprintf(cbuf, sizeof(cbuf),
656 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
657 term_escape_char);
658 }
90f998f5
DB
659 /* XXX this blocks entire thread. Rewrite to use
660 * qemu_chr_fe_write and background I/O callbacks */
5345fdb4 661 qemu_chr_write_all(chr, (uint8_t *)cbuf, strlen(cbuf));
6f97dba0
AL
662 for (i = 0; mux_help[i] != NULL; i++) {
663 for (j=0; mux_help[i][j] != '\0'; j++) {
664 if (mux_help[i][j] == '%')
5345fdb4 665 qemu_chr_write_all(chr, (uint8_t *)ebuf, strlen(ebuf));
6f97dba0 666 else
5345fdb4 667 qemu_chr_write_all(chr, (uint8_t *)&mux_help[i][j], 1);
6f97dba0
AL
668 }
669 }
670}
671
0ec7b3e7 672static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
2724b180 673{
a4afa548
MAL
674 CharBackend *be = d->backends[mux_nr];
675
676 if (be && be->chr_event) {
677 be->chr_event(be->opaque, event);
678 }
2724b180
AL
679}
680
0ec7b3e7 681static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)
6f97dba0
AL
682{
683 if (d->term_got_escape) {
684 d->term_got_escape = 0;
685 if (ch == term_escape_char)
686 goto send_char;
687 switch(ch) {
688 case '?':
689 case 'h':
690 mux_print_help(chr);
691 break;
692 case 'x':
693 {
694 const char *term = "QEMU: Terminated\n\r";
5345fdb4 695 qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));
6f97dba0
AL
696 exit(0);
697 break;
698 }
699 case 's':
da31d594 700 blk_commit_all();
6f97dba0
AL
701 break;
702 case 'b':
a425d23f 703 qemu_chr_be_event(chr, CHR_EVENT_BREAK);
6f97dba0
AL
704 break;
705 case 'c':
6dfa8298 706 assert(d->mux_cnt > 0); /* handler registered with first fe */
6f97dba0 707 /* Switch to the next registered device */
fb5e19d2 708 mux_set_focus(chr, (d->focus + 1) % d->mux_cnt);
6f97dba0 709 break;
2d22959d
JK
710 case 't':
711 d->timestamps = !d->timestamps;
712 d->timestamps_start = -1;
4ab312f7 713 d->linestart = 0;
2d22959d 714 break;
6f97dba0
AL
715 }
716 } else if (ch == term_escape_char) {
717 d->term_got_escape = 1;
718 } else {
719 send_char:
720 return 1;
721 }
722 return 0;
723}
724
0ec7b3e7 725static void mux_chr_accept_input(Chardev *chr)
6f97dba0 726{
777357d7 727 MuxChardev *d = MUX_CHARDEV(chr);
799f1f23 728 int m = d->focus;
a4afa548 729 CharBackend *be = d->backends[m];
6f97dba0 730
a4afa548
MAL
731 while (be && d->prod[m] != d->cons[m] &&
732 be->chr_can_read && be->chr_can_read(be->opaque)) {
733 be->chr_read(be->opaque,
734 &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
6f97dba0
AL
735 }
736}
737
738static int mux_chr_can_read(void *opaque)
739{
777357d7 740 MuxChardev *d = MUX_CHARDEV(opaque);
799f1f23 741 int m = d->focus;
a4afa548 742 CharBackend *be = d->backends[m];
6f97dba0 743
a4afa548 744 if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) {
6f97dba0 745 return 1;
a4afa548
MAL
746 }
747
748 if (be && be->chr_can_read) {
749 return be->chr_can_read(be->opaque);
750 }
751
6f97dba0
AL
752 return 0;
753}
754
755static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
756{
777357d7
MAL
757 Chardev *chr = CHARDEV(opaque);
758 MuxChardev *d = MUX_CHARDEV(opaque);
799f1f23 759 int m = d->focus;
a4afa548 760 CharBackend *be = d->backends[m];
6f97dba0
AL
761 int i;
762
a4afa548 763 mux_chr_accept_input(opaque);
6f97dba0 764
a4afa548 765 for (i = 0; i < size; i++)
6f97dba0 766 if (mux_proc_byte(chr, d, buf[i])) {
a80bf99f 767 if (d->prod[m] == d->cons[m] &&
a4afa548
MAL
768 be && be->chr_can_read &&
769 be->chr_can_read(be->opaque))
770 be->chr_read(be->opaque, &buf[i], 1);
6f97dba0 771 else
a80bf99f 772 d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
6f97dba0
AL
773 }
774}
775
fffbd9cf
PB
776static bool muxes_realized;
777
6f97dba0
AL
778static void mux_chr_event(void *opaque, int event)
779{
777357d7 780 MuxChardev *d = MUX_CHARDEV(opaque);
6f97dba0
AL
781 int i;
782
fffbd9cf
PB
783 if (!muxes_realized) {
784 return;
785 }
786
6f97dba0
AL
787 /* Send the event to all registered listeners */
788 for (i = 0; i < d->mux_cnt; i++)
2724b180 789 mux_chr_send_event(d, i, event);
6f97dba0
AL
790}
791
7b7ab18d
MR
792/**
793 * Called after processing of default and command-line-specified
794 * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
795 * to a mux chardev. This is done here to ensure that
796 * output/prompts/banners are only displayed for the FE that has
797 * focus when initial command-line processing/machine init is
798 * completed.
799 *
800 * After this point, any new FE attached to any new or existing
801 * mux will receive CHR_EVENT_OPENED notifications for the BE
802 * immediately.
803 */
804static void muxes_realize_done(Notifier *notifier, void *unused)
805{
0ec7b3e7 806 Chardev *chr;
7b7ab18d
MR
807
808 QTAILQ_FOREACH(chr, &chardevs, next) {
777357d7
MAL
809 if (CHARDEV_IS_MUX(chr)) {
810 MuxChardev *d = MUX_CHARDEV(chr);
7b7ab18d
MR
811 int i;
812
813 /* send OPENED to all already-attached FEs */
814 for (i = 0; i < d->mux_cnt; i++) {
815 mux_chr_send_event(d, i, CHR_EVENT_OPENED);
816 }
817 /* mark mux as OPENED so any new FEs will immediately receive
818 * OPENED event
819 */
820 qemu_chr_be_generic_open(chr);
821 }
822 }
823 muxes_realized = true;
824}
825
826static Notifier muxes_realize_notify = {
827 .notify = muxes_realize_done,
828};
829
0ec7b3e7 830static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
3f0838ab 831{
777357d7 832 MuxChardev *d = MUX_CHARDEV(s);
0ec7b3e7 833 Chardev *chr = qemu_chr_fe_get_driver(&d->chr);
777357d7 834 ChardevClass *cc = CHARDEV_GET_CLASS(chr);
5345fdb4 835
777357d7 836 if (!cc->chr_add_watch) {
b68e956a
MAL
837 return NULL;
838 }
839
777357d7 840 return cc->chr_add_watch(chr, cond);
3f0838ab
KB
841}
842
980d0414 843static void char_mux_finalize(Object *obj)
1371a369 844{
980d0414 845 MuxChardev *d = MUX_CHARDEV(obj);
a4afa548 846 int i;
1371a369 847
a4afa548
MAL
848 for (i = 0; i < d->mux_cnt; i++) {
849 CharBackend *be = d->backends[i];
850 if (be) {
851 be->chr = NULL;
852 }
853 }
c39860e6 854 qemu_chr_fe_deinit(&d->chr);
1371a369
MAL
855}
856
0ec7b3e7 857static void mux_chr_set_handlers(Chardev *chr, GMainContext *context)
6dfa8298 858{
777357d7 859 MuxChardev *d = MUX_CHARDEV(chr);
6dfa8298
MAL
860
861 /* Fix up the real driver with mux routines */
ecb672d1
MAL
862 qemu_chr_fe_set_handlers(&d->chr,
863 mux_chr_can_read,
864 mux_chr_read,
865 mux_chr_event,
866 chr,
39ab61c6 867 context, true);
6dfa8298
MAL
868}
869
0ec7b3e7 870static void mux_set_focus(Chardev *chr, int focus)
6dfa8298 871{
777357d7 872 MuxChardev *d = MUX_CHARDEV(chr);
fb5e19d2 873
6dfa8298
MAL
874 assert(focus >= 0);
875 assert(focus < d->mux_cnt);
876
877 if (d->focus != -1) {
878 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
879 }
880
881 d->focus = focus;
fb5e19d2 882 chr->be = d->backends[focus];
6dfa8298
MAL
883 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
884}
885
777357d7
MAL
886static void qemu_chr_open_mux(Chardev *chr,
887 ChardevBackend *backend,
888 bool *be_opened,
889 Error **errp)
6f97dba0 890{
32bafa8f 891 ChardevMux *mux = backend->u.mux.data;
777357d7
MAL
892 Chardev *drv;
893 MuxChardev *d = MUX_CHARDEV(chr);
6f97dba0 894
3c0e5a4a
PB
895 drv = qemu_chr_find(mux->chardev);
896 if (drv == NULL) {
897 error_setg(errp, "mux: base chardev %s not found", mux->chardev);
777357d7 898 return;
3c0e5a4a
PB
899 }
900
799f1f23 901 d->focus = -1;
7b7ab18d
MR
902 /* only default to opened state if we've realized the initial
903 * set of muxes
904 */
82878dac 905 *be_opened = muxes_realized;
777357d7 906 qemu_chr_fe_init(&d->chr, drv, errp);
6f97dba0
AL
907}
908
0ec7b3e7 909Chardev *qemu_chr_fe_get_driver(CharBackend *be)
94a40fc5
MAL
910{
911 return be->chr;
912}
913
0ec7b3e7 914bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
94a40fc5
MAL
915{
916 int tag = 0;
917
777357d7
MAL
918 if (CHARDEV_IS_MUX(s)) {
919 MuxChardev *d = MUX_CHARDEV(s);
3aef23d7
MAL
920
921 if (d->mux_cnt >= MAX_MUX) {
922 goto unavailable;
94a40fc5 923 }
3aef23d7
MAL
924
925 d->backends[d->mux_cnt] = b;
926 tag = d->mux_cnt++;
927 } else if (s->be) {
928 goto unavailable;
a4afa548
MAL
929 } else {
930 s->be = b;
94a40fc5
MAL
931 }
932
830896af 933 b->fe_open = false;
94a40fc5
MAL
934 b->tag = tag;
935 b->chr = s;
94a40fc5 936 return true;
3aef23d7
MAL
937
938unavailable:
939 error_setg(errp, QERR_DEVICE_IN_USE, s->label);
940 return false;
94a40fc5
MAL
941}
942
0ec7b3e7 943static bool qemu_chr_is_busy(Chardev *s)
a4afa548 944{
777357d7
MAL
945 if (CHARDEV_IS_MUX(s)) {
946 MuxChardev *d = MUX_CHARDEV(s);
a4afa548
MAL
947 return d->mux_cnt >= 0;
948 } else {
949 return s->be != NULL;
950 }
951}
952
c39860e6
MAL
953void qemu_chr_fe_deinit(CharBackend *b)
954{
955 assert(b);
956
957 if (b->chr) {
39ab61c6 958 qemu_chr_fe_set_handlers(b, NULL, NULL, NULL, NULL, NULL, true);
fb5e19d2
MAL
959 if (b->chr->be == b) {
960 b->chr->be = NULL;
961 }
777357d7
MAL
962 if (CHARDEV_IS_MUX(b->chr)) {
963 MuxChardev *d = MUX_CHARDEV(b->chr);
a4afa548
MAL
964 d->backends[b->tag] = NULL;
965 }
c39860e6
MAL
966 b->chr = NULL;
967 }
968}
969
94a40fc5
MAL
970void qemu_chr_fe_set_handlers(CharBackend *b,
971 IOCanReadHandler *fd_can_read,
972 IOReadHandler *fd_read,
973 IOEventHandler *fd_event,
974 void *opaque,
39ab61c6
MAL
975 GMainContext *context,
976 bool set_open)
94a40fc5 977{
0ec7b3e7 978 Chardev *s;
777357d7 979 ChardevClass *cc;
386f07d1
MAL
980 int fe_open;
981
982 s = b->chr;
983 if (!s) {
94a40fc5
MAL
984 return;
985 }
986
777357d7 987 cc = CHARDEV_GET_CLASS(s);
386f07d1
MAL
988 if (!opaque && !fd_can_read && !fd_read && !fd_event) {
989 fe_open = 0;
990 remove_fd_in_watch(s);
991 } else {
992 fe_open = 1;
993 }
a4afa548
MAL
994 b->chr_can_read = fd_can_read;
995 b->chr_read = fd_read;
996 b->chr_event = fd_event;
997 b->opaque = opaque;
777357d7
MAL
998 if (cc->chr_update_read_handler) {
999 cc->chr_update_read_handler(s, context);
386f07d1
MAL
1000 }
1001
39ab61c6 1002 if (set_open) {
386f07d1
MAL
1003 qemu_chr_fe_set_open(b, fe_open);
1004 }
94a40fc5 1005
386f07d1
MAL
1006 if (fe_open) {
1007 qemu_chr_fe_take_focus(b);
1008 /* We're connecting to an already opened device, so let's make sure we
1009 also get the open event */
1010 if (s->be_open) {
1011 qemu_chr_be_generic_open(s);
1012 }
1013 }
1014
777357d7 1015 if (CHARDEV_IS_MUX(s)) {
386f07d1 1016 mux_chr_set_handlers(s, context);
94a40fc5
MAL
1017 }
1018}
1019
1020void qemu_chr_fe_take_focus(CharBackend *b)
1021{
fa394ed6
MAL
1022 if (!b->chr) {
1023 return;
1024 }
1025
777357d7 1026 if (CHARDEV_IS_MUX(b->chr)) {
fb5e19d2 1027 mux_set_focus(b->chr, b->tag);
94a40fc5
MAL
1028 }
1029}
6f97dba0 1030
96c63847
AL
1031typedef struct IOWatchPoll
1032{
d185c094
PB
1033 GSource parent;
1034
9894dc0c 1035 QIOChannel *ioc;
96c63847 1036 GSource *src;
96c63847
AL
1037
1038 IOCanReadHandler *fd_can_read;
1e885b25 1039 GSourceFunc fd_read;
96c63847 1040 void *opaque;
e92aa36a 1041 GMainContext *context;
96c63847
AL
1042} IOWatchPoll;
1043
96c63847
AL
1044static IOWatchPoll *io_watch_poll_from_source(GSource *source)
1045{
d185c094 1046 return container_of(source, IOWatchPoll, parent);
96c63847
AL
1047}
1048
e92aa36a
ZC
1049static gboolean io_watch_poll_prepare(GSource *source,
1050 gint *timeout_)
96c63847
AL
1051{
1052 IOWatchPoll *iwp = io_watch_poll_from_source(source);
d185c094 1053 bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
1e885b25 1054 bool was_active = iwp->src != NULL;
d185c094 1055 if (was_active == now_active) {
96c63847
AL
1056 return FALSE;
1057 }
1058
d185c094 1059 if (now_active) {
9894dc0c
DB
1060 iwp->src = qio_channel_create_watch(
1061 iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
1e885b25 1062 g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
e92aa36a 1063 g_source_attach(iwp->src, iwp->context);
d185c094 1064 } else {
1e885b25
PB
1065 g_source_destroy(iwp->src);
1066 g_source_unref(iwp->src);
1067 iwp->src = NULL;
d185c094
PB
1068 }
1069 return FALSE;
96c63847
AL
1070}
1071
1072static gboolean io_watch_poll_check(GSource *source)
1073{
d185c094 1074 return FALSE;
96c63847
AL
1075}
1076
1077static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
1078 gpointer user_data)
1079{
d185c094 1080 abort();
96c63847
AL
1081}
1082
1083static void io_watch_poll_finalize(GSource *source)
1084{
2b316774
PB
1085 /* Due to a glib bug, removing the last reference to a source
1086 * inside a finalize callback causes recursive locking (and a
1087 * deadlock). This is not a problem inside other callbacks,
1088 * including dispatch callbacks, so we call io_remove_watch_poll
1089 * to remove this source. At this point, iwp->src must
1090 * be NULL, or we would leak it.
1091 *
1092 * This would be solved much more elegantly by child sources,
1093 * but we support older glib versions that do not have them.
1094 */
96c63847 1095 IOWatchPoll *iwp = io_watch_poll_from_source(source);
2b316774 1096 assert(iwp->src == NULL);
96c63847
AL
1097}
1098
1099static GSourceFuncs io_watch_poll_funcs = {
1100 .prepare = io_watch_poll_prepare,
1101 .check = io_watch_poll_check,
1102 .dispatch = io_watch_poll_dispatch,
1103 .finalize = io_watch_poll_finalize,
1104};
1105
1106/* Can only be used for read */
0ec7b3e7 1107static guint io_add_watch_poll(Chardev *chr,
e93a68e1 1108 QIOChannel *ioc,
96c63847 1109 IOCanReadHandler *fd_can_read,
9894dc0c 1110 QIOChannelFunc fd_read,
e92aa36a
ZC
1111 gpointer user_data,
1112 GMainContext *context)
96c63847
AL
1113{
1114 IOWatchPoll *iwp;
0ca5aa4f 1115 int tag;
e93a68e1 1116 char *name;
96c63847 1117
e92aa36a
ZC
1118 iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs,
1119 sizeof(IOWatchPoll));
96c63847
AL
1120 iwp->fd_can_read = fd_can_read;
1121 iwp->opaque = user_data;
9894dc0c 1122 iwp->ioc = ioc;
1e885b25
PB
1123 iwp->fd_read = (GSourceFunc) fd_read;
1124 iwp->src = NULL;
e92aa36a 1125 iwp->context = context;
96c63847 1126
e93a68e1
DB
1127 name = g_strdup_printf("chardev-iowatch-%s", chr->label);
1128 g_source_set_name((GSource *)iwp, name);
1129 g_free(name);
1130
e92aa36a 1131 tag = g_source_attach(&iwp->parent, context);
0ca5aa4f
PB
1132 g_source_unref(&iwp->parent);
1133 return tag;
96c63847
AL
1134}
1135
2b316774
PB
1136static void io_remove_watch_poll(guint tag)
1137{
1138 GSource *source;
1139 IOWatchPoll *iwp;
1140
1141 g_return_if_fail (tag > 0);
1142
1143 source = g_main_context_find_source_by_id(NULL, tag);
1144 g_return_if_fail (source != NULL);
1145
1146 iwp = io_watch_poll_from_source(source);
1147 if (iwp->src) {
1148 g_source_destroy(iwp->src);
1149 g_source_unref(iwp->src);
1150 iwp->src = NULL;
1151 }
1152 g_source_destroy(&iwp->parent);
1153}
1154
0ec7b3e7 1155static void remove_fd_in_watch(Chardev *chr)
26da70c7
AS
1156{
1157 if (chr->fd_in_tag) {
1158 io_remove_watch_poll(chr->fd_in_tag);
1159 chr->fd_in_tag = 0;
1160 }
1161}
1162
96c63847 1163
9894dc0c
DB
1164static int io_channel_send_full(QIOChannel *ioc,
1165 const void *buf, size_t len,
1166 int *fds, size_t nfds)
76a9644b 1167{
9894dc0c 1168 size_t offset = 0;
76a9644b 1169
9894dc0c
DB
1170 while (offset < len) {
1171 ssize_t ret = 0;
1172 struct iovec iov = { .iov_base = (char *)buf + offset,
1173 .iov_len = len - offset };
1174
1175 ret = qio_channel_writev_full(
1176 ioc, &iov, 1,
1177 fds, nfds, NULL);
1178 if (ret == QIO_CHANNEL_ERR_BLOCK) {
9894dc0c
DB
1179 if (offset) {
1180 return offset;
1181 }
76a9644b 1182
e046fb44
DB
1183 errno = EAGAIN;
1184 return -1;
1185 } else if (ret < 0) {
9894dc0c
DB
1186 errno = EINVAL;
1187 return -1;
1188 }
76a9644b 1189
9894dc0c
DB
1190 offset += ret;
1191 }
76a9644b 1192
9894dc0c 1193 return offset;
76a9644b
AL
1194}
1195
9894dc0c 1196
0ff0fad2 1197#ifndef _WIN32
9894dc0c 1198static int io_channel_send(QIOChannel *ioc, const void *buf, size_t len)
96c63847 1199{
9894dc0c 1200 return io_channel_send_full(ioc, buf, len, NULL, 0);
96c63847 1201}
96c63847 1202
0ec7b3e7
MAL
1203typedef struct FDChardev {
1204 Chardev parent;
1205 Chardev *chr;
9894dc0c 1206 QIOChannel *ioc_in, *ioc_out;
6f97dba0 1207 int max_size;
0ec7b3e7 1208} FDChardev;
6f97dba0 1209
777357d7
MAL
1210#define TYPE_CHARDEV_FD "chardev-fd"
1211#define FD_CHARDEV(obj) OBJECT_CHECK(FDChardev, (obj), TYPE_CHARDEV_FD)
1212
9005b2a7 1213/* Called with chr_write_lock held. */
0ec7b3e7 1214static int fd_chr_write(Chardev *chr, const uint8_t *buf, int len)
6f97dba0 1215{
777357d7 1216 FDChardev *s = FD_CHARDEV(chr);
41ac54b2 1217
9894dc0c 1218 return io_channel_send(s->ioc_out, buf, len);
6f97dba0
AL
1219}
1220
9894dc0c 1221static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
6f97dba0 1222{
777357d7
MAL
1223 Chardev *chr = CHARDEV(opaque);
1224 FDChardev *s = FD_CHARDEV(opaque);
a29753f8 1225 int len;
9bd7854e 1226 uint8_t buf[READ_BUF_LEN];
9894dc0c 1227 ssize_t ret;
6f97dba0
AL
1228
1229 len = sizeof(buf);
a29753f8 1230 if (len > s->max_size) {
6f97dba0 1231 len = s->max_size;
a29753f8
AL
1232 }
1233 if (len == 0) {
cdbf6e16 1234 return TRUE;
a29753f8
AL
1235 }
1236
9894dc0c
DB
1237 ret = qio_channel_read(
1238 chan, (gchar *)buf, len, NULL);
1239 if (ret == 0) {
26da70c7 1240 remove_fd_in_watch(chr);
a425d23f 1241 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
a29753f8 1242 return FALSE;
6f97dba0 1243 }
9894dc0c
DB
1244 if (ret > 0) {
1245 qemu_chr_be_write(chr, buf, ret);
6f97dba0 1246 }
a29753f8
AL
1247
1248 return TRUE;
1249}
1250
1251static int fd_chr_read_poll(void *opaque)
1252{
777357d7
MAL
1253 Chardev *chr = CHARDEV(opaque);
1254 FDChardev *s = FD_CHARDEV(opaque);
a29753f8
AL
1255
1256 s->max_size = qemu_chr_be_can_write(chr);
1257 return s->max_size;
6f97dba0
AL
1258}
1259
0ec7b3e7 1260static GSource *fd_chr_add_watch(Chardev *chr, GIOCondition cond)
23673ca7 1261{
777357d7 1262 FDChardev *s = FD_CHARDEV(chr);
9894dc0c 1263 return qio_channel_create_watch(s->ioc_out, cond);
23673ca7
AL
1264}
1265
0ec7b3e7 1266static void fd_chr_update_read_handler(Chardev *chr,
a4afa548 1267 GMainContext *context)
6f97dba0 1268{
777357d7 1269 FDChardev *s = FD_CHARDEV(chr);
6f97dba0 1270
26da70c7 1271 remove_fd_in_watch(chr);
9894dc0c 1272 if (s->ioc_in) {
e93a68e1 1273 chr->fd_in_tag = io_add_watch_poll(chr, s->ioc_in,
9894dc0c 1274 fd_chr_read_poll,
e92aa36a
ZC
1275 fd_chr_read, chr,
1276 context);
6f97dba0
AL
1277 }
1278}
1279
7f2fe073 1280static void char_fd_finalize(Object *obj)
6f97dba0 1281{
7f2fe073
MAL
1282 Chardev *chr = CHARDEV(obj);
1283 FDChardev *s = FD_CHARDEV(obj);
6f97dba0 1284
26da70c7 1285 remove_fd_in_watch(chr);
9894dc0c
DB
1286 if (s->ioc_in) {
1287 object_unref(OBJECT(s->ioc_in));
a29753f8 1288 }
9894dc0c
DB
1289 if (s->ioc_out) {
1290 object_unref(OBJECT(s->ioc_out));
6f97dba0
AL
1291 }
1292
a425d23f 1293 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
6f97dba0
AL
1294}
1295
1296/* open a character device to a unix fd */
777357d7
MAL
1297static void qemu_chr_open_fd(Chardev *chr,
1298 int fd_in, int fd_out)
6f97dba0 1299{
777357d7 1300 FDChardev *s = FD_CHARDEV(chr);
e93a68e1 1301 char *name;
6f97dba0 1302
9894dc0c 1303 s->ioc_in = QIO_CHANNEL(qio_channel_file_new_fd(fd_in));
e93a68e1
DB
1304 name = g_strdup_printf("chardev-file-in-%s", chr->label);
1305 qio_channel_set_name(QIO_CHANNEL(s->ioc_in), name);
1306 g_free(name);
9894dc0c 1307 s->ioc_out = QIO_CHANNEL(qio_channel_file_new_fd(fd_out));
e93a68e1
DB
1308 name = g_strdup_printf("chardev-file-out-%s", chr->label);
1309 qio_channel_set_name(QIO_CHANNEL(s->ioc_out), name);
1310 g_free(name);
4ff12bdb 1311 qemu_set_nonblock(fd_out);
a29753f8 1312 s->chr = chr;
777357d7 1313}
6f97dba0 1314
777357d7
MAL
1315static void char_fd_class_init(ObjectClass *oc, void *data)
1316{
1317 ChardevClass *cc = CHARDEV_CLASS(oc);
1318
1319 cc->chr_add_watch = fd_chr_add_watch;
1320 cc->chr_write = fd_chr_write;
1321 cc->chr_update_read_handler = fd_chr_update_read_handler;
6f97dba0
AL
1322}
1323
777357d7
MAL
1324static const TypeInfo char_fd_type_info = {
1325 .name = TYPE_CHARDEV_FD,
1326 .parent = TYPE_CHARDEV,
1327 .instance_size = sizeof(FDChardev),
7f2fe073 1328 .instance_finalize = char_fd_finalize,
777357d7
MAL
1329 .class_init = char_fd_class_init,
1330 .abstract = true,
1331};
1332
1333static void qemu_chr_open_pipe(Chardev *chr,
1334 ChardevBackend *backend,
1335 bool *be_opened,
1336 Error **errp)
6f97dba0 1337{
32bafa8f 1338 ChardevHostdev *opts = backend->u.pipe.data;
6f97dba0 1339 int fd_in, fd_out;
0ff0fad2
DB
1340 char *filename_in;
1341 char *filename_out;
548cbb36 1342 const char *filename = opts->device;
0ff0fad2
DB
1343
1344 filename_in = g_strdup_printf("%s.in", filename);
1345 filename_out = g_strdup_printf("%s.out", filename);
40ff6d7e
KW
1346 TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
1347 TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
0ff0fad2
DB
1348 g_free(filename_in);
1349 g_free(filename_out);
6f97dba0
AL
1350 if (fd_in < 0 || fd_out < 0) {
1351 if (fd_in >= 0)
1352 close(fd_in);
1353 if (fd_out >= 0)
1354 close(fd_out);
b181e047 1355 TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
a89dd6c3 1356 if (fd_in < 0) {
20cbe7a2 1357 error_setg_file_open(errp, errno, filename);
777357d7 1358 return;
a89dd6c3 1359 }
6f97dba0 1360 }
777357d7 1361 qemu_chr_open_fd(chr, fd_in, fd_out);
6f97dba0
AL
1362}
1363
6f97dba0
AL
1364/* init terminal so that we can grab keys */
1365static struct termios oldtty;
1366static int old_fd0_flags;
c88930a6 1367static bool stdio_in_use;
bb002513 1368static bool stdio_allow_signal;
e76d4420
GH
1369static bool stdio_echo_state;
1370
0ec7b3e7 1371static void qemu_chr_set_echo_stdio(Chardev *chr, bool echo);
6f97dba0
AL
1372
1373static void term_exit(void)
1374{
1375 tcsetattr (0, TCSANOW, &oldtty);
1376 fcntl(0, F_SETFL, old_fd0_flags);
1377}
1378
e76d4420
GH
1379static void term_stdio_handler(int sig)
1380{
1381 /* restore echo after resume from suspend. */
1382 qemu_chr_set_echo_stdio(NULL, stdio_echo_state);
1383}
1384
0ec7b3e7 1385static void qemu_chr_set_echo_stdio(Chardev *chr, bool echo)
6f97dba0
AL
1386{
1387 struct termios tty;
1388
e76d4420 1389 stdio_echo_state = echo;
0369364b 1390 tty = oldtty;
bb002513
PB
1391 if (!echo) {
1392 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
6f97dba0 1393 |INLCR|IGNCR|ICRNL|IXON);
bb002513
PB
1394 tty.c_oflag |= OPOST;
1395 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
1396 tty.c_cflag &= ~(CSIZE|PARENB);
1397 tty.c_cflag |= CS8;
1398 tty.c_cc[VMIN] = 1;
1399 tty.c_cc[VTIME] = 0;
1400 }
bb002513 1401 if (!stdio_allow_signal)
6f97dba0 1402 tty.c_lflag &= ~ISIG;
6f97dba0
AL
1403
1404 tcsetattr (0, TCSANOW, &tty);
6f97dba0
AL
1405}
1406
4d833ada 1407static void char_stdio_finalize(Object *obj)
6f97dba0
AL
1408{
1409 term_exit();
6f97dba0
AL
1410}
1411
777357d7
MAL
1412static void qemu_chr_open_stdio(Chardev *chr,
1413 ChardevBackend *backend,
1414 bool *be_opened,
1415 Error **errp)
6f97dba0 1416{
32bafa8f 1417 ChardevStdio *opts = backend->u.stdio.data;
e76d4420 1418 struct sigaction act;
6f97dba0 1419
ab51b1d5 1420 if (is_daemonized()) {
8c84b25d 1421 error_setg(errp, "cannot use stdio with -daemonize");
777357d7 1422 return;
ab51b1d5 1423 }
c88930a6
LL
1424
1425 if (stdio_in_use) {
8c84b25d 1426 error_setg(errp, "cannot use stdio by multiple character devices");
777357d7 1427 return;
c88930a6
LL
1428 }
1429
1430 stdio_in_use = true;
ed7a1540 1431 old_fd0_flags = fcntl(0, F_GETFL);
c88930a6 1432 tcgetattr(0, &oldtty);
4ff12bdb 1433 qemu_set_nonblock(0);
ed7a1540 1434 atexit(term_exit);
0369364b 1435
e76d4420
GH
1436 memset(&act, 0, sizeof(act));
1437 act.sa_handler = term_stdio_handler;
1438 sigaction(SIGCONT, &act, NULL);
1439
777357d7
MAL
1440 qemu_chr_open_fd(chr, 0, 1);
1441
7c358031
GH
1442 if (opts->has_signal) {
1443 stdio_allow_signal = opts->signal;
1444 }
5345fdb4 1445 qemu_chr_set_echo_stdio(chr, false);
6f97dba0
AL
1446}
1447
6f97dba0 1448#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
a167ba50
AJ
1449 || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
1450 || defined(__GLIBC__)
6f97dba0 1451
d809ab95
PB
1452#define HAVE_CHARDEV_SERIAL 1
1453#define HAVE_CHARDEV_PTY 1
e551498e 1454
6f97dba0 1455typedef struct {
0ec7b3e7 1456 Chardev parent;
9894dc0c 1457 QIOChannel *ioc;
6f97dba0 1458 int read_bytes;
9005b2a7 1459
0ec7b3e7 1460 /* Protected by the Chardev chr_write_lock. */
9005b2a7 1461 int connected;
8aa33caf 1462 guint timer_tag;
7b3621f4 1463 guint open_tag;
0ec7b3e7 1464} PtyChardev;
6f97dba0 1465
777357d7
MAL
1466#define PTY_CHARDEV(obj) OBJECT_CHECK(PtyChardev, (obj), TYPE_CHARDEV_PTY)
1467
0ec7b3e7
MAL
1468static void pty_chr_update_read_handler_locked(Chardev *chr);
1469static void pty_chr_state(Chardev *chr, int connected);
6f97dba0 1470
8aa33caf
AL
1471static gboolean pty_chr_timer(gpointer opaque)
1472{
777357d7
MAL
1473 struct Chardev *chr = CHARDEV(opaque);
1474 PtyChardev *s = PTY_CHARDEV(opaque);
8aa33caf 1475
9005b2a7 1476 qemu_mutex_lock(&chr->chr_write_lock);
79f20075 1477 s->timer_tag = 0;
7b3621f4 1478 s->open_tag = 0;
b0d768c3
GH
1479 if (!s->connected) {
1480 /* Next poll ... */
9005b2a7 1481 pty_chr_update_read_handler_locked(chr);
b0d768c3 1482 }
9005b2a7 1483 qemu_mutex_unlock(&chr->chr_write_lock);
8aa33caf
AL
1484 return FALSE;
1485}
1486
9005b2a7 1487/* Called with chr_write_lock held. */
0ec7b3e7 1488static void pty_chr_rearm_timer(Chardev *chr, int ms)
8aa33caf 1489{
777357d7 1490 PtyChardev *s = PTY_CHARDEV(chr);
e93a68e1 1491 char *name;
8aa33caf
AL
1492
1493 if (s->timer_tag) {
1494 g_source_remove(s->timer_tag);
1495 s->timer_tag = 0;
1496 }
1497
1498 if (ms == 1000) {
e93a68e1 1499 name = g_strdup_printf("pty-timer-secs-%s", chr->label);
8aa33caf
AL
1500 s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
1501 } else {
e93a68e1 1502 name = g_strdup_printf("pty-timer-ms-%s", chr->label);
8aa33caf
AL
1503 s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
1504 }
e93a68e1
DB
1505 g_source_set_name_by_id(s->timer_tag, name);
1506 g_free(name);
8aa33caf
AL
1507}
1508
9005b2a7 1509/* Called with chr_write_lock held. */
0ec7b3e7 1510static void pty_chr_update_read_handler_locked(Chardev *chr)
1bb7fe72 1511{
777357d7 1512 PtyChardev *s = PTY_CHARDEV(chr);
1bb7fe72 1513 GPollFD pfd;
c1f24489 1514 int rc;
9894dc0c 1515 QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc);
1bb7fe72 1516
9894dc0c 1517 pfd.fd = fioc->fd;
1bb7fe72
PB
1518 pfd.events = G_IO_OUT;
1519 pfd.revents = 0;
c1f24489
PB
1520 do {
1521 rc = g_poll(&pfd, 1, 0);
1522 } while (rc == -1 && errno == EINTR);
1523 assert(rc >= 0);
1524
1bb7fe72
PB
1525 if (pfd.revents & G_IO_HUP) {
1526 pty_chr_state(chr, 0);
1527 } else {
1528 pty_chr_state(chr, 1);
1529 }
1530}
1531
0ec7b3e7 1532static void pty_chr_update_read_handler(Chardev *chr,
a4afa548 1533 GMainContext *context)
9005b2a7
PB
1534{
1535 qemu_mutex_lock(&chr->chr_write_lock);
1536 pty_chr_update_read_handler_locked(chr);
1537 qemu_mutex_unlock(&chr->chr_write_lock);
1538}
1539
1540/* Called with chr_write_lock held. */
777357d7 1541static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len)
6f97dba0 1542{
777357d7 1543 PtyChardev *s = PTY_CHARDEV(chr);
6f97dba0
AL
1544
1545 if (!s->connected) {
1546 /* guest sends data, check for (re-)connect */
9005b2a7 1547 pty_chr_update_read_handler_locked(chr);
cf7330c7
ST
1548 if (!s->connected) {
1549 return 0;
1550 }
6f97dba0 1551 }
9894dc0c 1552 return io_channel_send(s->ioc, buf, len);
6f97dba0
AL
1553}
1554
0ec7b3e7 1555static GSource *pty_chr_add_watch(Chardev *chr, GIOCondition cond)
e6a87ed8 1556{
777357d7 1557 PtyChardev *s = PTY_CHARDEV(chr);
62c339c5
PB
1558 if (!s->connected) {
1559 return NULL;
1560 }
9894dc0c 1561 return qio_channel_create_watch(s->ioc, cond);
e6a87ed8
AL
1562}
1563
6f97dba0
AL
1564static int pty_chr_read_poll(void *opaque)
1565{
777357d7
MAL
1566 Chardev *chr = CHARDEV(opaque);
1567 PtyChardev *s = PTY_CHARDEV(opaque);
6f97dba0 1568
909cda12 1569 s->read_bytes = qemu_chr_be_can_write(chr);
6f97dba0
AL
1570 return s->read_bytes;
1571}
1572
9894dc0c 1573static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
6f97dba0 1574{
777357d7
MAL
1575 Chardev *chr = CHARDEV(opaque);
1576 PtyChardev *s = PTY_CHARDEV(opaque);
9894dc0c 1577 gsize len;
9bd7854e 1578 uint8_t buf[READ_BUF_LEN];
9894dc0c 1579 ssize_t ret;
6f97dba0
AL
1580
1581 len = sizeof(buf);
1582 if (len > s->read_bytes)
1583 len = s->read_bytes;
cdbf6e16
PB
1584 if (len == 0) {
1585 return TRUE;
1586 }
9894dc0c
DB
1587 ret = qio_channel_read(s->ioc, (char *)buf, len, NULL);
1588 if (ret <= 0) {
6f97dba0 1589 pty_chr_state(chr, 0);
093d3a20
AL
1590 return FALSE;
1591 } else {
6f97dba0 1592 pty_chr_state(chr, 1);
9894dc0c 1593 qemu_chr_be_write(chr, buf, ret);
6f97dba0 1594 }
093d3a20 1595 return TRUE;
6f97dba0
AL
1596}
1597
7b3621f4
PB
1598static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
1599{
777357d7
MAL
1600 Chardev *chr = CHARDEV(opaque);
1601 PtyChardev *s = PTY_CHARDEV(opaque);
7b3621f4
PB
1602
1603 s->open_tag = 0;
1604 qemu_chr_be_generic_open(chr);
1605 return FALSE;
1606}
1607
9005b2a7 1608/* Called with chr_write_lock held. */
0ec7b3e7 1609static void pty_chr_state(Chardev *chr, int connected)
6f97dba0 1610{
777357d7 1611 PtyChardev *s = PTY_CHARDEV(chr);
6f97dba0
AL
1612
1613 if (!connected) {
7b3621f4
PB
1614 if (s->open_tag) {
1615 g_source_remove(s->open_tag);
1616 s->open_tag = 0;
1617 }
26da70c7 1618 remove_fd_in_watch(chr);
6f97dba0 1619 s->connected = 0;
6f97dba0
AL
1620 /* (re-)connect poll interval for idle guests: once per second.
1621 * We check more frequently in case the guests sends data to
1622 * the virtual device linked to our pty. */
8aa33caf 1623 pty_chr_rearm_timer(chr, 1000);
6f97dba0 1624 } else {
85a67692
PB
1625 if (s->timer_tag) {
1626 g_source_remove(s->timer_tag);
1627 s->timer_tag = 0;
1628 }
1629 if (!s->connected) {
7b3621f4 1630 g_assert(s->open_tag == 0);
85a67692 1631 s->connected = 1;
7b3621f4 1632 s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
ac1b84dd
GH
1633 }
1634 if (!chr->fd_in_tag) {
e93a68e1 1635 chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
9894dc0c 1636 pty_chr_read_poll,
e92aa36a
ZC
1637 pty_chr_read,
1638 chr, NULL);
85a67692 1639 }
6f97dba0
AL
1640 }
1641}
1642
fa943b5e 1643static void char_pty_finalize(Object *obj)
6f97dba0 1644{
fa943b5e
MAL
1645 Chardev *chr = CHARDEV(obj);
1646 PtyChardev *s = PTY_CHARDEV(obj);
6f97dba0 1647
7b3621f4
PB
1648 qemu_mutex_lock(&chr->chr_write_lock);
1649 pty_chr_state(chr, 0);
9894dc0c 1650 object_unref(OBJECT(s->ioc));
8aa33caf
AL
1651 if (s->timer_tag) {
1652 g_source_remove(s->timer_tag);
910b6368 1653 s->timer_tag = 0;
8aa33caf 1654 }
7b3621f4 1655 qemu_mutex_unlock(&chr->chr_write_lock);
a425d23f 1656 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
6f97dba0
AL
1657}
1658
777357d7
MAL
1659static void char_pty_open(Chardev *chr,
1660 ChardevBackend *backend,
1661 bool *be_opened,
1662 Error **errp)
6f97dba0 1663{
0ec7b3e7 1664 PtyChardev *s;
e68c5958 1665 int master_fd, slave_fd;
6f97dba0 1666 char pty_name[PATH_MAX];
e93a68e1 1667 char *name;
6f97dba0 1668
4efeabbb
MT
1669 master_fd = qemu_openpty_raw(&slave_fd, pty_name);
1670 if (master_fd < 0) {
c2e75a43 1671 error_setg_errno(errp, errno, "Failed to create PTY");
777357d7 1672 return;
6f97dba0
AL
1673 }
1674
837a183f 1675 close(slave_fd);
fac6688a 1676 qemu_set_nonblock(master_fd);
6f97dba0 1677
4efeabbb 1678 chr->filename = g_strdup_printf("pty:%s", pty_name);
776a32a0 1679 error_report("char device redirected to %s (label %s)",
777357d7 1680 pty_name, chr->label);
6f97dba0 1681
777357d7 1682 s = PTY_CHARDEV(chr);
9894dc0c 1683 s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd));
e93a68e1
DB
1684 name = g_strdup_printf("chardev-pty-%s", chr->label);
1685 qio_channel_set_name(QIO_CHANNEL(s->ioc), name);
1686 g_free(name);
8aa33caf 1687 s->timer_tag = 0;
41ac54b2 1688 *be_opened = false;
6f97dba0
AL
1689}
1690
777357d7
MAL
1691static void char_pty_class_init(ObjectClass *oc, void *data)
1692{
1693 ChardevClass *cc = CHARDEV_CLASS(oc);
1694
1695 cc->open = char_pty_open;
1696 cc->chr_write = char_pty_chr_write;
1697 cc->chr_update_read_handler = pty_chr_update_read_handler;
1698 cc->chr_add_watch = pty_chr_add_watch;
777357d7
MAL
1699}
1700
1701static const TypeInfo char_pty_type_info = {
1702 .name = TYPE_CHARDEV_PTY,
1703 .parent = TYPE_CHARDEV,
1704 .instance_size = sizeof(PtyChardev),
fa943b5e 1705 .instance_finalize = char_pty_finalize,
777357d7 1706 .class_init = char_pty_class_init,
b68e956a
MAL
1707};
1708
6f97dba0
AL
1709static void tty_serial_init(int fd, int speed,
1710 int parity, int data_bits, int stop_bits)
1711{
1712 struct termios tty;
1713 speed_t spd;
1714
1715#if 0
1716 printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
1717 speed, parity, data_bits, stop_bits);
1718#endif
1719 tcgetattr (fd, &tty);
1720
45eea13b
SW
1721#define check_speed(val) if (speed <= val) { spd = B##val; break; }
1722 speed = speed * 10 / 11;
1723 do {
1724 check_speed(50);
1725 check_speed(75);
1726 check_speed(110);
1727 check_speed(134);
1728 check_speed(150);
1729 check_speed(200);
1730 check_speed(300);
1731 check_speed(600);
1732 check_speed(1200);
1733 check_speed(1800);
1734 check_speed(2400);
1735 check_speed(4800);
1736 check_speed(9600);
1737 check_speed(19200);
1738 check_speed(38400);
1739 /* Non-Posix values follow. They may be unsupported on some systems. */
1740 check_speed(57600);
1741 check_speed(115200);
1742#ifdef B230400
1743 check_speed(230400);
1744#endif
1745#ifdef B460800
1746 check_speed(460800);
1747#endif
1748#ifdef B500000
1749 check_speed(500000);
1750#endif
1751#ifdef B576000
1752 check_speed(576000);
1753#endif
1754#ifdef B921600
1755 check_speed(921600);
1756#endif
1757#ifdef B1000000
1758 check_speed(1000000);
1759#endif
1760#ifdef B1152000
1761 check_speed(1152000);
1762#endif
1763#ifdef B1500000
1764 check_speed(1500000);
1765#endif
1766#ifdef B2000000
1767 check_speed(2000000);
1768#endif
1769#ifdef B2500000
1770 check_speed(2500000);
1771#endif
1772#ifdef B3000000
1773 check_speed(3000000);
1774#endif
1775#ifdef B3500000
1776 check_speed(3500000);
1777#endif
1778#ifdef B4000000
1779 check_speed(4000000);
1780#endif
6f97dba0 1781 spd = B115200;
45eea13b 1782 } while (0);
6f97dba0
AL
1783
1784 cfsetispeed(&tty, spd);
1785 cfsetospeed(&tty, spd);
1786
1787 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1788 |INLCR|IGNCR|ICRNL|IXON);
1789 tty.c_oflag |= OPOST;
1790 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
1791 tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
1792 switch(data_bits) {
1793 default:
1794 case 8:
1795 tty.c_cflag |= CS8;
1796 break;
1797 case 7:
1798 tty.c_cflag |= CS7;
1799 break;
1800 case 6:
1801 tty.c_cflag |= CS6;
1802 break;
1803 case 5:
1804 tty.c_cflag |= CS5;
1805 break;
1806 }
1807 switch(parity) {
1808 default:
1809 case 'N':
1810 break;
1811 case 'E':
1812 tty.c_cflag |= PARENB;
1813 break;
1814 case 'O':
1815 tty.c_cflag |= PARENB | PARODD;
1816 break;
1817 }
1818 if (stop_bits == 2)
1819 tty.c_cflag |= CSTOPB;
1820
1821 tcsetattr (fd, TCSANOW, &tty);
1822}
1823
0ec7b3e7 1824static int tty_serial_ioctl(Chardev *chr, int cmd, void *arg)
6f97dba0 1825{
777357d7 1826 FDChardev *s = FD_CHARDEV(chr);
9894dc0c 1827 QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc_in);
6f97dba0
AL
1828
1829 switch(cmd) {
1830 case CHR_IOCTL_SERIAL_SET_PARAMS:
1831 {
1832 QEMUSerialSetParams *ssp = arg;
9894dc0c 1833 tty_serial_init(fioc->fd,
a29753f8 1834 ssp->speed, ssp->parity,
6f97dba0
AL
1835 ssp->data_bits, ssp->stop_bits);
1836 }
1837 break;
1838 case CHR_IOCTL_SERIAL_SET_BREAK:
1839 {
1840 int enable = *(int *)arg;
a29753f8 1841 if (enable) {
9894dc0c 1842 tcsendbreak(fioc->fd, 1);
a29753f8 1843 }
6f97dba0
AL
1844 }
1845 break;
1846 case CHR_IOCTL_SERIAL_GET_TIOCM:
1847 {
1848 int sarg = 0;
1849 int *targ = (int *)arg;
9894dc0c 1850 ioctl(fioc->fd, TIOCMGET, &sarg);
6f97dba0 1851 *targ = 0;
b4abdfa4 1852 if (sarg & TIOCM_CTS)
6f97dba0 1853 *targ |= CHR_TIOCM_CTS;
b4abdfa4 1854 if (sarg & TIOCM_CAR)
6f97dba0 1855 *targ |= CHR_TIOCM_CAR;
b4abdfa4 1856 if (sarg & TIOCM_DSR)
6f97dba0 1857 *targ |= CHR_TIOCM_DSR;
b4abdfa4 1858 if (sarg & TIOCM_RI)
6f97dba0 1859 *targ |= CHR_TIOCM_RI;
b4abdfa4 1860 if (sarg & TIOCM_DTR)
6f97dba0 1861 *targ |= CHR_TIOCM_DTR;
b4abdfa4 1862 if (sarg & TIOCM_RTS)
6f97dba0
AL
1863 *targ |= CHR_TIOCM_RTS;
1864 }
1865 break;
1866 case CHR_IOCTL_SERIAL_SET_TIOCM:
1867 {
1868 int sarg = *(int *)arg;
1869 int targ = 0;
9894dc0c 1870 ioctl(fioc->fd, TIOCMGET, &targ);
b4abdfa4
AJ
1871 targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
1872 | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
1873 if (sarg & CHR_TIOCM_CTS)
1874 targ |= TIOCM_CTS;
1875 if (sarg & CHR_TIOCM_CAR)
1876 targ |= TIOCM_CAR;
1877 if (sarg & CHR_TIOCM_DSR)
1878 targ |= TIOCM_DSR;
1879 if (sarg & CHR_TIOCM_RI)
1880 targ |= TIOCM_RI;
1881 if (sarg & CHR_TIOCM_DTR)
6f97dba0 1882 targ |= TIOCM_DTR;
b4abdfa4 1883 if (sarg & CHR_TIOCM_RTS)
6f97dba0 1884 targ |= TIOCM_RTS;
9894dc0c 1885 ioctl(fioc->fd, TIOCMSET, &targ);
6f97dba0
AL
1886 }
1887 break;
1888 default:
1889 return -ENOTSUP;
1890 }
1891 return 0;
1892}
6f97dba0
AL
1893#endif /* __linux__ || __sun__ */
1894
1895#if defined(__linux__)
e551498e
GH
1896
1897#define HAVE_CHARDEV_PARPORT 1
1898
6f97dba0 1899typedef struct {
0ec7b3e7 1900 Chardev parent;
6f97dba0
AL
1901 int fd;
1902 int mode;
0ec7b3e7 1903} ParallelChardev;
6f97dba0 1904
777357d7
MAL
1905#define PARALLEL_CHARDEV(obj) \
1906 OBJECT_CHECK(ParallelChardev, (obj), TYPE_CHARDEV_PARALLEL)
1907
0ec7b3e7 1908static int pp_hw_mode(ParallelChardev *s, uint16_t mode)
6f97dba0
AL
1909{
1910 if (s->mode != mode) {
1911 int m = mode;
1912 if (ioctl(s->fd, PPSETMODE, &m) < 0)
1913 return 0;
1914 s->mode = mode;
1915 }
1916 return 1;
1917}
1918
0ec7b3e7 1919static int pp_ioctl(Chardev *chr, int cmd, void *arg)
6f97dba0 1920{
777357d7 1921 ParallelChardev *drv = PARALLEL_CHARDEV(chr);
6f97dba0
AL
1922 int fd = drv->fd;
1923 uint8_t b;
1924
1925 switch(cmd) {
1926 case CHR_IOCTL_PP_READ_DATA:
1927 if (ioctl(fd, PPRDATA, &b) < 0)
1928 return -ENOTSUP;
1929 *(uint8_t *)arg = b;
1930 break;
1931 case CHR_IOCTL_PP_WRITE_DATA:
1932 b = *(uint8_t *)arg;
1933 if (ioctl(fd, PPWDATA, &b) < 0)
1934 return -ENOTSUP;
1935 break;
1936 case CHR_IOCTL_PP_READ_CONTROL:
1937 if (ioctl(fd, PPRCONTROL, &b) < 0)
1938 return -ENOTSUP;
1939 /* Linux gives only the lowest bits, and no way to know data
1940 direction! For better compatibility set the fixed upper
1941 bits. */
1942 *(uint8_t *)arg = b | 0xc0;
1943 break;
1944 case CHR_IOCTL_PP_WRITE_CONTROL:
1945 b = *(uint8_t *)arg;
1946 if (ioctl(fd, PPWCONTROL, &b) < 0)
1947 return -ENOTSUP;
1948 break;
1949 case CHR_IOCTL_PP_READ_STATUS:
1950 if (ioctl(fd, PPRSTATUS, &b) < 0)
1951 return -ENOTSUP;
1952 *(uint8_t *)arg = b;
1953 break;
1954 case CHR_IOCTL_PP_DATA_DIR:
1955 if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
1956 return -ENOTSUP;
1957 break;
1958 case CHR_IOCTL_PP_EPP_READ_ADDR:
1959 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1960 struct ParallelIOArg *parg = arg;
1961 int n = read(fd, parg->buffer, parg->count);
1962 if (n != parg->count) {
1963 return -EIO;
1964 }
1965 }
1966 break;
1967 case CHR_IOCTL_PP_EPP_READ:
1968 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1969 struct ParallelIOArg *parg = arg;
1970 int n = read(fd, parg->buffer, parg->count);
1971 if (n != parg->count) {
1972 return -EIO;
1973 }
1974 }
1975 break;
1976 case CHR_IOCTL_PP_EPP_WRITE_ADDR:
1977 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1978 struct ParallelIOArg *parg = arg;
1979 int n = write(fd, parg->buffer, parg->count);
1980 if (n != parg->count) {
1981 return -EIO;
1982 }
1983 }
1984 break;
1985 case CHR_IOCTL_PP_EPP_WRITE:
1986 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1987 struct ParallelIOArg *parg = arg;
1988 int n = write(fd, parg->buffer, parg->count);
1989 if (n != parg->count) {
1990 return -EIO;
1991 }
1992 }
1993 break;
1994 default:
1995 return -ENOTSUP;
1996 }
1997 return 0;
1998}
1999
777357d7
MAL
2000static void qemu_chr_open_pp_fd(Chardev *chr,
2001 int fd,
2002 bool *be_opened,
2003 Error **errp)
6f97dba0 2004{
777357d7 2005 ParallelChardev *drv = PARALLEL_CHARDEV(chr);
6f97dba0
AL
2006
2007 if (ioctl(fd, PPCLAIM) < 0) {
38bfb1a6 2008 error_setg_errno(errp, errno, "not a parallel port");
6f97dba0 2009 close(fd);
777357d7 2010 return;
d0d7708b 2011 }
27ef9cb0 2012
27ef9cb0
PB
2013 drv->fd = fd;
2014 drv->mode = IEEE1284_MODE_COMPAT;
6f97dba0
AL
2015}
2016#endif /* __linux__ */
2017
a167ba50 2018#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
e551498e
GH
2019
2020#define HAVE_CHARDEV_PARPORT 1
2021
41ac54b2 2022typedef struct {
0ec7b3e7 2023 Chardev parent;
41ac54b2 2024 int fd;
0ec7b3e7 2025} ParallelChardev;
41ac54b2 2026
777357d7
MAL
2027#define PARALLEL_CHARDEV(obj) \
2028 OBJECT_CHECK(ParallelChardev, (obj), TYPE_CHARDEV_PARALLEL)
2029
0ec7b3e7 2030static int pp_ioctl(Chardev *chr, int cmd, void *arg)
6972f935 2031{
777357d7 2032 ParallelChardev *drv = PARALLEL_CHARDEV(chr);
6972f935
BS
2033 uint8_t b;
2034
41ac54b2 2035 switch (cmd) {
6972f935 2036 case CHR_IOCTL_PP_READ_DATA:
41ac54b2 2037 if (ioctl(drv->fd, PPIGDATA, &b) < 0) {
6972f935 2038 return -ENOTSUP;
41ac54b2 2039 }
6972f935
BS
2040 *(uint8_t *)arg = b;
2041 break;
2042 case CHR_IOCTL_PP_WRITE_DATA:
2043 b = *(uint8_t *)arg;
41ac54b2 2044 if (ioctl(drv->fd, PPISDATA, &b) < 0) {
6972f935 2045 return -ENOTSUP;
41ac54b2 2046 }
6972f935
BS
2047 break;
2048 case CHR_IOCTL_PP_READ_CONTROL:
41ac54b2 2049 if (ioctl(drv->fd, PPIGCTRL, &b) < 0) {
6972f935 2050 return -ENOTSUP;
41ac54b2 2051 }
6972f935
BS
2052 *(uint8_t *)arg = b;
2053 break;
2054 case CHR_IOCTL_PP_WRITE_CONTROL:
2055 b = *(uint8_t *)arg;
41ac54b2 2056 if (ioctl(drv->fd, PPISCTRL, &b) < 0) {
6972f935 2057 return -ENOTSUP;
41ac54b2 2058 }
6972f935
BS
2059 break;
2060 case CHR_IOCTL_PP_READ_STATUS:
41ac54b2 2061 if (ioctl(drv->fd, PPIGSTATUS, &b) < 0) {
6972f935 2062 return -ENOTSUP;
41ac54b2 2063 }
6972f935
BS
2064 *(uint8_t *)arg = b;
2065 break;
2066 default:
2067 return -ENOTSUP;
2068 }
2069 return 0;
2070}
2071
777357d7
MAL
2072static void qemu_chr_open_pp_fd(Chardev *chr,
2073 int fd,
2074 bool *be_opened,
2075 Error **errp)
6972f935 2076{
777357d7 2077 ParallelChardev *drv = PARALLEL_CHARDEV(chr);
41ac54b2 2078 drv->fd = fd;
82878dac 2079 *be_opened = false;
6972f935
BS
2080}
2081#endif
2082
6f97dba0
AL
2083#else /* _WIN32 */
2084
d809ab95
PB
2085#define HAVE_CHARDEV_SERIAL 1
2086
6f97dba0 2087typedef struct {
0ec7b3e7 2088 Chardev parent;
6f97dba0
AL
2089 int max_size;
2090 HANDLE hcom, hrecv, hsend;
9005b2a7 2091 OVERLAPPED orecv;
6f97dba0
AL
2092 BOOL fpipe;
2093 DWORD len;
9005b2a7 2094
0ec7b3e7 2095 /* Protected by the Chardev chr_write_lock. */
9005b2a7 2096 OVERLAPPED osend;
c266d94e
MAL
2097 /* FIXME: file/console do not finalize */
2098 bool skip_free;
0ec7b3e7 2099} WinChardev;
6f97dba0 2100
777357d7
MAL
2101#define TYPE_CHARDEV_WIN "chardev-win"
2102#define WIN_CHARDEV(obj) OBJECT_CHECK(WinChardev, (obj), TYPE_CHARDEV_WIN)
2103
db418a0a 2104typedef struct {
0ec7b3e7 2105 Chardev parent;
db418a0a
FC
2106 HANDLE hStdIn;
2107 HANDLE hInputReadyEvent;
2108 HANDLE hInputDoneEvent;
2109 HANDLE hInputThread;
2110 uint8_t win_stdio_buf;
0ec7b3e7 2111} WinStdioChardev;
db418a0a 2112
777357d7
MAL
2113#define TYPE_CHARDEV_WIN_STDIO "chardev-win-stdio"
2114#define WIN_STDIO_CHARDEV(obj) \
2115 OBJECT_CHECK(WinStdioChardev, (obj), TYPE_CHARDEV_WIN_STDIO)
2116
6f97dba0
AL
2117#define NSENDBUF 2048
2118#define NRECVBUF 2048
2119#define MAXCONNECT 1
2120#define NTIMEOUT 5000
2121
2122static int win_chr_poll(void *opaque);
2123static int win_chr_pipe_poll(void *opaque);
2124
53a5736f 2125static void char_win_finalize(Object *obj)
6f97dba0 2126{
53a5736f 2127 Chardev *chr = CHARDEV(obj);
777357d7 2128 WinChardev *s = WIN_CHARDEV(chr);
6f97dba0 2129
c266d94e
MAL
2130 if (s->skip_free) {
2131 return;
2132 }
2133
6f97dba0
AL
2134 if (s->hsend) {
2135 CloseHandle(s->hsend);
6f97dba0
AL
2136 }
2137 if (s->hrecv) {
2138 CloseHandle(s->hrecv);
6f97dba0
AL
2139 }
2140 if (s->hcom) {
2141 CloseHandle(s->hcom);
6f97dba0
AL
2142 }
2143 if (s->fpipe)
2144 qemu_del_polling_cb(win_chr_pipe_poll, chr);
2145 else
2146 qemu_del_polling_cb(win_chr_poll, chr);
793cbfb5 2147
a425d23f 2148 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
6f97dba0
AL
2149}
2150
0ec7b3e7 2151static int win_chr_init(Chardev *chr, const char *filename, Error **errp)
6f97dba0 2152{
777357d7 2153 WinChardev *s = WIN_CHARDEV(chr);
6f97dba0
AL
2154 COMMCONFIG comcfg;
2155 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2156 COMSTAT comstat;
2157 DWORD size;
2158 DWORD err;
2159
2160 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2161 if (!s->hsend) {
6511d396 2162 error_setg(errp, "Failed CreateEvent");
6f97dba0
AL
2163 goto fail;
2164 }
2165 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2166 if (!s->hrecv) {
6511d396 2167 error_setg(errp, "Failed CreateEvent");
6f97dba0
AL
2168 goto fail;
2169 }
2170
2171 s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2172 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2173 if (s->hcom == INVALID_HANDLE_VALUE) {
6511d396 2174 error_setg(errp, "Failed CreateFile (%lu)", GetLastError());
6f97dba0
AL
2175 s->hcom = NULL;
2176 goto fail;
2177 }
2178
2179 if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
6511d396 2180 error_setg(errp, "Failed SetupComm");
6f97dba0
AL
2181 goto fail;
2182 }
2183
2184 ZeroMemory(&comcfg, sizeof(COMMCONFIG));
2185 size = sizeof(COMMCONFIG);
2186 GetDefaultCommConfig(filename, &comcfg, &size);
2187 comcfg.dcb.DCBlength = sizeof(DCB);
2188 CommConfigDialog(filename, NULL, &comcfg);
2189
2190 if (!SetCommState(s->hcom, &comcfg.dcb)) {
6511d396 2191 error_setg(errp, "Failed SetCommState");
6f97dba0
AL
2192 goto fail;
2193 }
2194
2195 if (!SetCommMask(s->hcom, EV_ERR)) {
6511d396 2196 error_setg(errp, "Failed SetCommMask");
6f97dba0
AL
2197 goto fail;
2198 }
2199
2200 cto.ReadIntervalTimeout = MAXDWORD;
2201 if (!SetCommTimeouts(s->hcom, &cto)) {
6511d396 2202 error_setg(errp, "Failed SetCommTimeouts");
6f97dba0
AL
2203 goto fail;
2204 }
2205
2206 if (!ClearCommError(s->hcom, &err, &comstat)) {
6511d396 2207 error_setg(errp, "Failed ClearCommError");
6f97dba0
AL
2208 goto fail;
2209 }
2210 qemu_add_polling_cb(win_chr_poll, chr);
2211 return 0;
2212
2213 fail:
6f97dba0
AL
2214 return -1;
2215}
2216
9005b2a7 2217/* Called with chr_write_lock held. */
0ec7b3e7 2218static int win_chr_write(Chardev *chr, const uint8_t *buf, int len1)
6f97dba0 2219{
777357d7 2220 WinChardev *s = WIN_CHARDEV(chr);
6f97dba0
AL
2221 DWORD len, ret, size, err;
2222
2223 len = len1;
2224 ZeroMemory(&s->osend, sizeof(s->osend));
2225 s->osend.hEvent = s->hsend;
2226 while (len > 0) {
2227 if (s->hsend)
2228 ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
2229 else
2230 ret = WriteFile(s->hcom, buf, len, &size, NULL);
2231 if (!ret) {
2232 err = GetLastError();
2233 if (err == ERROR_IO_PENDING) {
2234 ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
2235 if (ret) {
2236 buf += size;
2237 len -= size;
2238 } else {
2239 break;
2240 }
2241 } else {
2242 break;
2243 }
2244 } else {
2245 buf += size;
2246 len -= size;
2247 }
2248 }
2249 return len1 - len;
2250}
2251
0ec7b3e7 2252static int win_chr_read_poll(Chardev *chr)
6f97dba0 2253{
777357d7 2254 WinChardev *s = WIN_CHARDEV(chr);
6f97dba0 2255
909cda12 2256 s->max_size = qemu_chr_be_can_write(chr);
6f97dba0
AL
2257 return s->max_size;
2258}
2259
0ec7b3e7 2260static void win_chr_readfile(Chardev *chr)
6f97dba0 2261{
777357d7
MAL
2262 WinChardev *s = WIN_CHARDEV(chr);
2263
6f97dba0 2264 int ret, err;
9bd7854e 2265 uint8_t buf[READ_BUF_LEN];
6f97dba0
AL
2266 DWORD size;
2267
2268 ZeroMemory(&s->orecv, sizeof(s->orecv));
2269 s->orecv.hEvent = s->hrecv;
2270 ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
2271 if (!ret) {
2272 err = GetLastError();
2273 if (err == ERROR_IO_PENDING) {
2274 ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
2275 }
2276 }
2277
2278 if (size > 0) {
fa5efccb 2279 qemu_chr_be_write(chr, buf, size);
6f97dba0
AL
2280 }
2281}
2282
0ec7b3e7 2283static void win_chr_read(Chardev *chr)
6f97dba0 2284{
777357d7 2285 WinChardev *s = WIN_CHARDEV(chr);
6f97dba0
AL
2286
2287 if (s->len > s->max_size)
2288 s->len = s->max_size;
2289 if (s->len == 0)
2290 return;
2291
2292 win_chr_readfile(chr);
2293}
2294
2295static int win_chr_poll(void *opaque)
2296{
777357d7
MAL
2297 Chardev *chr = CHARDEV(opaque);
2298 WinChardev *s = WIN_CHARDEV(opaque);
6f97dba0
AL
2299 COMSTAT status;
2300 DWORD comerr;
2301
2302 ClearCommError(s->hcom, &comerr, &status);
2303 if (status.cbInQue > 0) {
2304 s->len = status.cbInQue;
2305 win_chr_read_poll(chr);
2306 win_chr_read(chr);
2307 return 1;
2308 }
2309 return 0;
2310}
2311
6f97dba0
AL
2312static int win_chr_pipe_poll(void *opaque)
2313{
777357d7
MAL
2314 Chardev *chr = CHARDEV(opaque);
2315 WinChardev *s = WIN_CHARDEV(opaque);
6f97dba0
AL
2316 DWORD size;
2317
2318 PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
2319 if (size > 0) {
2320 s->len = size;
2321 win_chr_read_poll(chr);
2322 win_chr_read(chr);
2323 return 1;
2324 }
2325 return 0;
2326}
2327
0ec7b3e7 2328static int win_chr_pipe_init(Chardev *chr, const char *filename,
20cbe7a2 2329 Error **errp)
6f97dba0 2330{
777357d7 2331 WinChardev *s = WIN_CHARDEV(chr);
6f97dba0
AL
2332 OVERLAPPED ov;
2333 int ret;
2334 DWORD size;
0ff0fad2 2335 char *openname;
6f97dba0
AL
2336
2337 s->fpipe = TRUE;
2338
2339 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2340 if (!s->hsend) {
20cbe7a2 2341 error_setg(errp, "Failed CreateEvent");
6f97dba0
AL
2342 goto fail;
2343 }
2344 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2345 if (!s->hrecv) {
20cbe7a2 2346 error_setg(errp, "Failed CreateEvent");
6f97dba0
AL
2347 goto fail;
2348 }
2349
0ff0fad2 2350 openname = g_strdup_printf("\\\\.\\pipe\\%s", filename);
6f97dba0
AL
2351 s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2352 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
2353 PIPE_WAIT,
2354 MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
0ff0fad2 2355 g_free(openname);
6f97dba0 2356 if (s->hcom == INVALID_HANDLE_VALUE) {
20cbe7a2 2357 error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError());
6f97dba0
AL
2358 s->hcom = NULL;
2359 goto fail;
2360 }
2361
2362 ZeroMemory(&ov, sizeof(ov));
2363 ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2364 ret = ConnectNamedPipe(s->hcom, &ov);
2365 if (ret) {
20cbe7a2 2366 error_setg(errp, "Failed ConnectNamedPipe");
6f97dba0
AL
2367 goto fail;
2368 }
2369
2370 ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
2371 if (!ret) {
20cbe7a2 2372 error_setg(errp, "Failed GetOverlappedResult");
6f97dba0
AL
2373 if (ov.hEvent) {
2374 CloseHandle(ov.hEvent);
2375 ov.hEvent = NULL;
2376 }
2377 goto fail;
2378 }
2379
2380 if (ov.hEvent) {
2381 CloseHandle(ov.hEvent);
2382 ov.hEvent = NULL;
2383 }
2384 qemu_add_polling_cb(win_chr_pipe_poll, chr);
2385 return 0;
2386
2387 fail:
6f97dba0
AL
2388 return -1;
2389}
2390
2391
777357d7
MAL
2392static void qemu_chr_open_pipe(Chardev *chr,
2393 ChardevBackend *backend,
2394 bool *be_opened,
2395 Error **errp)
6f97dba0 2396{
32bafa8f 2397 ChardevHostdev *opts = backend->u.pipe.data;
548cbb36 2398 const char *filename = opts->device;
6f97dba0 2399
20cbe7a2 2400 if (win_chr_pipe_init(chr, filename, errp) < 0) {
777357d7 2401 return;
6f97dba0 2402 }
6f97dba0
AL
2403}
2404
777357d7 2405static void qemu_chr_open_win_file(Chardev *chr, HANDLE fd_out)
6f97dba0 2406{
777357d7 2407 WinChardev *s = WIN_CHARDEV(chr);
6f97dba0 2408
c266d94e 2409 s->skip_free = true;
6f97dba0 2410 s->hcom = fd_out;
6f97dba0
AL
2411}
2412
777357d7 2413static void char_win_class_init(ObjectClass *oc, void *data)
6f97dba0 2414{
777357d7
MAL
2415 ChardevClass *cc = CHARDEV_CLASS(oc);
2416
2417 cc->chr_write = win_chr_write;
6f97dba0
AL
2418}
2419
777357d7
MAL
2420static const TypeInfo char_win_type_info = {
2421 .name = TYPE_CHARDEV_WIN,
2422 .parent = TYPE_CHARDEV,
0ec7b3e7 2423 .instance_size = sizeof(WinChardev),
53a5736f 2424 .instance_finalize = char_win_finalize,
777357d7
MAL
2425 .class_init = char_win_class_init,
2426 .abstract = true,
2427};
2428
2429static void qemu_chr_open_win_con(Chardev *chr,
2430 ChardevBackend *backend,
2431 bool *be_opened,
2432 Error **errp)
2433{
2434 qemu_chr_open_win_file(chr, GetStdHandle(STD_OUTPUT_HANDLE));
2435}
2436
777357d7
MAL
2437static void char_console_class_init(ObjectClass *oc, void *data)
2438{
2439 ChardevClass *cc = CHARDEV_CLASS(oc);
2440
2441 cc->open = qemu_chr_open_win_con;
777357d7
MAL
2442}
2443
2444static const TypeInfo char_console_type_info = {
2445 .name = TYPE_CHARDEV_CONSOLE,
2446 .parent = TYPE_CHARDEV_WIN,
2447 .class_init = char_console_class_init,
b68e956a
MAL
2448};
2449
0ec7b3e7 2450static int win_stdio_write(Chardev *chr, const uint8_t *buf, int len)
db418a0a
FC
2451{
2452 HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
2453 DWORD dwSize;
2454 int len1;
2455
2456 len1 = len;
2457
2458 while (len1 > 0) {
2459 if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
2460 break;
2461 }
2462 buf += dwSize;
2463 len1 -= dwSize;
2464 }
2465
2466 return len - len1;
2467}
2468
2469static void win_stdio_wait_func(void *opaque)
2470{
777357d7
MAL
2471 Chardev *chr = CHARDEV(opaque);
2472 WinStdioChardev *stdio = WIN_STDIO_CHARDEV(opaque);
db418a0a
FC
2473 INPUT_RECORD buf[4];
2474 int ret;
2475 DWORD dwSize;
2476 int i;
2477
dff7424d 2478 ret = ReadConsoleInput(stdio->hStdIn, buf, ARRAY_SIZE(buf), &dwSize);
db418a0a
FC
2479
2480 if (!ret) {
2481 /* Avoid error storm */
2482 qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
2483 return;
2484 }
2485
2486 for (i = 0; i < dwSize; i++) {
2487 KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;
2488
2489 if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
2490 int j;
2491 if (kev->uChar.AsciiChar != 0) {
2492 for (j = 0; j < kev->wRepeatCount; j++) {
2493 if (qemu_chr_be_can_write(chr)) {
2494 uint8_t c = kev->uChar.AsciiChar;
2495 qemu_chr_be_write(chr, &c, 1);
2496 }
2497 }
2498 }
2499 }
2500 }
2501}
2502
2503static DWORD WINAPI win_stdio_thread(LPVOID param)
2504{
777357d7 2505 WinStdioChardev *stdio = WIN_STDIO_CHARDEV(param);
db418a0a
FC
2506 int ret;
2507 DWORD dwSize;
2508
2509 while (1) {
2510
2511 /* Wait for one byte */
2512 ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);
2513
2514 /* Exit in case of error, continue if nothing read */
2515 if (!ret) {
2516 break;
2517 }
2518 if (!dwSize) {
2519 continue;
2520 }
2521
2522 /* Some terminal emulator returns \r\n for Enter, just pass \n */
2523 if (stdio->win_stdio_buf == '\r') {
2524 continue;
2525 }
2526
2527 /* Signal the main thread and wait until the byte was eaten */
2528 if (!SetEvent(stdio->hInputReadyEvent)) {
2529 break;
2530 }
2531 if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
2532 != WAIT_OBJECT_0) {
2533 break;
2534 }
2535 }
2536
2537 qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
2538 return 0;
2539}
2540
2541static void win_stdio_thread_wait_func(void *opaque)
2542{
777357d7
MAL
2543 Chardev *chr = CHARDEV(opaque);
2544 WinStdioChardev *stdio = WIN_STDIO_CHARDEV(opaque);
db418a0a
FC
2545
2546 if (qemu_chr_be_can_write(chr)) {
2547 qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
2548 }
2549
2550 SetEvent(stdio->hInputDoneEvent);
2551}
2552
0ec7b3e7 2553static void qemu_chr_set_echo_win_stdio(Chardev *chr, bool echo)
db418a0a 2554{
777357d7 2555 WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr);
db418a0a
FC
2556 DWORD dwMode = 0;
2557
2558 GetConsoleMode(stdio->hStdIn, &dwMode);
2559
2560 if (echo) {
2561 SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
2562 } else {
2563 SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
2564 }
2565}
2566
1566b0c4 2567static void char_win_stdio_finalize(Object *obj)
db418a0a 2568{
1566b0c4 2569 WinStdioChardev *stdio = WIN_STDIO_CHARDEV(obj);
db418a0a
FC
2570
2571 if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
2572 CloseHandle(stdio->hInputReadyEvent);
2573 }
2574 if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
2575 CloseHandle(stdio->hInputDoneEvent);
2576 }
2577 if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
2578 TerminateThread(stdio->hInputThread, 0);
2579 }
db418a0a
FC
2580}
2581
777357d7
MAL
2582static const TypeInfo char_win_stdio_type_info = {
2583 .name = TYPE_CHARDEV_WIN_STDIO,
2584 .parent = TYPE_CHARDEV,
2585 .instance_size = sizeof(WinStdioChardev),
1566b0c4 2586 .instance_finalize = char_win_stdio_finalize,
777357d7
MAL
2587 .abstract = true,
2588};
2589
2590static void qemu_chr_open_stdio(Chardev *chr,
2591 ChardevBackend *backend,
2592 bool *be_opened,
2593 Error **errp)
db418a0a 2594{
777357d7 2595 WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr);
db418a0a
FC
2596 DWORD dwMode;
2597 int is_console = 0;
db418a0a
FC
2598
2599 stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
2600 if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
8c84b25d 2601 error_setg(errp, "cannot open stdio: invalid handle");
777357d7 2602 return;
db418a0a
FC
2603 }
2604
2605 is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
2606
ed7a1540
AL
2607 if (is_console) {
2608 if (qemu_add_wait_object(stdio->hStdIn,
2609 win_stdio_wait_func, chr)) {
8c84b25d
PB
2610 error_setg(errp, "qemu_add_wait_object: failed");
2611 goto err1;
ed7a1540
AL
2612 }
2613 } else {
2614 DWORD dwId;
2615
2616 stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2617 stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
8c84b25d 2618 if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
ed7a1540 2619 || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
8c84b25d
PB
2620 error_setg(errp, "cannot create event");
2621 goto err2;
ed7a1540
AL
2622 }
2623 if (qemu_add_wait_object(stdio->hInputReadyEvent,
2624 win_stdio_thread_wait_func, chr)) {
8c84b25d
PB
2625 error_setg(errp, "qemu_add_wait_object: failed");
2626 goto err2;
2627 }
2628 stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread,
2629 chr, 0, &dwId);
2630
2631 if (stdio->hInputThread == INVALID_HANDLE_VALUE) {
2632 error_setg(errp, "cannot create stdio thread");
2633 goto err3;
db418a0a
FC
2634 }
2635 }
2636
2637 dwMode |= ENABLE_LINE_INPUT;
2638
ed7a1540 2639 if (is_console) {
db418a0a
FC
2640 /* set the terminal in raw mode */
2641 /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
2642 dwMode |= ENABLE_PROCESSED_INPUT;
2643 }
2644
2645 SetConsoleMode(stdio->hStdIn, dwMode);
2646
5345fdb4 2647 qemu_chr_set_echo_win_stdio(chr, false);
db418a0a 2648
777357d7 2649 return;
8c84b25d
PB
2650
2651err3:
2652 qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
2653err2:
2654 CloseHandle(stdio->hInputReadyEvent);
2655 CloseHandle(stdio->hInputDoneEvent);
2656err1:
2657 qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
db418a0a 2658}
6f97dba0
AL
2659#endif /* !_WIN32 */
2660
2661/***********************************************************/
2662/* UDP Net console */
2663
2664typedef struct {
0ec7b3e7 2665 Chardev parent;
9894dc0c 2666 QIOChannel *ioc;
9bd7854e 2667 uint8_t buf[READ_BUF_LEN];
6f97dba0
AL
2668 int bufcnt;
2669 int bufptr;
2670 int max_size;
1876ed04 2671} UdpChardev;
6f97dba0 2672
777357d7
MAL
2673#define UDP_CHARDEV(obj) OBJECT_CHECK(UdpChardev, (obj), TYPE_CHARDEV_UDP)
2674
9005b2a7 2675/* Called with chr_write_lock held. */
0ec7b3e7 2676static int udp_chr_write(Chardev *chr, const uint8_t *buf, int len)
6f97dba0 2677{
777357d7 2678 UdpChardev *s = UDP_CHARDEV(chr);
76a9644b 2679
9894dc0c
DB
2680 return qio_channel_write(
2681 s->ioc, (const char *)buf, len, NULL);
6f97dba0
AL
2682}
2683
2684static int udp_chr_read_poll(void *opaque)
2685{
777357d7
MAL
2686 Chardev *chr = CHARDEV(opaque);
2687 UdpChardev *s = UDP_CHARDEV(opaque);
6f97dba0 2688
909cda12 2689 s->max_size = qemu_chr_be_can_write(chr);
6f97dba0
AL
2690
2691 /* If there were any stray characters in the queue process them
2692 * first
2693 */
2694 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
fa5efccb 2695 qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
6f97dba0 2696 s->bufptr++;
909cda12 2697 s->max_size = qemu_chr_be_can_write(chr);
6f97dba0
AL
2698 }
2699 return s->max_size;
2700}
2701
9894dc0c 2702static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
6f97dba0 2703{
777357d7
MAL
2704 Chardev *chr = CHARDEV(opaque);
2705 UdpChardev *s = UDP_CHARDEV(opaque);
9894dc0c 2706 ssize_t ret;
6f97dba0 2707
cdbf6e16
PB
2708 if (s->max_size == 0) {
2709 return TRUE;
2710 }
9894dc0c
DB
2711 ret = qio_channel_read(
2712 s->ioc, (char *)s->buf, sizeof(s->buf), NULL);
2713 if (ret <= 0) {
26da70c7 2714 remove_fd_in_watch(chr);
76a9644b
AL
2715 return FALSE;
2716 }
9894dc0c 2717 s->bufcnt = ret;
6f97dba0
AL
2718
2719 s->bufptr = 0;
2720 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
fa5efccb 2721 qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
6f97dba0 2722 s->bufptr++;
909cda12 2723 s->max_size = qemu_chr_be_can_write(chr);
6f97dba0 2724 }
76a9644b
AL
2725
2726 return TRUE;
6f97dba0
AL
2727}
2728
0ec7b3e7 2729static void udp_chr_update_read_handler(Chardev *chr,
a4afa548 2730 GMainContext *context)
6f97dba0 2731{
777357d7 2732 UdpChardev *s = UDP_CHARDEV(chr);
6f97dba0 2733
26da70c7 2734 remove_fd_in_watch(chr);
9894dc0c 2735 if (s->ioc) {
e93a68e1 2736 chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
9894dc0c 2737 udp_chr_read_poll,
e92aa36a
ZC
2738 udp_chr_read, chr,
2739 context);
6f97dba0
AL
2740 }
2741}
2742
819aad23 2743static void char_udp_finalize(Object *obj)
819f56b7 2744{
819aad23
MAL
2745 Chardev *chr = CHARDEV(obj);
2746 UdpChardev *s = UDP_CHARDEV(obj);
26da70c7
AS
2747
2748 remove_fd_in_watch(chr);
9894dc0c
DB
2749 if (s->ioc) {
2750 object_unref(OBJECT(s->ioc));
819f56b7 2751 }
a425d23f 2752 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
819f56b7
AL
2753}
2754
6f97dba0
AL
2755/***********************************************************/
2756/* TCP Net console */
2757
2758typedef struct {
0ec7b3e7 2759 Chardev parent;
a8fb5427
DB
2760 QIOChannel *ioc; /* Client I/O channel */
2761 QIOChannelSocket *sioc; /* Client master channel */
9894dc0c 2762 QIOChannelSocket *listen_ioc;
7ba9addc 2763 guint listen_tag;
a8fb5427 2764 QCryptoTLSCreds *tls_creds;
6f97dba0
AL
2765 int connected;
2766 int max_size;
2767 int do_telnetopt;
2768 int do_nodelay;
2769 int is_unix;
c76bf6bb 2770 int *read_msgfds;
9894dc0c 2771 size_t read_msgfds_num;
d39aac7a 2772 int *write_msgfds;
9894dc0c 2773 size_t write_msgfds_num;
cfb429cb
CM
2774
2775 SocketAddress *addr;
2776 bool is_listen;
2777 bool is_telnet;
5dd1f02b
CM
2778
2779 guint reconnect_timer;
2780 int64_t reconnect_time;
5008e5b7 2781 bool connect_err_reported;
1876ed04 2782} SocketChardev;
6f97dba0 2783
777357d7
MAL
2784#define SOCKET_CHARDEV(obj) \
2785 OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET)
2786
5dd1f02b
CM
2787static gboolean socket_reconnect_timeout(gpointer opaque);
2788
0ec7b3e7 2789static void qemu_chr_socket_restart_timer(Chardev *chr)
5dd1f02b 2790{
777357d7 2791 SocketChardev *s = SOCKET_CHARDEV(chr);
e93a68e1 2792 char *name;
41ac54b2 2793
5dd1f02b
CM
2794 assert(s->connected == 0);
2795 s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
2796 socket_reconnect_timeout, chr);
e93a68e1
DB
2797 name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
2798 g_source_set_name_by_id(s->reconnect_timer, name);
2799 g_free(name);
5dd1f02b
CM
2800}
2801
0ec7b3e7 2802static void check_report_connect_error(Chardev *chr,
5008e5b7
CM
2803 Error *err)
2804{
777357d7 2805 SocketChardev *s = SOCKET_CHARDEV(chr);
5008e5b7
CM
2806
2807 if (!s->connect_err_reported) {
2808 error_report("Unable to connect character device %s: %s",
2809 chr->label, error_get_pretty(err));
2810 s->connect_err_reported = true;
2811 }
2812 qemu_chr_socket_restart_timer(chr);
2813}
2814
9894dc0c
DB
2815static gboolean tcp_chr_accept(QIOChannel *chan,
2816 GIOCondition cond,
2817 void *opaque);
d39aac7a 2818
9005b2a7 2819/* Called with chr_write_lock held. */
0ec7b3e7 2820static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
6f97dba0 2821{
777357d7 2822 SocketChardev *s = SOCKET_CHARDEV(chr);
41ac54b2 2823
6f97dba0 2824 if (s->connected) {
9894dc0c
DB
2825 int ret = io_channel_send_full(s->ioc, buf, len,
2826 s->write_msgfds,
2827 s->write_msgfds_num);
2828
2829 /* free the written msgfds, no matter what */
2830 if (s->write_msgfds_num) {
2831 g_free(s->write_msgfds);
2832 s->write_msgfds = 0;
2833 s->write_msgfds_num = 0;
d39aac7a 2834 }
9894dc0c
DB
2835
2836 return ret;
455aa1e0 2837 } else {
6db0fdce 2838 /* XXX: indicate an error ? */
455aa1e0 2839 return len;
6f97dba0
AL
2840 }
2841}
2842
2843static int tcp_chr_read_poll(void *opaque)
2844{
777357d7
MAL
2845 Chardev *chr = CHARDEV(opaque);
2846 SocketChardev *s = SOCKET_CHARDEV(opaque);
6f97dba0
AL
2847 if (!s->connected)
2848 return 0;
909cda12 2849 s->max_size = qemu_chr_be_can_write(chr);
6f97dba0
AL
2850 return s->max_size;
2851}
2852
2853#define IAC 255
2854#define IAC_BREAK 243
0ec7b3e7 2855static void tcp_chr_process_IAC_bytes(Chardev *chr,
1876ed04 2856 SocketChardev *s,
6f97dba0
AL
2857 uint8_t *buf, int *size)
2858{
2859 /* Handle any telnet client's basic IAC options to satisfy char by
2860 * char mode with no echo. All IAC options will be removed from
2861 * the buf and the do_telnetopt variable will be used to track the
2862 * state of the width of the IAC information.
2863 *
2864 * IAC commands come in sets of 3 bytes with the exception of the
2865 * "IAC BREAK" command and the double IAC.
2866 */
2867
2868 int i;
2869 int j = 0;
2870
2871 for (i = 0; i < *size; i++) {
2872 if (s->do_telnetopt > 1) {
2873 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
2874 /* Double IAC means send an IAC */
2875 if (j != i)
2876 buf[j] = buf[i];
2877 j++;
2878 s->do_telnetopt = 1;
2879 } else {
2880 if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
2881 /* Handle IAC break commands by sending a serial break */
a425d23f 2882 qemu_chr_be_event(chr, CHR_EVENT_BREAK);
6f97dba0
AL
2883 s->do_telnetopt++;
2884 }
2885 s->do_telnetopt++;
2886 }
2887 if (s->do_telnetopt >= 4) {
2888 s->do_telnetopt = 1;
2889 }
2890 } else {
2891 if ((unsigned char)buf[i] == IAC) {
2892 s->do_telnetopt = 2;
2893 } else {
2894 if (j != i)
2895 buf[j] = buf[i];
2896 j++;
2897 }
2898 }
2899 }
2900 *size = j;
2901}
2902
0ec7b3e7 2903static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
7d174059 2904{
777357d7 2905 SocketChardev *s = SOCKET_CHARDEV(chr);
41ac54b2 2906
c76bf6bb
NN
2907 int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
2908
c4095726
MT
2909 assert(num <= TCP_MAX_FDS);
2910
c76bf6bb 2911 if (to_copy) {
d2fc39b4
SH
2912 int i;
2913
c76bf6bb
NN
2914 memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
2915
d2fc39b4
SH
2916 /* Close unused fds */
2917 for (i = to_copy; i < s->read_msgfds_num; i++) {
2918 close(s->read_msgfds[i]);
2919 }
2920
c76bf6bb
NN
2921 g_free(s->read_msgfds);
2922 s->read_msgfds = 0;
2923 s->read_msgfds_num = 0;
2924 }
2925
2926 return to_copy;
7d174059
MM
2927}
2928
0ec7b3e7 2929static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
d39aac7a 2930{
777357d7 2931 SocketChardev *s = SOCKET_CHARDEV(chr);
d39aac7a
NN
2932
2933 /* clear old pending fd array */
ef1e1e07 2934 g_free(s->write_msgfds);
869a58af 2935 s->write_msgfds = NULL;
5b498459 2936 s->write_msgfds_num = 0;
d39aac7a 2937
5c7eaabf
MAL
2938 if (!s->connected ||
2939 !qio_channel_has_feature(s->ioc,
2940 QIO_CHANNEL_FEATURE_FD_PASS)) {
2941 return -1;
2942 }
2943
d39aac7a 2944 if (num) {
2d528d45 2945 s->write_msgfds = g_new(int, num);
d39aac7a
NN
2946 memcpy(s->write_msgfds, fds, num * sizeof(int));
2947 }
2948
2949 s->write_msgfds_num = num;
2950
2951 return 0;
2952}
2953
0ec7b3e7 2954static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
7d174059 2955{
777357d7 2956 SocketChardev *s = SOCKET_CHARDEV(chr);
9894dc0c
DB
2957 struct iovec iov = { .iov_base = buf, .iov_len = len };
2958 int ret;
2959 size_t i;
2960 int *msgfds = NULL;
2961 size_t msgfds_num = 0;
2962
2963 if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
2964 ret = qio_channel_readv_full(s->ioc, &iov, 1,
2965 &msgfds, &msgfds_num,
2966 NULL);
2967 } else {
2968 ret = qio_channel_readv_full(s->ioc, &iov, 1,
2969 NULL, NULL,
2970 NULL);
2971 }
7d174059 2972
b6572b4f
MAL
2973 if (ret == QIO_CHANNEL_ERR_BLOCK) {
2974 errno = EAGAIN;
2975 ret = -1;
2976 } else if (ret == -1) {
2977 errno = EIO;
2978 }
2979
9894dc0c 2980 if (msgfds_num) {
c76bf6bb
NN
2981 /* close and clean read_msgfds */
2982 for (i = 0; i < s->read_msgfds_num; i++) {
2983 close(s->read_msgfds[i]);
2984 }
9b938c72 2985
c76bf6bb
NN
2986 if (s->read_msgfds_num) {
2987 g_free(s->read_msgfds);
2988 }
2989
9894dc0c
DB
2990 s->read_msgfds = msgfds;
2991 s->read_msgfds_num = msgfds_num;
7d174059 2992 }
7d174059 2993
9894dc0c
DB
2994 for (i = 0; i < s->read_msgfds_num; i++) {
2995 int fd = s->read_msgfds[i];
2996 if (fd < 0) {
2997 continue;
2998 }
9977c894 2999
9894dc0c
DB
3000 /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
3001 qemu_set_block(fd);
7d174059 3002
9894dc0c
DB
3003#ifndef MSG_CMSG_CLOEXEC
3004 qemu_set_cloexec(fd);
06138651 3005#endif
06138651 3006 }
9977c894 3007
7d174059 3008 return ret;
9977c894 3009}
9977c894 3010
0ec7b3e7 3011static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
d3cc5bc4 3012{
777357d7 3013 SocketChardev *s = SOCKET_CHARDEV(chr);
9894dc0c 3014 return qio_channel_create_watch(s->ioc, cond);
d3cc5bc4
AS
3015}
3016
0ec7b3e7 3017static void tcp_chr_free_connection(Chardev *chr)
7b0bfdf5 3018{
777357d7 3019 SocketChardev *s = SOCKET_CHARDEV(chr);
5b498459 3020 int i;
7b0bfdf5 3021
342f7a9d
MAL
3022 if (!s->connected) {
3023 return;
3024 }
3025
5b498459
MAL
3026 if (s->read_msgfds_num) {
3027 for (i = 0; i < s->read_msgfds_num; i++) {
3028 close(s->read_msgfds[i]);
3029 }
3030 g_free(s->read_msgfds);
3031 s->read_msgfds = NULL;
3032 s->read_msgfds_num = 0;
7b0bfdf5 3033 }
5b498459 3034
6167ebbd 3035 tcp_set_msgfds(chr, NULL, 0);
7b0bfdf5 3036 remove_fd_in_watch(chr);
a8fb5427
DB
3037 object_unref(OBJECT(s->sioc));
3038 s->sioc = NULL;
9894dc0c
DB
3039 object_unref(OBJECT(s->ioc));
3040 s->ioc = NULL;
0ff0fad2 3041 g_free(chr->filename);
5b498459
MAL
3042 chr->filename = NULL;
3043 s->connected = 0;
3044}
3045
0ec7b3e7 3046static void tcp_chr_disconnect(Chardev *chr)
5b498459 3047{
777357d7 3048 SocketChardev *s = SOCKET_CHARDEV(chr);
5b498459
MAL
3049
3050 if (!s->connected) {
3051 return;
3052 }
3053
3054 tcp_chr_free_connection(chr);
3055
3056 if (s->listen_ioc) {
3057 s->listen_tag = qio_channel_add_watch(
3058 QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
3059 }
0ff0fad2
DB
3060 chr->filename = SocketAddress_to_str("disconnected:", s->addr,
3061 s->is_listen, s->is_telnet);
7b0bfdf5 3062 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
5dd1f02b
CM
3063 if (s->reconnect_time) {
3064 qemu_chr_socket_restart_timer(chr);
3065 }
7b0bfdf5
NN
3066}
3067
9894dc0c 3068static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
6f97dba0 3069{
777357d7
MAL
3070 Chardev *chr = CHARDEV(opaque);
3071 SocketChardev *s = SOCKET_CHARDEV(opaque);
9bd7854e 3072 uint8_t buf[READ_BUF_LEN];
6f97dba0
AL
3073 int len, size;
3074
2ea5a7af 3075 if (!s->connected || s->max_size <= 0) {
cdbf6e16 3076 return TRUE;
2ea5a7af 3077 }
6f97dba0
AL
3078 len = sizeof(buf);
3079 if (len > s->max_size)
3080 len = s->max_size;
9977c894 3081 size = tcp_chr_recv(chr, (void *)buf, len);
9894dc0c 3082 if (size == 0 || size == -1) {
6f97dba0 3083 /* connection closed */
7b0bfdf5 3084 tcp_chr_disconnect(chr);
6f97dba0
AL
3085 } else if (size > 0) {
3086 if (s->do_telnetopt)
3087 tcp_chr_process_IAC_bytes(chr, s, buf, &size);
3088 if (size > 0)
fa5efccb 3089 qemu_chr_be_write(chr, buf, size);
6f97dba0 3090 }
2ea5a7af
AL
3091
3092 return TRUE;
6f97dba0
AL
3093}
3094
0ec7b3e7 3095static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
7b0bfdf5 3096{
777357d7 3097 SocketChardev *s = SOCKET_CHARDEV(chr);
7b0bfdf5
NN
3098 int size;
3099
3100 if (!s->connected) {
3101 return 0;
3102 }
3103
3104 size = tcp_chr_recv(chr, (void *) buf, len);
3105 if (size == 0) {
3106 /* connection closed */
3107 tcp_chr_disconnect(chr);
3108 }
3109
3110 return size;
3111}
3112
6f97dba0
AL
3113static void tcp_chr_connect(void *opaque)
3114{
777357d7
MAL
3115 Chardev *chr = CHARDEV(opaque);
3116 SocketChardev *s = SOCKET_CHARDEV(opaque);
16cc4ffe 3117
0ff0fad2 3118 g_free(chr->filename);
a8fb5427
DB
3119 chr->filename = sockaddr_to_str(
3120 &s->sioc->localAddr, s->sioc->localAddrLen,
3121 &s->sioc->remoteAddr, s->sioc->remoteAddrLen,
3122 s->is_listen, s->is_telnet);
6f97dba0
AL
3123
3124 s->connected = 1;
9894dc0c 3125 if (s->ioc) {
e93a68e1 3126 chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
9894dc0c 3127 tcp_chr_read_poll,
e92aa36a
ZC
3128 tcp_chr_read,
3129 chr, NULL);
bbdd2ad0 3130 }
fee204fd 3131 qemu_chr_be_generic_open(chr);
6f97dba0
AL
3132}
3133
0ec7b3e7 3134static void tcp_chr_update_read_handler(Chardev *chr,
a4afa548 3135 GMainContext *context)
ac1b84dd 3136{
777357d7 3137 SocketChardev *s = SOCKET_CHARDEV(chr);
ac1b84dd 3138
1e94f23d
DB
3139 if (!s->connected) {
3140 return;
3141 }
3142
ac1b84dd 3143 remove_fd_in_watch(chr);
9894dc0c 3144 if (s->ioc) {
e93a68e1 3145 chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
9894dc0c 3146 tcp_chr_read_poll,
e92aa36a
ZC
3147 tcp_chr_read, chr,
3148 context);
ac1b84dd
GH
3149 }
3150}
3151
f2001a7e 3152typedef struct {
0ec7b3e7 3153 Chardev *chr;
f2001a7e
DB
3154 char buf[12];
3155 size_t buflen;
279b066e 3156} TCPChardevTelnetInit;
f2001a7e
DB
3157
3158static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
3159 GIOCondition cond G_GNUC_UNUSED,
3160 gpointer user_data)
6f97dba0 3161{
279b066e 3162 TCPChardevTelnetInit *init = user_data;
f2001a7e
DB
3163 ssize_t ret;
3164
3165 ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
3166 if (ret < 0) {
3167 if (ret == QIO_CHANNEL_ERR_BLOCK) {
3168 ret = 0;
3169 } else {
3170 tcp_chr_disconnect(init->chr);
3171 return FALSE;
3172 }
3173 }
3174 init->buflen -= ret;
3175
3176 if (init->buflen == 0) {
3177 tcp_chr_connect(init->chr);
3178 return FALSE;
3179 }
3180
3181 memmove(init->buf, init->buf + ret, init->buflen);
3182
3183 return TRUE;
3184}
3185
0ec7b3e7 3186static void tcp_chr_telnet_init(Chardev *chr)
f2001a7e 3187{
777357d7 3188 SocketChardev *s = SOCKET_CHARDEV(chr);
279b066e 3189 TCPChardevTelnetInit *init = g_new0(TCPChardevTelnetInit, 1);
f2001a7e
DB
3190 size_t n = 0;
3191
3192 init->chr = chr;
3193 init->buflen = 12;
3194
3195#define IACSET(x, a, b, c) \
3196 do { \
3197 x[n++] = a; \
3198 x[n++] = b; \
3199 x[n++] = c; \
3200 } while (0)
3201
3202 /* Prep the telnet negotion to put telnet in binary,
3203 * no echo, single char mode */
3204 IACSET(init->buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
3205 IACSET(init->buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
3206 IACSET(init->buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
3207 IACSET(init->buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
3208
3209#undef IACSET
3210
3211 qio_channel_add_watch(
3212 s->ioc, G_IO_OUT,
3213 tcp_chr_telnet_init_io,
3214 init, NULL);
6f97dba0
AL
3215}
3216
a8fb5427 3217
60e705c5 3218static void tcp_chr_tls_handshake(QIOTask *task,
a8fb5427
DB
3219 gpointer user_data)
3220{
0ec7b3e7 3221 Chardev *chr = user_data;
1876ed04 3222 SocketChardev *s = user_data;
a8fb5427 3223
60e705c5 3224 if (qio_task_propagate_error(task, NULL)) {
a8fb5427
DB
3225 tcp_chr_disconnect(chr);
3226 } else {
3227 if (s->do_telnetopt) {
3228 tcp_chr_telnet_init(chr);
3229 } else {
3230 tcp_chr_connect(chr);
3231 }
3232 }
3233}
3234
3235
0ec7b3e7 3236static void tcp_chr_tls_init(Chardev *chr)
a8fb5427 3237{
777357d7 3238 SocketChardev *s = SOCKET_CHARDEV(chr);
a8fb5427
DB
3239 QIOChannelTLS *tioc;
3240 Error *err = NULL;
e93a68e1 3241 gchar *name;
a8fb5427
DB
3242
3243 if (s->is_listen) {
3244 tioc = qio_channel_tls_new_server(
3245 s->ioc, s->tls_creds,
3246 NULL, /* XXX Use an ACL */
3247 &err);
3248 } else {
3249 tioc = qio_channel_tls_new_client(
3250 s->ioc, s->tls_creds,
32bafa8f 3251 s->addr->u.inet.data->host,
a8fb5427
DB
3252 &err);
3253 }
3254 if (tioc == NULL) {
3255 error_free(err);
3256 tcp_chr_disconnect(chr);
660a2d83 3257 return;
a8fb5427 3258 }
e93a68e1
DB
3259 name = g_strdup_printf("chardev-tls-%s-%s",
3260 s->is_listen ? "server" : "client",
3261 chr->label);
3262 qio_channel_set_name(QIO_CHANNEL(tioc), name);
3263 g_free(name);
a8fb5427
DB
3264 object_unref(OBJECT(s->ioc));
3265 s->ioc = QIO_CHANNEL(tioc);
3266
3267 qio_channel_tls_handshake(tioc,
3268 tcp_chr_tls_handshake,
3269 chr,
3270 NULL);
3271}
3272
3273
0ec7b3e7 3274static void tcp_chr_set_client_ioc_name(Chardev *chr,
e93a68e1
DB
3275 QIOChannelSocket *sioc)
3276{
777357d7 3277 SocketChardev *s = SOCKET_CHARDEV(chr);
e93a68e1
DB
3278 char *name;
3279 name = g_strdup_printf("chardev-tcp-%s-%s",
3280 s->is_listen ? "server" : "client",
3281 chr->label);
3282 qio_channel_set_name(QIO_CHANNEL(sioc), name);
3283 g_free(name);
3284
3285}
3286
0ec7b3e7 3287static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
13661089 3288{
777357d7 3289 SocketChardev *s = SOCKET_CHARDEV(chr);
41ac54b2 3290
9894dc0c 3291 if (s->ioc != NULL) {
13661089 3292 return -1;
9894dc0c 3293 }
13661089 3294
9894dc0c
DB
3295 s->ioc = QIO_CHANNEL(sioc);
3296 object_ref(OBJECT(sioc));
a8fb5427
DB
3297 s->sioc = sioc;
3298 object_ref(OBJECT(sioc));
9894dc0c 3299
64c800f8
DB
3300 qio_channel_set_blocking(s->ioc, false, NULL);
3301
9894dc0c
DB
3302 if (s->do_nodelay) {
3303 qio_channel_set_delay(s->ioc, false);
3304 }
910b6368
PB
3305 if (s->listen_tag) {
3306 g_source_remove(s->listen_tag);
3307 s->listen_tag = 0;
3308 }
f2001a7e 3309
a8fb5427
DB
3310 if (s->tls_creds) {
3311 tcp_chr_tls_init(chr);
f2001a7e 3312 } else {
a8fb5427
DB
3313 if (s->do_telnetopt) {
3314 tcp_chr_telnet_init(chr);
3315 } else {
3316 tcp_chr_connect(chr);
3317 }
f2001a7e 3318 }
13661089
DB
3319
3320 return 0;
3321}
3322
9894dc0c 3323
0ec7b3e7 3324static int tcp_chr_add_client(Chardev *chr, int fd)
9894dc0c
DB
3325{
3326 int ret;
3327 QIOChannelSocket *sioc;
3328
3329 sioc = qio_channel_socket_new_fd(fd, NULL);
3330 if (!sioc) {
3331 return -1;
3332 }
e93a68e1 3333 tcp_chr_set_client_ioc_name(chr, sioc);
9894dc0c
DB
3334 ret = tcp_chr_new_client(chr, sioc);
3335 object_unref(OBJECT(sioc));
3336 return ret;
3337}
3338
3339static gboolean tcp_chr_accept(QIOChannel *channel,
3340 GIOCondition cond,
3341 void *opaque)
6f97dba0 3342{
777357d7 3343 Chardev *chr = CHARDEV(opaque);
9894dc0c 3344 QIOChannelSocket *sioc;
6f97dba0 3345
9894dc0c
DB
3346 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(channel),
3347 NULL);
3348 if (!sioc) {
3349 return TRUE;
6f97dba0 3350 }
9894dc0c 3351
9894dc0c
DB
3352 tcp_chr_new_client(chr, sioc);
3353
3354 object_unref(OBJECT(sioc));
2ea5a7af
AL
3355
3356 return TRUE;
6f97dba0
AL
3357}
3358
0ec7b3e7 3359static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
d7a04fd7 3360{
777357d7 3361 SocketChardev *s = SOCKET_CHARDEV(chr);
d7a04fd7
MAL
3362 QIOChannelSocket *sioc;
3363
1dc8a669
MAL
3364 /* It can't wait on s->connected, since it is set asynchronously
3365 * in TLS and telnet cases, only wait for an accepted socket */
3366 while (!s->ioc) {
d7a04fd7 3367 if (s->is_listen) {
776a32a0
MAL
3368 error_report("QEMU waiting for connection on: %s",
3369 chr->filename);
d7a04fd7
MAL
3370 qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), true, NULL);
3371 tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr);
3372 qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL);
3373 } else {
3374 sioc = qio_channel_socket_new();
e93a68e1 3375 tcp_chr_set_client_ioc_name(chr, sioc);
d7a04fd7
MAL
3376 if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
3377 object_unref(OBJECT(sioc));
3378 return -1;
3379 }
3380 tcp_chr_new_client(chr, sioc);
3381 object_unref(OBJECT(sioc));
3382 }
3383 }
3384
3385 return 0;
3386}
3387
0ec7b3e7 3388static int qemu_chr_wait_connected(Chardev *chr, Error **errp)
6b6723c3 3389{
777357d7
MAL
3390 ChardevClass *cc = CHARDEV_GET_CLASS(chr);
3391
3392 if (cc->chr_wait_connected) {
3393 return cc->chr_wait_connected(chr, errp);
6b6723c3
MAL
3394 }
3395
3396 return 0;
3397}
3398
5345fdb4
MAL
3399int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp)
3400{
fa394ed6
MAL
3401 if (!be->chr) {
3402 error_setg(errp, "missing associated backend");
3403 return -1;
3404 }
3405
5345fdb4
MAL
3406 return qemu_chr_wait_connected(be->chr, errp);
3407}
3408
2c3a5dcb 3409static void char_socket_finalize(Object *obj)
6f97dba0 3410{
2c3a5dcb
MAL
3411 Chardev *chr = CHARDEV(obj);
3412 SocketChardev *s = SOCKET_CHARDEV(obj);
5b498459
MAL
3413
3414 tcp_chr_free_connection(chr);
cfb429cb 3415
5dd1f02b
CM
3416 if (s->reconnect_timer) {
3417 g_source_remove(s->reconnect_timer);
3418 s->reconnect_timer = 0;
3419 }
cfb429cb 3420 qapi_free_SocketAddress(s->addr);
9894dc0c
DB
3421 if (s->listen_tag) {
3422 g_source_remove(s->listen_tag);
3423 s->listen_tag = 0;
3424 }
3425 if (s->listen_ioc) {
3426 object_unref(OBJECT(s->listen_ioc));
819f56b7 3427 }
a8fb5427
DB
3428 if (s->tls_creds) {
3429 object_unref(OBJECT(s->tls_creds));
3430 }
41ac54b2 3431
a425d23f 3432 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
6f97dba0
AL
3433}
3434
43ded1a0 3435
60e705c5 3436static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
5dd1f02b 3437{
60e705c5 3438 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
777357d7
MAL
3439 Chardev *chr = CHARDEV(opaque);
3440 SocketChardev *s = SOCKET_CHARDEV(chr);
60e705c5 3441 Error *err = NULL;
5dd1f02b 3442
60e705c5 3443 if (qio_task_propagate_error(task, &err)) {
5008e5b7 3444 check_report_connect_error(chr, err);
60e705c5
DB
3445 error_free(err);
3446 goto cleanup;
5dd1f02b
CM
3447 }
3448
5008e5b7 3449 s->connect_err_reported = false;
f50dfe45 3450 tcp_chr_new_client(chr, sioc);
60e705c5
DB
3451
3452 cleanup:
f50dfe45 3453 object_unref(OBJECT(sioc));
5dd1f02b
CM
3454}
3455
f6bd5d6e 3456
51767e7c 3457/*********************************************************/
3949e594 3458/* Ring buffer chardev */
51767e7c
LL
3459
3460typedef struct {
0ec7b3e7 3461 Chardev parent;
51767e7c
LL
3462 size_t size;
3463 size_t prod;
3464 size_t cons;
3465 uint8_t *cbuf;
0ec7b3e7 3466} RingBufChardev;
51767e7c 3467
777357d7
MAL
3468#define RINGBUF_CHARDEV(obj) \
3469 OBJECT_CHECK(RingBufChardev, (obj), TYPE_CHARDEV_RINGBUF)
3470
0ec7b3e7 3471static size_t ringbuf_count(const Chardev *chr)
51767e7c 3472{
777357d7 3473 const RingBufChardev *d = RINGBUF_CHARDEV(chr);
51767e7c 3474
5c230105 3475 return d->prod - d->cons;
51767e7c
LL
3476}
3477
9005b2a7 3478/* Called with chr_write_lock held. */
0ec7b3e7 3479static int ringbuf_chr_write(Chardev *chr, const uint8_t *buf, int len)
51767e7c 3480{
777357d7 3481 RingBufChardev *d = RINGBUF_CHARDEV(chr);
51767e7c
LL
3482 int i;
3483
3484 if (!buf || (len < 0)) {
3485 return -1;
3486 }
3487
3488 for (i = 0; i < len; i++ ) {
5c230105
MA
3489 d->cbuf[d->prod++ & (d->size - 1)] = buf[i];
3490 if (d->prod - d->cons > d->size) {
51767e7c
LL
3491 d->cons = d->prod - d->size;
3492 }
3493 }
3494
5c936a83 3495 return len;
51767e7c
LL
3496}
3497
0ec7b3e7 3498static int ringbuf_chr_read(Chardev *chr, uint8_t *buf, int len)
51767e7c 3499{
777357d7 3500 RingBufChardev *d = RINGBUF_CHARDEV(chr);
51767e7c
LL
3501 int i;
3502
9005b2a7 3503 qemu_mutex_lock(&chr->chr_write_lock);
5c230105
MA
3504 for (i = 0; i < len && d->cons != d->prod; i++) {
3505 buf[i] = d->cbuf[d->cons++ & (d->size - 1)];
51767e7c 3506 }
9005b2a7 3507 qemu_mutex_unlock(&chr->chr_write_lock);
51767e7c
LL
3508
3509 return i;
3510}
3511
9fa2f7a4 3512static void char_ringbuf_finalize(Object *obj)
51767e7c 3513{
9fa2f7a4 3514 RingBufChardev *d = RINGBUF_CHARDEV(obj);
51767e7c
LL
3515
3516 g_free(d->cbuf);
51767e7c
LL
3517}
3518
777357d7
MAL
3519static void qemu_chr_open_ringbuf(Chardev *chr,
3520 ChardevBackend *backend,
3521 bool *be_opened,
3522 Error **errp)
51767e7c 3523{
32bafa8f 3524 ChardevRingbuf *opts = backend->u.ringbuf.data;
777357d7 3525 RingBufChardev *d = RINGBUF_CHARDEV(chr);
51767e7c 3526
1da48c65 3527 d->size = opts->has_size ? opts->size : 65536;
51767e7c
LL
3528
3529 /* The size must be power of 2 */
3530 if (d->size & (d->size - 1)) {
4f57378f 3531 error_setg(errp, "size of ringbuf chardev must be power of two");
777357d7 3532 return;
51767e7c
LL
3533 }
3534
3535 d->prod = 0;
3536 d->cons = 0;
3537 d->cbuf = g_malloc0(d->size);
1f590cf9
LL
3538}
3539
3949e594 3540void qmp_ringbuf_write(const char *device, const char *data,
82e59a67 3541 bool has_format, enum DataFormat format,
1f590cf9
LL
3542 Error **errp)
3543{
0ec7b3e7 3544 Chardev *chr;
c4f331b6 3545 const uint8_t *write_data;
1f590cf9 3546 int ret;
3d1bba20 3547 gsize write_count;
1f590cf9
LL
3548
3549 chr = qemu_chr_find(device);
3550 if (!chr) {
1a69278e 3551 error_setg(errp, "Device '%s' not found", device);
1f590cf9
LL
3552 return;
3553 }
3554
777357d7 3555 if (!CHARDEV_IS_RINGBUF(chr)) {
3949e594 3556 error_setg(errp,"%s is not a ringbuf device", device);
1f590cf9
LL
3557 return;
3558 }
3559
1f590cf9 3560 if (has_format && (format == DATA_FORMAT_BASE64)) {
e9cf2fe0
DB
3561 write_data = qbase64_decode(data, -1,
3562 &write_count,
3563 errp);
3564 if (!write_data) {
3565 return;
3566 }
1f590cf9
LL
3567 } else {
3568 write_data = (uint8_t *)data;
82e59a67 3569 write_count = strlen(data);
1f590cf9
LL
3570 }
3571
3949e594 3572 ret = ringbuf_chr_write(chr, write_data, write_count);
1f590cf9 3573
13289fb5
MA
3574 if (write_data != (uint8_t *)data) {
3575 g_free((void *)write_data);
3576 }
3577
1f590cf9
LL
3578 if (ret < 0) {
3579 error_setg(errp, "Failed to write to device %s", device);
3580 return;
3581 }
3582}
3583
3949e594 3584char *qmp_ringbuf_read(const char *device, int64_t size,
3ab651fc
MA
3585 bool has_format, enum DataFormat format,
3586 Error **errp)
49b6d722 3587{
0ec7b3e7 3588 Chardev *chr;
c4f331b6 3589 uint8_t *read_data;
49b6d722 3590 size_t count;
3ab651fc 3591 char *data;
49b6d722
LL
3592
3593 chr = qemu_chr_find(device);
3594 if (!chr) {
1a69278e 3595 error_setg(errp, "Device '%s' not found", device);
49b6d722
LL
3596 return NULL;
3597 }
3598
777357d7 3599 if (!CHARDEV_IS_RINGBUF(chr)) {
3949e594 3600 error_setg(errp,"%s is not a ringbuf device", device);
49b6d722
LL
3601 return NULL;
3602 }
3603
3604 if (size <= 0) {
3605 error_setg(errp, "size must be greater than zero");
3606 return NULL;
3607 }
3608
3949e594 3609 count = ringbuf_count(chr);
49b6d722 3610 size = size > count ? count : size;
44f3bcd2 3611 read_data = g_malloc(size + 1);
49b6d722 3612
3949e594 3613 ringbuf_chr_read(chr, read_data, size);
49b6d722
LL
3614
3615 if (has_format && (format == DATA_FORMAT_BASE64)) {
3ab651fc 3616 data = g_base64_encode(read_data, size);
13289fb5 3617 g_free(read_data);
49b6d722 3618 } else {
3949e594
MA
3619 /*
3620 * FIXME should read only complete, valid UTF-8 characters up
3621 * to @size bytes. Invalid sequences should be replaced by a
3622 * suitable replacement character. Except when (and only
3623 * when) ring buffer lost characters since last read, initial
3624 * continuation characters should be dropped.
3625 */
44f3bcd2 3626 read_data[size] = 0;
3ab651fc 3627 data = (char *)read_data;
49b6d722
LL
3628 }
3629
3ab651fc 3630 return data;
49b6d722
LL
3631}
3632
33521634 3633QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
191bc01b 3634{
6ea314d9 3635 char host[65], port[33], width[8], height[8];
aeb2c47a 3636 int pos;
7d31544f 3637 const char *p;
191bc01b 3638 QemuOpts *opts;
8be7e7e4 3639 Error *local_err = NULL;
191bc01b 3640
8be7e7e4 3641 opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
84d18f06 3642 if (local_err) {
33394884 3643 error_report_err(local_err);
191bc01b 3644 return NULL;
8be7e7e4 3645 }
191bc01b 3646
7591c5c1
GH
3647 if (strstart(filename, "mon:", &p)) {
3648 filename = p;
f43e47db 3649 qemu_opt_set(opts, "mux", "on", &error_abort);
02c4bdf1
PB
3650 if (strcmp(filename, "stdio") == 0) {
3651 /* Monitor is muxed to stdio: do not exit on Ctrl+C by default
3652 * but pass it to the guest. Handle this only for compat syntax,
3653 * for -chardev syntax we have special option for this.
3654 * This is what -nographic did, redirecting+muxing serial+monitor
3655 * to stdio causing Ctrl+C to be passed to guest. */
f43e47db 3656 qemu_opt_set(opts, "signal", "off", &error_abort);
02c4bdf1 3657 }
7591c5c1
GH
3658 }
3659
f0457e8d
GH
3660 if (strcmp(filename, "null") == 0 ||
3661 strcmp(filename, "pty") == 0 ||
3662 strcmp(filename, "msmouse") == 0 ||
dc1c21e6 3663 strcmp(filename, "braille") == 0 ||
5692399f 3664 strcmp(filename, "testdev") == 0 ||
f0457e8d 3665 strcmp(filename, "stdio") == 0) {
f43e47db 3666 qemu_opt_set(opts, "backend", filename, &error_abort);
191bc01b
GH
3667 return opts;
3668 }
6ea314d9 3669 if (strstart(filename, "vc", &p)) {
f43e47db 3670 qemu_opt_set(opts, "backend", "vc", &error_abort);
6ea314d9 3671 if (*p == ':') {
49aa4058 3672 if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
6ea314d9 3673 /* pixels */
f43e47db
MA
3674 qemu_opt_set(opts, "width", width, &error_abort);
3675 qemu_opt_set(opts, "height", height, &error_abort);
49aa4058 3676 } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
6ea314d9 3677 /* chars */
f43e47db
MA
3678 qemu_opt_set(opts, "cols", width, &error_abort);
3679 qemu_opt_set(opts, "rows", height, &error_abort);
6ea314d9
GH
3680 } else {
3681 goto fail;
3682 }
3683 }
3684 return opts;
3685 }
d6c983cd 3686 if (strcmp(filename, "con:") == 0) {
f43e47db 3687 qemu_opt_set(opts, "backend", "console", &error_abort);
d6c983cd
GH
3688 return opts;
3689 }
48b76496 3690 if (strstart(filename, "COM", NULL)) {
f43e47db
MA
3691 qemu_opt_set(opts, "backend", "serial", &error_abort);
3692 qemu_opt_set(opts, "path", filename, &error_abort);
48b76496
GH
3693 return opts;
3694 }
7d31544f 3695 if (strstart(filename, "file:", &p)) {
f43e47db
MA
3696 qemu_opt_set(opts, "backend", "file", &error_abort);
3697 qemu_opt_set(opts, "path", p, &error_abort);
7d31544f
GH
3698 return opts;
3699 }
3700 if (strstart(filename, "pipe:", &p)) {
f43e47db
MA
3701 qemu_opt_set(opts, "backend", "pipe", &error_abort);
3702 qemu_opt_set(opts, "path", p, &error_abort);
7d31544f
GH
3703 return opts;
3704 }
aeb2c47a
GH
3705 if (strstart(filename, "tcp:", &p) ||
3706 strstart(filename, "telnet:", &p)) {
3707 if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
3708 host[0] = 0;
3709 if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
3710 goto fail;
3711 }
f43e47db
MA
3712 qemu_opt_set(opts, "backend", "socket", &error_abort);
3713 qemu_opt_set(opts, "host", host, &error_abort);
3714 qemu_opt_set(opts, "port", port, &error_abort);
aeb2c47a 3715 if (p[pos] == ',') {
dc523cd3
MA
3716 qemu_opts_do_parse(opts, p+pos+1, NULL, &local_err);
3717 if (local_err) {
3718 error_report_err(local_err);
aeb2c47a 3719 goto fail;
dc523cd3 3720 }
aeb2c47a
GH
3721 }
3722 if (strstart(filename, "telnet:", &p))
f43e47db 3723 qemu_opt_set(opts, "telnet", "on", &error_abort);
aeb2c47a
GH
3724 return opts;
3725 }
7e1b35b4 3726 if (strstart(filename, "udp:", &p)) {
f43e47db 3727 qemu_opt_set(opts, "backend", "udp", &error_abort);
7e1b35b4
GH
3728 if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
3729 host[0] = 0;
39324ca4 3730 if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
7e1b35b4
GH
3731 goto fail;
3732 }
3733 }
f43e47db
MA
3734 qemu_opt_set(opts, "host", host, &error_abort);
3735 qemu_opt_set(opts, "port", port, &error_abort);
7e1b35b4
GH
3736 if (p[pos] == '@') {
3737 p += pos + 1;
3738 if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
3739 host[0] = 0;
3740 if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
7e1b35b4
GH
3741 goto fail;
3742 }
3743 }
f43e47db
MA
3744 qemu_opt_set(opts, "localaddr", host, &error_abort);
3745 qemu_opt_set(opts, "localport", port, &error_abort);
7e1b35b4
GH
3746 }
3747 return opts;
3748 }
aeb2c47a 3749 if (strstart(filename, "unix:", &p)) {
f43e47db 3750 qemu_opt_set(opts, "backend", "socket", &error_abort);
dc523cd3
MA
3751 qemu_opts_do_parse(opts, p, "path", &local_err);
3752 if (local_err) {
3753 error_report_err(local_err);
aeb2c47a 3754 goto fail;
dc523cd3 3755 }
aeb2c47a
GH
3756 return opts;
3757 }
48b76496
GH
3758 if (strstart(filename, "/dev/parport", NULL) ||
3759 strstart(filename, "/dev/ppi", NULL)) {
f43e47db
MA
3760 qemu_opt_set(opts, "backend", "parport", &error_abort);
3761 qemu_opt_set(opts, "path", filename, &error_abort);
48b76496
GH
3762 return opts;
3763 }
3764 if (strstart(filename, "/dev/", NULL)) {
f43e47db
MA
3765 qemu_opt_set(opts, "backend", "tty", &error_abort);
3766 qemu_opt_set(opts, "path", filename, &error_abort);
48b76496
GH
3767 return opts;
3768 }
191bc01b 3769
aeb2c47a 3770fail:
191bc01b
GH
3771 qemu_opts_del(opts);
3772 return NULL;
3773}
3774
21a933ea 3775void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
d0d7708b
DB
3776{
3777 const char *logfile = qemu_opt_get(opts, "logfile");
3778
3779 backend->has_logfile = logfile != NULL;
3780 backend->logfile = logfile ? g_strdup(logfile) : NULL;
3781
3782 backend->has_logappend = true;
3783 backend->logappend = qemu_opt_get_bool(opts, "logappend", false);
3784}
3785
3786
846e2e49
GH
3787static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
3788 Error **errp)
3789{
3790 const char *path = qemu_opt_get(opts, "path");
f194a1ae 3791 ChardevFile *file;
846e2e49 3792
0b663b7d 3793 backend->type = CHARDEV_BACKEND_KIND_FILE;
846e2e49
GH
3794 if (path == NULL) {
3795 error_setg(errp, "chardev: file: no filename given");
3796 return;
3797 }
32bafa8f 3798 file = backend->u.file.data = g_new0(ChardevFile, 1);
f194a1ae
EB
3799 qemu_chr_parse_common(opts, qapi_ChardevFile_base(file));
3800 file->out = g_strdup(path);
31e38a22 3801
f194a1ae
EB
3802 file->has_append = true;
3803 file->append = qemu_opt_get_bool(opts, "append", false);
846e2e49
GH
3804}
3805
7c358031
GH
3806static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
3807 Error **errp)
3808{
f194a1ae
EB
3809 ChardevStdio *stdio;
3810
0b663b7d 3811 backend->type = CHARDEV_BACKEND_KIND_STDIO;
32bafa8f 3812 stdio = backend->u.stdio.data = g_new0(ChardevStdio, 1);
f194a1ae
EB
3813 qemu_chr_parse_common(opts, qapi_ChardevStdio_base(stdio));
3814 stdio->has_signal = true;
3815 stdio->signal = qemu_opt_get_bool(opts, "signal", true);
7c358031
GH
3816}
3817
777357d7
MAL
3818static void char_stdio_class_init(ObjectClass *oc, void *data)
3819{
3820 ChardevClass *cc = CHARDEV_CLASS(oc);
3821
88cace9f 3822 cc->parse = qemu_chr_parse_stdio;
777357d7 3823 cc->open = qemu_chr_open_stdio;
b68e956a 3824#ifdef _WIN32
777357d7
MAL
3825 cc->chr_write = win_stdio_write;
3826 cc->chr_set_echo = qemu_chr_set_echo_win_stdio;
b68e956a 3827#else
777357d7 3828 cc->chr_set_echo = qemu_chr_set_echo_stdio;
b68e956a 3829#endif
777357d7
MAL
3830}
3831
3832static const TypeInfo char_stdio_type_info = {
3833 .name = TYPE_CHARDEV_STDIO,
3834#ifdef _WIN32
3835 .parent = TYPE_CHARDEV_WIN_STDIO,
3836#else
3837 .parent = TYPE_CHARDEV_FD,
4d833ada 3838 .instance_finalize = char_stdio_finalize,
777357d7
MAL
3839#endif
3840 .class_init = char_stdio_class_init,
b68e956a
MAL
3841};
3842
6511d396 3843#ifdef HAVE_CHARDEV_SERIAL
0f1cb51d
GH
3844static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
3845 Error **errp)
3846{
3847 const char *device = qemu_opt_get(opts, "path");
f194a1ae 3848 ChardevHostdev *serial;
0f1cb51d 3849
0b663b7d 3850 backend->type = CHARDEV_BACKEND_KIND_SERIAL;
0f1cb51d
GH
3851 if (device == NULL) {
3852 error_setg(errp, "chardev: serial/tty: no device path given");
3853 return;
3854 }
32bafa8f 3855 serial = backend->u.serial.data = g_new0(ChardevHostdev, 1);
f194a1ae
EB
3856 qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial));
3857 serial->device = g_strdup(device);
0f1cb51d 3858}
6511d396 3859#endif
0f1cb51d 3860
38bfb1a6 3861#ifdef HAVE_CHARDEV_PARPORT
dc375097
GH
3862static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
3863 Error **errp)
3864{
3865 const char *device = qemu_opt_get(opts, "path");
f194a1ae 3866 ChardevHostdev *parallel;
dc375097 3867
0b663b7d 3868 backend->type = CHARDEV_BACKEND_KIND_PARALLEL;
dc375097
GH
3869 if (device == NULL) {
3870 error_setg(errp, "chardev: parallel: no device path given");
3871 return;
3872 }
32bafa8f 3873 parallel = backend->u.parallel.data = g_new0(ChardevHostdev, 1);
f194a1ae
EB
3874 qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(parallel));
3875 parallel->device = g_strdup(device);
dc375097 3876}
38bfb1a6 3877#endif
dc375097 3878
548cbb36
GH
3879static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
3880 Error **errp)
3881{
3882 const char *device = qemu_opt_get(opts, "path");
f194a1ae 3883 ChardevHostdev *dev;
548cbb36 3884
0b663b7d 3885 backend->type = CHARDEV_BACKEND_KIND_PIPE;
548cbb36
GH
3886 if (device == NULL) {
3887 error_setg(errp, "chardev: pipe: no device path given");
3888 return;
3889 }
32bafa8f 3890 dev = backend->u.pipe.data = g_new0(ChardevHostdev, 1);
f194a1ae
EB
3891 qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(dev));
3892 dev->device = g_strdup(device);
548cbb36
GH
3893}
3894
777357d7
MAL
3895static void char_pipe_class_init(ObjectClass *oc, void *data)
3896{
3897 ChardevClass *cc = CHARDEV_CLASS(oc);
3898
88cace9f 3899 cc->parse = qemu_chr_parse_pipe;
777357d7
MAL
3900 cc->open = qemu_chr_open_pipe;
3901}
3902
3903static const TypeInfo char_pipe_type_info = {
3904 .name = TYPE_CHARDEV_PIPE,
b68e956a 3905#ifdef _WIN32
777357d7 3906 .parent = TYPE_CHARDEV_WIN,
b68e956a 3907#else
777357d7 3908 .parent = TYPE_CHARDEV_FD,
b68e956a 3909#endif
777357d7 3910 .class_init = char_pipe_class_init,
b68e956a
MAL
3911};
3912
4f57378f
MA
3913static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
3914 Error **errp)
1da48c65
GH
3915{
3916 int val;
f194a1ae 3917 ChardevRingbuf *ringbuf;
1da48c65 3918
0b663b7d 3919 backend->type = CHARDEV_BACKEND_KIND_RINGBUF;
32bafa8f 3920 ringbuf = backend->u.ringbuf.data = g_new0(ChardevRingbuf, 1);
f194a1ae 3921 qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(ringbuf));
1da48c65 3922
0f953051 3923 val = qemu_opt_get_size(opts, "size", 0);
1da48c65 3924 if (val != 0) {
f194a1ae
EB
3925 ringbuf->has_size = true;
3926 ringbuf->size = val;
1da48c65
GH
3927 }
3928}
3929
777357d7
MAL
3930static void char_ringbuf_class_init(ObjectClass *oc, void *data)
3931{
3932 ChardevClass *cc = CHARDEV_CLASS(oc);
3933
88cace9f 3934 cc->parse = qemu_chr_parse_ringbuf;
777357d7
MAL
3935 cc->open = qemu_chr_open_ringbuf;
3936 cc->chr_write = ringbuf_chr_write;
777357d7
MAL
3937}
3938
3939static const TypeInfo char_ringbuf_type_info = {
3940 .name = TYPE_CHARDEV_RINGBUF,
3941 .parent = TYPE_CHARDEV,
3942 .class_init = char_ringbuf_class_init,
3943 .instance_size = sizeof(RingBufChardev),
9fa2f7a4 3944 .instance_finalize = char_ringbuf_finalize,
b68e956a
MAL
3945};
3946
3947/* Bug-compatibility: */
777357d7
MAL
3948static const TypeInfo char_memory_type_info = {
3949 .name = TYPE_CHARDEV_MEMORY,
3950 .parent = TYPE_CHARDEV_RINGBUF,
b68e956a
MAL
3951};
3952
bb6fb7c0
GH
3953static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
3954 Error **errp)
3955{
3956 const char *chardev = qemu_opt_get(opts, "chardev");
f194a1ae 3957 ChardevMux *mux;
bb6fb7c0 3958
0b663b7d 3959 backend->type = CHARDEV_BACKEND_KIND_MUX;
bb6fb7c0
GH
3960 if (chardev == NULL) {
3961 error_setg(errp, "chardev: mux: no chardev given");
3962 return;
3963 }
32bafa8f 3964 mux = backend->u.mux.data = g_new0(ChardevMux, 1);
f194a1ae
EB
3965 qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux));
3966 mux->chardev = g_strdup(chardev);
bb6fb7c0
GH
3967}
3968
777357d7
MAL
3969static void char_mux_class_init(ObjectClass *oc, void *data)
3970{
3971 ChardevClass *cc = CHARDEV_CLASS(oc);
3972
88cace9f 3973 cc->parse = qemu_chr_parse_mux;
777357d7 3974 cc->open = qemu_chr_open_mux;
777357d7
MAL
3975 cc->chr_write = mux_chr_write;
3976 cc->chr_accept_input = mux_chr_accept_input;
3977 cc->chr_add_watch = mux_chr_add_watch;
3978}
3979
3980static const TypeInfo char_mux_type_info = {
3981 .name = TYPE_CHARDEV_MUX,
3982 .parent = TYPE_CHARDEV,
3983 .class_init = char_mux_class_init,
3984 .instance_size = sizeof(MuxChardev),
980d0414 3985 .instance_finalize = char_mux_finalize,
b68e956a
MAL
3986};
3987
dafd325d
PM
3988static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
3989 Error **errp)
3990{
3991 bool is_listen = qemu_opt_get_bool(opts, "server", false);
3992 bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
3993 bool is_telnet = qemu_opt_get_bool(opts, "telnet", false);
3994 bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true);
5dd1f02b 3995 int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0);
dafd325d
PM
3996 const char *path = qemu_opt_get(opts, "path");
3997 const char *host = qemu_opt_get(opts, "host");
3998 const char *port = qemu_opt_get(opts, "port");
a8fb5427 3999 const char *tls_creds = qemu_opt_get(opts, "tls-creds");
dafd325d 4000 SocketAddress *addr;
f194a1ae 4001 ChardevSocket *sock;
dafd325d 4002
0b663b7d 4003 backend->type = CHARDEV_BACKEND_KIND_SOCKET;
dafd325d
PM
4004 if (!path) {
4005 if (!host) {
4006 error_setg(errp, "chardev: socket: no host given");
4007 return;
4008 }
4009 if (!port) {
4010 error_setg(errp, "chardev: socket: no port given");
4011 return;
4012 }
a8fb5427
DB
4013 } else {
4014 if (tls_creds) {
4015 error_setg(errp, "TLS can only be used over TCP socket");
4016 return;
4017 }
dafd325d
PM
4018 }
4019
32bafa8f 4020 sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
f194a1ae 4021 qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
dafd325d 4022
f194a1ae
EB
4023 sock->has_nodelay = true;
4024 sock->nodelay = do_nodelay;
4025 sock->has_server = true;
4026 sock->server = is_listen;
4027 sock->has_telnet = true;
4028 sock->telnet = is_telnet;
4029 sock->has_wait = true;
4030 sock->wait = is_waitconnect;
4031 sock->has_reconnect = true;
4032 sock->reconnect = reconnect;
4033 sock->tls_creds = g_strdup(tls_creds);
dafd325d
PM
4034
4035 addr = g_new0(SocketAddress, 1);
4036 if (path) {
0399293e 4037 UnixSocketAddress *q_unix;
130257dc 4038 addr->type = SOCKET_ADDRESS_KIND_UNIX;
32bafa8f 4039 q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
0399293e 4040 q_unix->path = g_strdup(path);
dafd325d 4041 } else {
130257dc 4042 addr->type = SOCKET_ADDRESS_KIND_INET;
32bafa8f
EB
4043 addr->u.inet.data = g_new(InetSocketAddress, 1);
4044 *addr->u.inet.data = (InetSocketAddress) {
0399293e
EB
4045 .host = g_strdup(host),
4046 .port = g_strdup(port),
4047 .has_to = qemu_opt_get(opts, "to"),
4048 .to = qemu_opt_get_number(opts, "to", 0),
4049 .has_ipv4 = qemu_opt_get(opts, "ipv4"),
4050 .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
4051 .has_ipv6 = qemu_opt_get(opts, "ipv6"),
4052 .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
4053 };
dafd325d 4054 }
f194a1ae 4055 sock->addr = addr;
dafd325d
PM
4056}
4057
90a14bfe
PM
4058static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
4059 Error **errp)
4060{
4061 const char *host = qemu_opt_get(opts, "host");
4062 const char *port = qemu_opt_get(opts, "port");
4063 const char *localaddr = qemu_opt_get(opts, "localaddr");
4064 const char *localport = qemu_opt_get(opts, "localport");
4065 bool has_local = false;
4066 SocketAddress *addr;
f194a1ae 4067 ChardevUdp *udp;
90a14bfe 4068
0b663b7d 4069 backend->type = CHARDEV_BACKEND_KIND_UDP;
90a14bfe
PM
4070 if (host == NULL || strlen(host) == 0) {
4071 host = "localhost";
4072 }
4073 if (port == NULL || strlen(port) == 0) {
4074 error_setg(errp, "chardev: udp: remote port not specified");
4075 return;
4076 }
4077 if (localport == NULL || strlen(localport) == 0) {
4078 localport = "0";
4079 } else {
4080 has_local = true;
4081 }
4082 if (localaddr == NULL || strlen(localaddr) == 0) {
4083 localaddr = "";
4084 } else {
4085 has_local = true;
4086 }
4087
32bafa8f 4088 udp = backend->u.udp.data = g_new0(ChardevUdp, 1);
f194a1ae 4089 qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp));
90a14bfe
PM
4090
4091 addr = g_new0(SocketAddress, 1);
130257dc 4092 addr->type = SOCKET_ADDRESS_KIND_INET;
32bafa8f
EB
4093 addr->u.inet.data = g_new(InetSocketAddress, 1);
4094 *addr->u.inet.data = (InetSocketAddress) {
0399293e
EB
4095 .host = g_strdup(host),
4096 .port = g_strdup(port),
4097 .has_ipv4 = qemu_opt_get(opts, "ipv4"),
4098 .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
4099 .has_ipv6 = qemu_opt_get(opts, "ipv6"),
4100 .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
4101 };
f194a1ae 4102 udp->remote = addr;
90a14bfe
PM
4103
4104 if (has_local) {
f194a1ae 4105 udp->has_local = true;
90a14bfe 4106 addr = g_new0(SocketAddress, 1);
130257dc 4107 addr->type = SOCKET_ADDRESS_KIND_INET;
32bafa8f
EB
4108 addr->u.inet.data = g_new(InetSocketAddress, 1);
4109 *addr->u.inet.data = (InetSocketAddress) {
0399293e
EB
4110 .host = g_strdup(localaddr),
4111 .port = g_strdup(localport),
4112 };
f194a1ae 4113 udp->local = addr;
90a14bfe
PM
4114 }
4115}
4116
88cace9f
MAL
4117static const ChardevClass *char_get_class(const char *driver, Error **errp)
4118{
4119 ObjectClass *oc;
4120 const ChardevClass *cc;
4121 char *typename = g_strdup_printf("chardev-%s", driver);
4122
4123 oc = object_class_by_name(typename);
4124 g_free(typename);
4125
4126 if (!object_class_dynamic_cast(oc, TYPE_CHARDEV)) {
4127 error_setg(errp, "'%s' is not a valid char driver name", driver);
4128 return NULL;
4129 }
d654f34e 4130
88cace9f
MAL
4131 if (object_class_is_abstract(oc)) {
4132 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
4133 "abstract device type");
4134 return NULL;
4135 }
4136
4137 cc = CHARDEV_CLASS(oc);
4138 if (cc->internal) {
4139 error_setg(errp, "'%s' is not a valid char driver name", driver);
4140 return NULL;
4141 }
4142
4143 return cc;
4144}
4145
0b663b7d
MAL
4146static Chardev *qemu_chardev_add(const char *id, const char *typename,
4147 ChardevBackend *backend, Error **errp)
4148{
4149 Chardev *chr;
4150
4151 chr = qemu_chr_find(id);
4152 if (chr) {
4153 error_setg(errp, "Chardev '%s' already exists", id);
4154 return NULL;
4155 }
4156
4157 chr = qemu_chardev_new(id, typename, backend, errp);
4158 if (!chr) {
4159 return NULL;
4160 }
4161
4162 QTAILQ_INSERT_TAIL(&chardevs, chr, next);
4163 return chr;
4164}
4165
88cace9f
MAL
4166static const struct ChardevAlias {
4167 const char *typename;
4168 const char *alias;
4169} chardev_alias_table[] = {
4170#ifdef HAVE_CHARDEV_PARPORT
4171 { "parallel", "parport" },
4172#endif
4173#ifdef HAVE_CHARDEV_SERIAL
4174 { "serial", "tty" },
4175#endif
4176};
4177
4178typedef struct ChadevClassFE {
4179 void (*fn)(const char *name, void *opaque);
4180 void *opaque;
4181} ChadevClassFE;
4182
4183static void
4184chardev_class_foreach(ObjectClass *klass, void *opaque)
2c5f4882 4185{
88cace9f
MAL
4186 ChadevClassFE *fe = opaque;
4187
4188 assert(g_str_has_prefix(object_class_get_name(klass), "chardev-"));
4189 if (CHARDEV_CLASS(klass)->internal) {
4190 return;
4191 }
4192
4193 fe->fn(object_class_get_name(klass) + 8, fe->opaque);
4194}
4195
4196static void
4197chardev_name_foreach(void (*fn)(const char *name, void *opaque), void *opaque)
4198{
4199 ChadevClassFE fe = { .fn = fn, .opaque = opaque };
4200 int i;
4201
4202 object_class_foreach(chardev_class_foreach, TYPE_CHARDEV, false, &fe);
4203
4204 for (i = 0; i < ARRAY_SIZE(chardev_alias_table); i++) {
4205 fn(chardev_alias_table[i].alias, opaque);
4206 }
4207}
4208
4209static void
4210help_string_append(const char *name, void *opaque)
4211{
4212 GString *str = opaque;
4213
4214 g_string_append_printf(str, "\n%s", name);
2c5f4882
GH
4215}
4216
0ec7b3e7
MAL
4217Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
4218 Error **errp)
191bc01b 4219{
0aff637e 4220 Error *local_err = NULL;
88cace9f 4221 const ChardevClass *cc;
0ec7b3e7 4222 Chardev *chr;
a1698bf1 4223 int i;
0b663b7d 4224 ChardevBackend *backend = NULL;
0b812f31 4225 const char *name = qemu_opt_get(opts, "backend");
a61ae7f8
PM
4226 const char *id = qemu_opts_id(opts);
4227 char *bid = NULL;
191bc01b 4228
0b812f31 4229 if (name == NULL) {
312fd5f2 4230 error_setg(errp, "chardev: \"%s\" missing backend",
bd2d80b2 4231 qemu_opts_id(opts));
0b663b7d 4232 return NULL;
1bbd185f 4233 }
517b3d40 4234
0b812f31 4235 if (is_help_option(name)) {
776a32a0 4236 GString *str = g_string_new("");
88cace9f
MAL
4237
4238 chardev_name_foreach(help_string_append, str);
776a32a0
MAL
4239
4240 error_report("Available chardev backend types: %s", str->str);
4241 g_string_free(str, true);
0b812f31 4242 exit(0);
517b3d40
LM
4243 }
4244
4245 if (id == NULL) {
4246 error_setg(errp, "chardev: no id specified");
0b663b7d 4247 return NULL;
517b3d40
LM
4248 }
4249
88cace9f
MAL
4250 for (i = 0; i < ARRAY_SIZE(chardev_alias_table); i++) {
4251 if (g_strcmp0(chardev_alias_table[i].alias, name) == 0) {
4252 name = chardev_alias_table[i].typename;
191bc01b 4253 break;
d654f34e 4254 }
191bc01b 4255 }
88cace9f
MAL
4256
4257 cc = char_get_class(name, errp);
4258 if (cc == NULL) {
0b663b7d 4259 return NULL;
191bc01b
GH
4260 }
4261
a61ae7f8 4262 backend = g_new0(ChardevBackend, 1);
0b663b7d 4263 backend->type = CHARDEV_BACKEND_KIND_NULL;
edb2fb3c 4264
a61ae7f8
PM
4265 if (qemu_opt_get_bool(opts, "mux", 0)) {
4266 bid = g_strdup_printf("%s-base", id);
4267 }
2c5f4882 4268
a61ae7f8 4269 chr = NULL;
88cace9f
MAL
4270 if (cc->parse) {
4271 cc->parse(opts, backend, &local_err);
a61ae7f8
PM
4272 if (local_err) {
4273 error_propagate(errp, local_err);
0b663b7d 4274 goto out;
2c5f4882 4275 }
d0d7708b 4276 } else {
88cace9f
MAL
4277 ChardevCommon *ccom = g_new0(ChardevCommon, 1);
4278 qemu_chr_parse_common(opts, ccom);
4279 backend->u.null.data = ccom; /* Any ChardevCommon member would work */
2c5f4882 4280 }
d0d7708b 4281
0b663b7d
MAL
4282 chr = qemu_chardev_add(bid ? bid : id,
4283 object_class_get_name(OBJECT_CLASS(cc)),
4284 backend, errp);
4285 if (chr == NULL) {
4286 goto out;
191bc01b
GH
4287 }
4288
a61ae7f8 4289 if (bid) {
0b663b7d 4290 Chardev *mux;
a61ae7f8 4291 qapi_free_ChardevBackend(backend);
a61ae7f8 4292 backend = g_new0(ChardevBackend, 1);
130257dc 4293 backend->type = CHARDEV_BACKEND_KIND_MUX;
0b663b7d 4294 backend->u.mux.data = g_new0(ChardevMux, 1);
32bafa8f 4295 backend->u.mux.data->chardev = g_strdup(bid);
0b663b7d
MAL
4296 mux = qemu_chardev_add(id, TYPE_CHARDEV_MUX, backend, errp);
4297 if (mux == NULL) {
a61ae7f8
PM
4298 qemu_chr_delete(chr);
4299 chr = NULL;
0b663b7d 4300 goto out;
a61ae7f8 4301 }
0b663b7d 4302 chr = mux;
bd5c51ee 4303 }
7591c5c1 4304
0b663b7d 4305out:
a61ae7f8 4306 qapi_free_ChardevBackend(backend);
a61ae7f8 4307 g_free(bid);
191bc01b
GH
4308 return chr;
4309}
4310
0ec7b3e7 4311Chardev *qemu_chr_new_noreplay(const char *label, const char *filename)
6f97dba0
AL
4312{
4313 const char *p;
0ec7b3e7 4314 Chardev *chr;
191bc01b 4315 QemuOpts *opts;
bd2d80b2 4316 Error *err = NULL;
191bc01b 4317
c845f401
GH
4318 if (strstart(filename, "chardev:", &p)) {
4319 return qemu_chr_find(p);
4320 }
4321
191bc01b 4322 opts = qemu_chr_parse_compat(label, filename);
7e1b35b4
GH
4323 if (!opts)
4324 return NULL;
6f97dba0 4325
b4948be9 4326 chr = qemu_chr_new_from_opts(opts, &err);
84d18f06 4327 if (err) {
565f65d2 4328 error_report_err(err);
bd2d80b2 4329 }
7e1b35b4
GH
4330 if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
4331 monitor_init(chr, MONITOR_USE_READLINE);
6f97dba0 4332 }
0a73336d 4333 qemu_opts_del(opts);
6f97dba0
AL
4334 return chr;
4335}
4336
0ec7b3e7 4337Chardev *qemu_chr_new(const char *label, const char *filename)
33577b47 4338{
0ec7b3e7 4339 Chardev *chr;
b4948be9 4340 chr = qemu_chr_new_noreplay(label, filename);
33577b47 4341 if (chr) {
5ebd6703
MAL
4342 if (replay_mode != REPLAY_MODE_NONE) {
4343 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
4344 }
777357d7 4345 if (qemu_chr_replay(chr) && CHARDEV_GET_CLASS(chr)->chr_ioctl) {
776a32a0
MAL
4346 error_report("Replay: ioctl is not supported "
4347 "for serial devices yet");
33577b47
PD
4348 }
4349 replay_register_char_driver(chr);
4350 }
4351 return chr;
4352}
4353
5345fdb4 4354void qemu_chr_fe_set_echo(CharBackend *be, bool echo)
c48855e1 4355{
0ec7b3e7 4356 Chardev *chr = be->chr;
5345fdb4 4357
777357d7
MAL
4358 if (chr && CHARDEV_GET_CLASS(chr)->chr_set_echo) {
4359 CHARDEV_GET_CLASS(chr)->chr_set_echo(chr, echo);
c48855e1
PB
4360 }
4361}
4362
5345fdb4 4363void qemu_chr_fe_set_open(CharBackend *be, int fe_open)
7c32c4fe 4364{
0ec7b3e7 4365 Chardev *chr = be->chr;
5345fdb4 4366
fa394ed6
MAL
4367 if (!chr) {
4368 return;
4369 }
4370
830896af 4371 if (be->fe_open == fe_open) {
c0c4bd2c
HG
4372 return;
4373 }
830896af 4374 be->fe_open = fe_open;
777357d7
MAL
4375 if (CHARDEV_GET_CLASS(chr)->chr_set_fe_open) {
4376 CHARDEV_GET_CLASS(chr)->chr_set_fe_open(chr, fe_open);
7c32c4fe
HG
4377 }
4378}
4379
5345fdb4 4380guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
6f1de6b7 4381 GIOFunc func, void *user_data)
23673ca7 4382{
0ec7b3e7 4383 Chardev *s = be->chr;
23673ca7
AL
4384 GSource *src;
4385 guint tag;
4386
777357d7 4387 if (!s || CHARDEV_GET_CLASS(s)->chr_add_watch == NULL) {
6f1de6b7 4388 return 0;
23673ca7
AL
4389 }
4390
777357d7 4391 src = CHARDEV_GET_CLASS(s)->chr_add_watch(s, cond);
62c339c5 4392 if (!src) {
6f1de6b7 4393 return 0;
62c339c5
PB
4394 }
4395
23673ca7
AL
4396 g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
4397 tag = g_source_attach(src, NULL);
4398 g_source_unref(src);
4399
4400 return tag;
4401}
4402
5345fdb4 4403void qemu_chr_fe_disconnect(CharBackend *be)
7d9d17f7 4404{
0ec7b3e7 4405 Chardev *chr = be->chr;
5345fdb4 4406
777357d7
MAL
4407 if (chr && CHARDEV_GET_CLASS(chr)->chr_disconnect) {
4408 CHARDEV_GET_CLASS(chr)->chr_disconnect(chr);
7d9d17f7
TM
4409 }
4410}
4411
0ec7b3e7 4412void qemu_chr_delete(Chardev *chr)
1ad78ea5
MAL
4413{
4414 QTAILQ_REMOVE(&chardevs, chr, next);
8cddc469 4415 object_unref(OBJECT(chr));
1ad78ea5
MAL
4416}
4417
c5a415a0 4418ChardevInfoList *qmp_query_chardev(Error **errp)
6f97dba0 4419{
c5a415a0 4420 ChardevInfoList *chr_list = NULL;
0ec7b3e7 4421 Chardev *chr;
6f97dba0 4422
72cf2d4f 4423 QTAILQ_FOREACH(chr, &chardevs, next) {
c5a415a0
LC
4424 ChardevInfoList *info = g_malloc0(sizeof(*info));
4425 info->value = g_malloc0(sizeof(*info->value));
4426 info->value->label = g_strdup(chr->label);
4427 info->value->filename = g_strdup(chr->filename);
830896af 4428 info->value->frontend_open = chr->be && chr->be->fe_open;
c5a415a0
LC
4429
4430 info->next = chr_list;
4431 chr_list = info;
6f97dba0 4432 }
588b3832 4433
c5a415a0 4434 return chr_list;
6f97dba0 4435}
c845f401 4436
88cace9f
MAL
4437static void
4438qmp_prepend_backend(const char *name, void *opaque)
0b812f31 4439{
88cace9f 4440 ChardevBackendInfoList **list = opaque;
0b812f31 4441 ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
88cace9f 4442
0b812f31
MAL
4443 info->value = g_malloc0(sizeof(*info->value));
4444 info->value->name = g_strdup(name);
88cace9f
MAL
4445 info->next = *list;
4446 *list = info;
0b812f31
MAL
4447}
4448
77d1c3c6
MK
4449ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
4450{
4451 ChardevBackendInfoList *backend_list = NULL;
a1698bf1 4452
88cace9f 4453 chardev_name_foreach(qmp_prepend_backend, &backend_list);
77d1c3c6
MK
4454
4455 return backend_list;
4456}
4457
0ec7b3e7 4458Chardev *qemu_chr_find(const char *name)
c845f401 4459{
0ec7b3e7 4460 Chardev *chr;
c845f401 4461
72cf2d4f 4462 QTAILQ_FOREACH(chr, &chardevs, next) {
c845f401
GH
4463 if (strcmp(chr->label, name) != 0)
4464 continue;
4465 return chr;
4466 }
4467 return NULL;
4468}
0beb4942 4469
4d454574
PB
4470QemuOptsList qemu_chardev_opts = {
4471 .name = "chardev",
4472 .implied_opt_name = "backend",
4473 .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
4474 .desc = {
4475 {
4476 .name = "backend",
4477 .type = QEMU_OPT_STRING,
4478 },{
4479 .name = "path",
4480 .type = QEMU_OPT_STRING,
4481 },{
4482 .name = "host",
4483 .type = QEMU_OPT_STRING,
4484 },{
4485 .name = "port",
4486 .type = QEMU_OPT_STRING,
4487 },{
4488 .name = "localaddr",
4489 .type = QEMU_OPT_STRING,
4490 },{
4491 .name = "localport",
4492 .type = QEMU_OPT_STRING,
4493 },{
4494 .name = "to",
4495 .type = QEMU_OPT_NUMBER,
4496 },{
4497 .name = "ipv4",
4498 .type = QEMU_OPT_BOOL,
4499 },{
4500 .name = "ipv6",
4501 .type = QEMU_OPT_BOOL,
4502 },{
4503 .name = "wait",
4504 .type = QEMU_OPT_BOOL,
4505 },{
4506 .name = "server",
4507 .type = QEMU_OPT_BOOL,
4508 },{
4509 .name = "delay",
4510 .type = QEMU_OPT_BOOL,
5dd1f02b
CM
4511 },{
4512 .name = "reconnect",
4513 .type = QEMU_OPT_NUMBER,
4d454574
PB
4514 },{
4515 .name = "telnet",
4516 .type = QEMU_OPT_BOOL,
a8fb5427
DB
4517 },{
4518 .name = "tls-creds",
4519 .type = QEMU_OPT_STRING,
4d454574
PB
4520 },{
4521 .name = "width",
4522 .type = QEMU_OPT_NUMBER,
4523 },{
4524 .name = "height",
4525 .type = QEMU_OPT_NUMBER,
4526 },{
4527 .name = "cols",
4528 .type = QEMU_OPT_NUMBER,
4529 },{
4530 .name = "rows",
4531 .type = QEMU_OPT_NUMBER,
4532 },{
4533 .name = "mux",
4534 .type = QEMU_OPT_BOOL,
4535 },{
4536 .name = "signal",
4537 .type = QEMU_OPT_BOOL,
4538 },{
4539 .name = "name",
4540 .type = QEMU_OPT_STRING,
4541 },{
4542 .name = "debug",
4543 .type = QEMU_OPT_NUMBER,
51767e7c 4544 },{
3949e594 4545 .name = "size",
de1cc36e 4546 .type = QEMU_OPT_SIZE,
bb6fb7c0
GH
4547 },{
4548 .name = "chardev",
4549 .type = QEMU_OPT_STRING,
31e38a22
OK
4550 },{
4551 .name = "append",
4552 .type = QEMU_OPT_BOOL,
d0d7708b
DB
4553 },{
4554 .name = "logfile",
4555 .type = QEMU_OPT_STRING,
4556 },{
4557 .name = "logappend",
4558 .type = QEMU_OPT_BOOL,
4d454574
PB
4559 },
4560 { /* end of list */ }
4561 },
4562};
f1a1a356 4563
ffbdbe59
GH
4564#ifdef _WIN32
4565
777357d7
MAL
4566static void qmp_chardev_open_file(Chardev *chr,
4567 ChardevBackend *backend,
4568 bool *be_opened,
4569 Error **errp)
ffbdbe59 4570{
32bafa8f 4571 ChardevFile *file = backend->u.file.data;
ffbdbe59 4572 HANDLE out;
c025f689
SW
4573 DWORD accessmode;
4574 DWORD flags;
ffbdbe59 4575
e859eda5 4576 if (file->has_in) {
ffbdbe59 4577 error_setg(errp, "input file not supported");
777357d7 4578 return;
ffbdbe59
GH
4579 }
4580
c025f689
SW
4581 if (file->has_append && file->append) {
4582 /* Append to file if it already exists. */
4583 accessmode = FILE_GENERIC_WRITE & ~FILE_WRITE_DATA;
4584 flags = OPEN_ALWAYS;
4585 } else {
4586 /* Truncate file if it already exists. */
4587 accessmode = GENERIC_WRITE;
4588 flags = CREATE_ALWAYS;
4589 }
4590
4591 out = CreateFile(file->out, accessmode, FILE_SHARE_READ, NULL, flags,
4592 FILE_ATTRIBUTE_NORMAL, NULL);
ffbdbe59
GH
4593 if (out == INVALID_HANDLE_VALUE) {
4594 error_setg(errp, "open %s failed", file->out);
777357d7 4595 return;
ffbdbe59 4596 }
777357d7
MAL
4597
4598 qemu_chr_open_win_file(chr, out);
ffbdbe59
GH
4599}
4600
777357d7
MAL
4601static void qmp_chardev_open_serial(Chardev *chr,
4602 ChardevBackend *backend,
4603 bool *be_opened,
4604 Error **errp)
d59044ef 4605{
32bafa8f 4606 ChardevHostdev *serial = backend->u.serial.data;
acbfbe4a 4607
777357d7 4608 win_chr_init(chr, serial->device, errp);
d36b2b90
MA
4609}
4610
ffbdbe59
GH
4611#else /* WIN32 */
4612
4613static int qmp_chardev_open_file_source(char *src, int flags,
4614 Error **errp)
4615{
4616 int fd = -1;
4617
4618 TFR(fd = qemu_open(src, flags, 0666));
4619 if (fd == -1) {
20c39760 4620 error_setg_file_open(errp, errno, src);
ffbdbe59
GH
4621 }
4622 return fd;
4623}
4624
777357d7
MAL
4625static void qmp_chardev_open_file(Chardev *chr,
4626 ChardevBackend *backend,
4627 bool *be_opened,
4628 Error **errp)
ffbdbe59 4629{
32bafa8f 4630 ChardevFile *file = backend->u.file.data;
5f758366 4631 int flags, in = -1, out;
ffbdbe59 4632
31e38a22
OK
4633 flags = O_WRONLY | O_CREAT | O_BINARY;
4634 if (file->has_append && file->append) {
4635 flags |= O_APPEND;
4636 } else {
4637 flags |= O_TRUNC;
4638 }
4639
ffbdbe59 4640 out = qmp_chardev_open_file_source(file->out, flags, errp);
5f758366 4641 if (out < 0) {
777357d7 4642 return;
ffbdbe59
GH
4643 }
4644
e859eda5 4645 if (file->has_in) {
ffbdbe59
GH
4646 flags = O_RDONLY;
4647 in = qmp_chardev_open_file_source(file->in, flags, errp);
5f758366 4648 if (in < 0) {
ffbdbe59 4649 qemu_close(out);
777357d7 4650 return;
ffbdbe59
GH
4651 }
4652 }
4653
777357d7 4654 qemu_chr_open_fd(chr, in, out);
ffbdbe59
GH
4655}
4656
d809ab95 4657#ifdef HAVE_CHARDEV_SERIAL
777357d7
MAL
4658static void qmp_chardev_open_serial(Chardev *chr,
4659 ChardevBackend *backend,
4660 bool *be_opened,
4661 Error **errp)
d59044ef 4662{
32bafa8f 4663 ChardevHostdev *serial = backend->u.serial.data;
d36b2b90
MA
4664 int fd;
4665
4666 fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
5f758366 4667 if (fd < 0) {
777357d7 4668 return;
39099991 4669 }
f9e8cacc 4670 qemu_set_nonblock(fd);
acbfbe4a 4671 tty_serial_init(fd, 115200, 'N', 8, 1);
b68e956a 4672
777357d7 4673 qemu_chr_open_fd(chr, fd, fd);
d36b2b90 4674}
6511d396 4675#endif
d36b2b90 4676
d809ab95 4677#ifdef HAVE_CHARDEV_PARPORT
777357d7
MAL
4678static void qmp_chardev_open_parallel(Chardev *chr,
4679 ChardevBackend *backend,
4680 bool *be_opened,
4681 Error **errp)
d36b2b90 4682{
32bafa8f 4683 ChardevHostdev *parallel = backend->u.parallel.data;
d36b2b90
MA
4684 int fd;
4685
4686 fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
5f758366 4687 if (fd < 0) {
777357d7 4688 return;
d59044ef 4689 }
777357d7 4690 qemu_chr_open_pp_fd(chr, fd, be_opened, errp);
d59044ef 4691}
b68e956a 4692
777357d7
MAL
4693static void char_parallel_class_init(ObjectClass *oc, void *data)
4694{
4695 ChardevClass *cc = CHARDEV_CLASS(oc);
4696
88cace9f 4697 cc->parse = qemu_chr_parse_parallel;
777357d7 4698 cc->open = qmp_chardev_open_parallel;
b68e956a 4699#if defined(__linux__)
777357d7 4700 cc->chr_ioctl = pp_ioctl;
b68e956a 4701#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
777357d7 4702 cc->chr_ioctl = pp_ioctl;
b68e956a 4703#endif
777357d7
MAL
4704}
4705
c9305728
MAL
4706static void char_parallel_finalize(Object *obj)
4707{
4708#if defined(__linux__)
4709 Chardev *chr = CHARDEV(obj);
4710 ParallelChardev *drv = PARALLEL_CHARDEV(chr);
4711 int fd = drv->fd;
4712
4713 pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
4714 ioctl(fd, PPRELEASE);
4715 close(fd);
4716 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
4717#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
4718 /* FIXME: close fd? */
4719#endif
4720}
4721
777357d7
MAL
4722static const TypeInfo char_parallel_type_info = {
4723 .name = TYPE_CHARDEV_PARALLEL,
4724 .parent = TYPE_CHARDEV,
4725 .instance_size = sizeof(ParallelChardev),
c9305728 4726 .instance_finalize = char_parallel_finalize,
777357d7 4727 .class_init = char_parallel_class_init,
b68e956a 4728};
d809ab95 4729#endif
d59044ef 4730
ffbdbe59
GH
4731#endif /* WIN32 */
4732
777357d7
MAL
4733static void char_file_class_init(ObjectClass *oc, void *data)
4734{
4735 ChardevClass *cc = CHARDEV_CLASS(oc);
4736
88cace9f 4737 cc->parse = qemu_chr_parse_file_out;
777357d7 4738 cc->open = qmp_chardev_open_file;
777357d7
MAL
4739}
4740
4741static const TypeInfo char_file_type_info = {
4742 .name = TYPE_CHARDEV_FILE,
4743#ifdef _WIN32
4744 .parent = TYPE_CHARDEV_WIN,
b68e956a 4745#else
777357d7 4746 .parent = TYPE_CHARDEV_FD,
b68e956a 4747#endif
777357d7 4748 .class_init = char_file_class_init,
b68e956a
MAL
4749};
4750
4751#ifdef HAVE_CHARDEV_SERIAL
777357d7 4752
777357d7
MAL
4753static void char_serial_class_init(ObjectClass *oc, void *data)
4754{
4755 ChardevClass *cc = CHARDEV_CLASS(oc);
4756
88cace9f 4757 cc->parse = qemu_chr_parse_serial;
777357d7
MAL
4758 cc->open = qmp_chardev_open_serial;
4759#ifndef _WIN32
4760 cc->chr_ioctl = tty_serial_ioctl;
777357d7
MAL
4761#endif
4762}
4763
4764static const TypeInfo char_serial_type_info = {
4765 .name = TYPE_CHARDEV_SERIAL,
b68e956a 4766#ifdef _WIN32
777357d7 4767 .parent = TYPE_CHARDEV_WIN,
b68e956a 4768#else
777357d7 4769 .parent = TYPE_CHARDEV_FD,
b68e956a 4770#endif
777357d7 4771 .class_init = char_serial_class_init,
b68e956a
MAL
4772};
4773#endif
4774
5dd1f02b
CM
4775static gboolean socket_reconnect_timeout(gpointer opaque)
4776{
777357d7
MAL
4777 Chardev *chr = CHARDEV(opaque);
4778 SocketChardev *s = SOCKET_CHARDEV(opaque);
317856ca 4779 QIOChannelSocket *sioc;
5dd1f02b
CM
4780
4781 s->reconnect_timer = 0;
4782
4783 if (chr->be_open) {
4784 return false;
4785 }
4786
317856ca 4787 sioc = qio_channel_socket_new();
e93a68e1 4788 tcp_chr_set_client_ioc_name(chr, sioc);
317856ca
DB
4789 qio_channel_socket_connect_async(sioc, s->addr,
4790 qemu_chr_socket_connected,
4791 chr, NULL);
5dd1f02b
CM
4792
4793 return false;
4794}
4795
777357d7
MAL
4796static void qmp_chardev_open_socket(Chardev *chr,
4797 ChardevBackend *backend,
4798 bool *be_opened,
4799 Error **errp)
f6bd5d6e 4800{
777357d7 4801 SocketChardev *s = SOCKET_CHARDEV(chr);
32bafa8f 4802 ChardevSocket *sock = backend->u.socket.data;
f6bd5d6e
GH
4803 SocketAddress *addr = sock->addr;
4804 bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
4805 bool is_listen = sock->has_server ? sock->server : true;
4806 bool is_telnet = sock->has_telnet ? sock->telnet : false;
4807 bool is_waitconnect = sock->has_wait ? sock->wait : false;
5dd1f02b 4808 int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0;
317856ca 4809 QIOChannelSocket *sioc = NULL;
43ded1a0 4810
130257dc 4811 s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX;
cfb429cb
CM
4812 s->is_listen = is_listen;
4813 s->is_telnet = is_telnet;
43ded1a0 4814 s->do_nodelay = do_nodelay;
a8fb5427
DB
4815 if (sock->tls_creds) {
4816 Object *creds;
4817 creds = object_resolve_path_component(
4818 object_get_objects_root(), sock->tls_creds);
4819 if (!creds) {
4820 error_setg(errp, "No TLS credentials with id '%s'",
4821 sock->tls_creds);
4822 goto error;
4823 }
4824 s->tls_creds = (QCryptoTLSCreds *)
4825 object_dynamic_cast(creds,
4826 TYPE_QCRYPTO_TLS_CREDS);
4827 if (!s->tls_creds) {
4828 error_setg(errp, "Object with id '%s' is not TLS credentials",
4829 sock->tls_creds);
4830 goto error;
4831 }
4832 object_ref(OBJECT(s->tls_creds));
4833 if (is_listen) {
4834 if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
4835 error_setg(errp, "%s",
4836 "Expected TLS credentials for server endpoint");
4837 goto error;
4838 }
4839 } else {
4840 if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
4841 error_setg(errp, "%s",
4842 "Expected TLS credentials for client endpoint");
4843 goto error;
4844 }
4845 }
4846 }
4847
37f9e0a2 4848 s->addr = QAPI_CLONE(SocketAddress, sock->addr);
43ded1a0 4849
0a73336d
DB
4850 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
4851 if (s->is_unix) {
4852 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
4853 }
4854
43ded1a0 4855 /* be isn't opened until we get a connection */
82878dac 4856 *be_opened = false;
43ded1a0 4857
0ff0fad2
DB
4858 chr->filename = SocketAddress_to_str("disconnected:",
4859 addr, is_listen, is_telnet);
f6bd5d6e
GH
4860
4861 if (is_listen) {
43ded1a0
CM
4862 if (is_telnet) {
4863 s->do_telnetopt = 1;
4864 }
5dd1f02b
CM
4865 } else if (reconnect > 0) {
4866 s->reconnect_time = reconnect;
f6bd5d6e 4867 }
43ded1a0 4868
5008e5b7 4869 if (s->reconnect_time) {
d7a04fd7 4870 sioc = qio_channel_socket_new();
e93a68e1 4871 tcp_chr_set_client_ioc_name(chr, sioc);
317856ca
DB
4872 qio_channel_socket_connect_async(sioc, s->addr,
4873 qemu_chr_socket_connected,
4874 chr, NULL);
08b758b4 4875 } else {
d7a04fd7 4876 if (s->is_listen) {
e93a68e1 4877 char *name;
d7a04fd7 4878 sioc = qio_channel_socket_new();
e93a68e1
DB
4879
4880 name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
4881 qio_channel_set_name(QIO_CHANNEL(sioc), name);
4882 g_free(name);
4883
d7a04fd7
MAL
4884 if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) {
4885 goto error;
4886 }
4887 s->listen_ioc = sioc;
4888 if (is_waitconnect &&
4889 qemu_chr_wait_connected(chr, errp) < 0) {
2c3a5dcb 4890 return;
d7a04fd7
MAL
4891 }
4892 if (!s->ioc) {
4893 s->listen_tag = qio_channel_add_watch(
4894 QIO_CHANNEL(s->listen_ioc), G_IO_IN,
4895 tcp_chr_accept, chr, NULL);
4896 }
4897 } else if (qemu_chr_wait_connected(chr, errp) < 0) {
08b758b4
DB
4898 goto error;
4899 }
43ded1a0
CM
4900 }
4901
777357d7 4902 return;
a8fb5427 4903
777357d7 4904error:
08b758b4
DB
4905 if (sioc) {
4906 object_unref(OBJECT(sioc));
4907 }
f6bd5d6e
GH
4908}
4909
777357d7
MAL
4910static void char_socket_class_init(ObjectClass *oc, void *data)
4911{
4912 ChardevClass *cc = CHARDEV_CLASS(oc);
4913
88cace9f 4914 cc->parse = qemu_chr_parse_socket;
777357d7
MAL
4915 cc->open = qmp_chardev_open_socket;
4916 cc->chr_wait_connected = tcp_chr_wait_connected;
4917 cc->chr_write = tcp_chr_write;
4918 cc->chr_sync_read = tcp_chr_sync_read;
4919 cc->chr_disconnect = tcp_chr_disconnect;
4920 cc->get_msgfds = tcp_get_msgfds;
4921 cc->set_msgfds = tcp_set_msgfds;
4922 cc->chr_add_client = tcp_chr_add_client;
4923 cc->chr_add_watch = tcp_chr_add_watch;
4924 cc->chr_update_read_handler = tcp_chr_update_read_handler;
777357d7
MAL
4925}
4926
4927static const TypeInfo char_socket_type_info = {
4928 .name = TYPE_CHARDEV_SOCKET,
4929 .parent = TYPE_CHARDEV,
4930 .instance_size = sizeof(SocketChardev),
2c3a5dcb 4931 .instance_finalize = char_socket_finalize,
777357d7
MAL
4932 .class_init = char_socket_class_init,
4933};
4934
4935static void qmp_chardev_open_udp(Chardev *chr,
4936 ChardevBackend *backend,
4937 bool *be_opened,
4938 Error **errp)
3ecc059d 4939{
32bafa8f 4940 ChardevUdp *udp = backend->u.udp.data;
9894dc0c 4941 QIOChannelSocket *sioc = qio_channel_socket_new();
e93a68e1 4942 char *name;
777357d7 4943 UdpChardev *s = UDP_CHARDEV(chr);
3ecc059d 4944
9894dc0c 4945 if (qio_channel_socket_dgram_sync(sioc,
150dcd1a 4946 udp->local, udp->remote,
9894dc0c
DB
4947 errp) < 0) {
4948 object_unref(OBJECT(sioc));
777357d7 4949 return;
acbfbe4a 4950 }
e93a68e1
DB
4951
4952 name = g_strdup_printf("chardev-udp-%s", chr->label);
4953 qio_channel_set_name(QIO_CHANNEL(sioc), name);
4954 g_free(name);
4955
acbfbe4a 4956 s->ioc = QIO_CHANNEL(sioc);
acbfbe4a
MAL
4957 /* be isn't opened until we get a connection */
4958 *be_opened = false;
3ecc059d
GH
4959}
4960
777357d7
MAL
4961static void char_udp_class_init(ObjectClass *oc, void *data)
4962{
4963 ChardevClass *cc = CHARDEV_CLASS(oc);
4964
88cace9f 4965 cc->parse = qemu_chr_parse_udp;
777357d7
MAL
4966 cc->open = qmp_chardev_open_udp;
4967 cc->chr_write = udp_chr_write;
4968 cc->chr_update_read_handler = udp_chr_update_read_handler;
777357d7
MAL
4969}
4970
4971static const TypeInfo char_udp_type_info = {
4972 .name = TYPE_CHARDEV_UDP,
4973 .parent = TYPE_CHARDEV,
4974 .instance_size = sizeof(UdpChardev),
819aad23 4975 .instance_finalize = char_udp_finalize,
777357d7 4976 .class_init = char_udp_class_init,
b68e956a 4977};
0a73336d 4978
0ec7b3e7 4979bool qemu_chr_has_feature(Chardev *chr,
279b066e 4980 ChardevFeature feature)
0a73336d
DB
4981{
4982 return test_bit(feature, chr->features);
4983}
4984
0ec7b3e7 4985void qemu_chr_set_feature(Chardev *chr,
279b066e 4986 ChardevFeature feature)
0a73336d
DB
4987{
4988 return set_bit(feature, chr->features);
4989}
4990
777357d7
MAL
4991Chardev *qemu_chardev_new(const char *id, const char *typename,
4992 ChardevBackend *backend, Error **errp)
f1a1a356 4993{
0ec7b3e7 4994 Chardev *chr = NULL;
eaeba653 4995 Error *local_err = NULL;
82878dac 4996 bool be_opened = true;
f1a1a356 4997
777357d7 4998 assert(g_str_has_prefix(typename, "chardev-"));
f1a1a356 4999
777357d7
MAL
5000 chr = CHARDEV(object_new(typename));
5001 chr->label = g_strdup(id);
4ca17281 5002
777357d7 5003 qemu_char_open(chr, backend, &be_opened, &local_err);
a1698bf1
MAL
5004 if (local_err) {
5005 error_propagate(errp, local_err);
777357d7
MAL
5006 object_unref(OBJECT(chr));
5007 return NULL;
eaeba653
PB
5008 }
5009
eaeba653 5010 if (!chr->filename) {
777357d7 5011 chr->filename = g_strdup(typename + 8);
f1a1a356 5012 }
82878dac 5013 if (be_opened) {
eaeba653
PB
5014 qemu_chr_be_event(chr, CHR_EVENT_OPENED);
5015 }
777357d7
MAL
5016
5017 return chr;
5018}
5019
5020ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
5021 Error **errp)
5022{
5023 const ChardevClass *cc;
5024 ChardevReturn *ret;
5025 Chardev *chr;
5026
777357d7
MAL
5027 cc = char_get_class(ChardevBackendKind_lookup[backend->type], errp);
5028 if (!cc) {
5029 return NULL;
5030 }
5031
0b663b7d 5032 chr = qemu_chardev_add(id, object_class_get_name(OBJECT_CLASS(cc)),
777357d7
MAL
5033 backend, errp);
5034 if (!chr) {
5035 return NULL;
5036 }
5037
5038 ret = g_new0(ChardevReturn, 1);
5039 if (CHARDEV_IS_PTY(chr)) {
5040 ret->pty = g_strdup(chr->filename + 4);
5041 ret->has_pty = true;
5042 }
5043
eaeba653 5044 return ret;
f1a1a356
GH
5045}
5046
5047void qmp_chardev_remove(const char *id, Error **errp)
5048{
0ec7b3e7 5049 Chardev *chr;
f1a1a356
GH
5050
5051 chr = qemu_chr_find(id);
8108fd3e 5052 if (chr == NULL) {
f1a1a356
GH
5053 error_setg(errp, "Chardev '%s' not found", id);
5054 return;
5055 }
a4afa548 5056 if (qemu_chr_is_busy(chr)) {
f1a1a356
GH
5057 error_setg(errp, "Chardev '%s' is busy", id);
5058 return;
5059 }
5ebd6703 5060 if (qemu_chr_replay(chr)) {
33577b47
PD
5061 error_setg(errp,
5062 "Chardev '%s' cannot be unplugged in record/replay mode", id);
5063 return;
5064 }
f1a1a356
GH
5065 qemu_chr_delete(chr);
5066}
d654f34e 5067
aa5cb7f5 5068void qemu_chr_cleanup(void)
c1111a24 5069{
0ec7b3e7 5070 Chardev *chr, *tmp;
c1111a24
MAL
5071
5072 QTAILQ_FOREACH_SAFE(chr, &chardevs, next, tmp) {
5073 qemu_chr_delete(chr);
5074 }
5075}
5076
d654f34e
AL
5077static void register_types(void)
5078{
88cace9f
MAL
5079 type_register_static(&char_type_info);
5080#ifndef _WIN32
5081 type_register_static(&char_fd_type_info);
5082#else
5083 type_register_static(&char_win_type_info);
5084 type_register_static(&char_win_stdio_type_info);
5085#endif
88cace9f
MAL
5086 type_register_static(&char_socket_type_info);
5087 type_register_static(&char_udp_type_info);
5088 type_register_static(&char_ringbuf_type_info);
5089 type_register_static(&char_file_type_info);
5090 type_register_static(&char_stdio_type_info);
b68e956a 5091#ifdef HAVE_CHARDEV_SERIAL
88cace9f 5092 type_register_static(&char_serial_type_info);
6511d396 5093#endif
38bfb1a6 5094#ifdef HAVE_CHARDEV_PARPORT
88cace9f 5095 type_register_static(&char_parallel_type_info);
38bfb1a6 5096#endif
c2e75a43 5097#ifdef HAVE_CHARDEV_PTY
88cace9f 5098 type_register_static(&char_pty_type_info);
c2e75a43 5099#endif
122e5ed4 5100#ifdef _WIN32
88cace9f 5101 type_register_static(&char_console_type_info);
122e5ed4 5102#endif
88cace9f
MAL
5103 type_register_static(&char_pipe_type_info);
5104 type_register_static(&char_mux_type_info);
5105 type_register_static(&char_memory_type_info);
0b812f31 5106
7b7ab18d
MR
5107 /* this must be done after machine init, since we register FEs with muxes
5108 * as part of realize functions like serial_isa_realizefn when -nographic
5109 * is specified
5110 */
5111 qemu_add_machine_init_done_notifier(&muxes_realize_notify);
d654f34e
AL
5112}
5113
5114type_init(register_types);