blob: a671d6bbcb4973bb14bac6f96764f825e08204d3 [file] [log] [blame]
aliguori6f97dba2008-10-31 18:49:55 +00001/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "qemu-common.h"
Paolo Bonzini83c90892012-12-17 18:19:49 +010025#include "monitor/monitor.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010026#include "sysemu/sysemu.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010027#include "qemu/timer.h"
Paolo Bonzinidccfcd02013-04-08 16:55:25 +020028#include "sysemu/char.h"
aurel32cf3ebac2008-11-01 00:53:09 +000029#include "hw/usb.h"
Luiz Capitulinoc5a415a2011-09-14 16:05:49 -030030#include "qmp-commands.h"
Corey Minyardcfb429c2014-10-02 11:17:35 -050031#include "qapi/qmp-input-visitor.h"
32#include "qapi/qmp-output-visitor.h"
33#include "qapi-visit.h"
aliguori6f97dba2008-10-31 18:49:55 +000034
35#include <unistd.h>
36#include <fcntl.h>
aliguori6f97dba2008-10-31 18:49:55 +000037#include <time.h>
38#include <errno.h>
39#include <sys/time.h>
40#include <zlib.h>
41
42#ifndef _WIN32
43#include <sys/times.h>
44#include <sys/wait.h>
45#include <termios.h>
46#include <sys/mman.h>
47#include <sys/ioctl.h>
blueswir124646c72008-11-07 16:55:48 +000048#include <sys/resource.h>
aliguori6f97dba2008-10-31 18:49:55 +000049#include <sys/socket.h>
50#include <netinet/in.h>
blueswir124646c72008-11-07 16:55:48 +000051#include <net/if.h>
blueswir124646c72008-11-07 16:55:48 +000052#include <arpa/inet.h>
aliguori6f97dba2008-10-31 18:49:55 +000053#include <dirent.h>
54#include <netdb.h>
55#include <sys/select.h>
Juan Quintela71e72a12009-07-27 16:12:56 +020056#ifdef CONFIG_BSD
aliguori6f97dba2008-10-31 18:49:55 +000057#include <sys/stat.h>
Michael Tokarev3294ce12012-06-02 23:43:33 +040058#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
59#include <dev/ppbus/ppi.h>
60#include <dev/ppbus/ppbconf.h>
61#elif defined(__DragonFly__)
62#include <dev/misc/ppi/ppi.h>
63#include <bus/ppbus/ppbconf.h>
64#endif
Aurelien Jarnobbe813a2009-11-30 15:42:59 +010065#else
aliguori6f97dba2008-10-31 18:49:55 +000066#ifdef __linux__
aliguori6f97dba2008-10-31 18:49:55 +000067#include <linux/ppdev.h>
68#include <linux/parport.h>
69#endif
70#ifdef __sun__
71#include <sys/stat.h>
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>
aliguori6f97dba2008-10-31 18:49:55 +000081#endif
82#endif
83#endif
84
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010085#include "qemu/sockets.h"
Alon Levycbcc6332011-01-19 10:49:50 +020086#include "ui/qemu-spice.h"
aliguori6f97dba2008-10-31 18:49:55 +000087
Amit Shah9bd78542009-11-03 19:59:54 +053088#define READ_BUF_LEN 4096
Nikolay Nikolaev7b0bfdf2014-05-27 15:03:48 +030089#define READ_RETRIES 10
Corey Minyard9f781162014-10-02 11:17:33 -050090#define CHR_MAX_FILENAME_SIZE 256
Amit Shah9bd78542009-11-03 19:59:54 +053091
aliguori6f97dba2008-10-31 18:49:55 +000092/***********************************************************/
Corey Minyardcfb429c2014-10-02 11:17:35 -050093/* Socket address helpers */
94static void qapi_copy_SocketAddress(SocketAddress **p_dest,
95 SocketAddress *src)
96{
97 QmpOutputVisitor *qov;
98 QmpInputVisitor *qiv;
99 Visitor *ov, *iv;
100 QObject *obj;
101
102 *p_dest = NULL;
103
104 qov = qmp_output_visitor_new();
105 ov = qmp_output_get_visitor(qov);
106 visit_type_SocketAddress(ov, &src, NULL, &error_abort);
107 obj = qmp_output_get_qobject(qov);
108 qmp_output_visitor_cleanup(qov);
109 if (!obj) {
110 return;
111 }
112
113 qiv = qmp_input_visitor_new(obj);
114 iv = qmp_input_get_visitor(qiv);
115 visit_type_SocketAddress(iv, p_dest, NULL, &error_abort);
116 qmp_input_visitor_cleanup(qiv);
117 qobject_decref(obj);
118}
119
120/***********************************************************/
aliguori6f97dba2008-10-31 18:49:55 +0000121/* character device */
122
Blue Swirl72cf2d42009-09-12 07:36:22 +0000123static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
124 QTAILQ_HEAD_INITIALIZER(chardevs);
aliguori2970a6c2009-03-05 22:59:58 +0000125
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +0200126CharDriverState *qemu_chr_alloc(void)
127{
128 CharDriverState *chr = g_malloc0(sizeof(CharDriverState));
Paolo Bonzinif3db17b2014-06-25 09:04:57 +0200129 qemu_mutex_init(&chr->chr_write_lock);
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +0200130 return chr;
131}
132
Hans de Goedea425d232011-11-19 10:22:43 +0100133void qemu_chr_be_event(CharDriverState *s, int event)
aliguori6f97dba2008-10-31 18:49:55 +0000134{
Alexander Graf73cdf3f2010-04-01 18:42:39 +0200135 /* Keep track if the char device is open */
136 switch (event) {
137 case CHR_EVENT_OPENED:
Hans de Goede16665b92013-03-26 11:07:53 +0100138 s->be_open = 1;
Alexander Graf73cdf3f2010-04-01 18:42:39 +0200139 break;
140 case CHR_EVENT_CLOSED:
Hans de Goede16665b92013-03-26 11:07:53 +0100141 s->be_open = 0;
Alexander Graf73cdf3f2010-04-01 18:42:39 +0200142 break;
143 }
144
aliguori6f97dba2008-10-31 18:49:55 +0000145 if (!s->chr_event)
146 return;
147 s->chr_event(s->handler_opaque, event);
148}
149
Hans de Goedefee204f2013-03-26 11:07:54 +0100150void qemu_chr_be_generic_open(CharDriverState *s)
aliguori6f97dba2008-10-31 18:49:55 +0000151{
Michael Rothbd5c51e2013-06-07 15:19:53 -0500152 qemu_chr_be_event(s, CHR_EVENT_OPENED);
aliguori6f97dba2008-10-31 18:49:55 +0000153}
154
Anthony Liguori2cc6e0a2011-08-15 11:17:28 -0500155int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
aliguori6f97dba2008-10-31 18:49:55 +0000156{
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200157 int ret;
158
159 qemu_mutex_lock(&s->chr_write_lock);
160 ret = s->chr_write(s, buf, len);
161 qemu_mutex_unlock(&s->chr_write_lock);
162 return ret;
aliguori6f97dba2008-10-31 18:49:55 +0000163}
164
Anthony Liguoricd187202013-03-26 10:04:17 -0500165int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len)
166{
167 int offset = 0;
Igor Mammedov09313042014-06-25 10:00:41 +0200168 int res = 0;
Anthony Liguoricd187202013-03-26 10:04:17 -0500169
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200170 qemu_mutex_lock(&s->chr_write_lock);
Anthony Liguoricd187202013-03-26 10:04:17 -0500171 while (offset < len) {
172 do {
173 res = s->chr_write(s, buf + offset, len - offset);
174 if (res == -1 && errno == EAGAIN) {
175 g_usleep(100);
176 }
177 } while (res == -1 && errno == EAGAIN);
178
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200179 if (res <= 0) {
Anthony Liguoricd187202013-03-26 10:04:17 -0500180 break;
181 }
182
Anthony Liguoricd187202013-03-26 10:04:17 -0500183 offset += res;
184 }
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200185 qemu_mutex_unlock(&s->chr_write_lock);
Anthony Liguoricd187202013-03-26 10:04:17 -0500186
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200187 if (res < 0) {
188 return res;
189 }
Anthony Liguoricd187202013-03-26 10:04:17 -0500190 return offset;
191}
192
Nikolay Nikolaev7b0bfdf2014-05-27 15:03:48 +0300193int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len)
194{
195 int offset = 0, counter = 10;
196 int res;
197
198 if (!s->chr_sync_read) {
199 return 0;
200 }
201
202 while (offset < len) {
203 do {
204 res = s->chr_sync_read(s, buf + offset, len - offset);
205 if (res == -1 && errno == EAGAIN) {
206 g_usleep(100);
207 }
208 } while (res == -1 && errno == EAGAIN);
209
210 if (res == 0) {
211 break;
212 }
213
214 if (res < 0) {
215 return res;
216 }
217
218 offset += res;
219
220 if (!counter--) {
221 break;
222 }
223 }
224
225 return offset;
226}
227
Anthony Liguori41084f12011-08-15 11:17:34 -0500228int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
aliguori6f97dba2008-10-31 18:49:55 +0000229{
230 if (!s->chr_ioctl)
231 return -ENOTSUP;
232 return s->chr_ioctl(s, cmd, arg);
233}
234
Anthony Liguori909cda12011-08-15 11:17:31 -0500235int qemu_chr_be_can_write(CharDriverState *s)
aliguori6f97dba2008-10-31 18:49:55 +0000236{
237 if (!s->chr_can_read)
238 return 0;
239 return s->chr_can_read(s->handler_opaque);
240}
241
Anthony Liguorifa5efcc2011-08-15 11:17:30 -0500242void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
aliguori6f97dba2008-10-31 18:49:55 +0000243{
Stefan Weilac310732012-04-19 22:27:14 +0200244 if (s->chr_read) {
245 s->chr_read(s->handler_opaque, buf, len);
246 }
aliguori6f97dba2008-10-31 18:49:55 +0000247}
248
Anthony Liguori74c0d6f2011-08-15 11:17:39 -0500249int qemu_chr_fe_get_msgfd(CharDriverState *s)
Mark McLoughlin7d174052009-07-22 09:11:39 +0100250{
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +0300251 int fd;
Stefan Hajnoczi4f858612014-06-22 10:38:36 +0800252 return (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +0300253}
254
255int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len)
256{
257 return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1;
Mark McLoughlin7d174052009-07-22 09:11:39 +0100258}
259
Nikolay Nikolaevd39aac72014-05-27 15:04:02 +0300260int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num)
261{
262 return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1;
263}
264
Daniel P. Berrange13661082011-06-23 13:31:42 +0100265int qemu_chr_add_client(CharDriverState *s, int fd)
266{
267 return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
268}
269
aliguori6f97dba2008-10-31 18:49:55 +0000270void qemu_chr_accept_input(CharDriverState *s)
271{
272 if (s->chr_accept_input)
273 s->chr_accept_input(s);
Jan Kiszka98c8ee12012-03-16 13:18:00 +0100274 qemu_notify_event();
aliguori6f97dba2008-10-31 18:49:55 +0000275}
276
Anthony Liguorie7e71b02011-08-15 11:17:29 -0500277void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
aliguori6f97dba2008-10-31 18:49:55 +0000278{
Amit Shah9bd78542009-11-03 19:59:54 +0530279 char buf[READ_BUF_LEN];
aliguori6f97dba2008-10-31 18:49:55 +0000280 va_list ap;
281 va_start(ap, fmt);
282 vsnprintf(buf, sizeof(buf), fmt, ap);
Anthony Liguori2cc6e0a2011-08-15 11:17:28 -0500283 qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
aliguori6f97dba2008-10-31 18:49:55 +0000284 va_end(ap);
285}
286
Amit Shah386a5a12013-08-28 15:24:05 +0530287static void remove_fd_in_watch(CharDriverState *chr);
288
aliguori6f97dba2008-10-31 18:49:55 +0000289void qemu_chr_add_handlers(CharDriverState *s,
Juan Quintela7b27a762010-03-11 17:55:39 +0100290 IOCanReadHandler *fd_can_read,
aliguori6f97dba2008-10-31 18:49:55 +0000291 IOReadHandler *fd_read,
292 IOEventHandler *fd_event,
293 void *opaque)
294{
Hans de Goede19083222013-03-26 11:07:56 +0100295 int fe_open;
296
Amit Shahda7d9982011-04-25 15:18:22 +0530297 if (!opaque && !fd_can_read && !fd_read && !fd_event) {
Hans de Goede19083222013-03-26 11:07:56 +0100298 fe_open = 0;
Amit Shah386a5a12013-08-28 15:24:05 +0530299 remove_fd_in_watch(s);
Hans de Goede19083222013-03-26 11:07:56 +0100300 } else {
301 fe_open = 1;
Amit Shah2d6c1ef2011-02-10 12:55:20 +0530302 }
aliguori6f97dba2008-10-31 18:49:55 +0000303 s->chr_can_read = fd_can_read;
304 s->chr_read = fd_read;
305 s->chr_event = fd_event;
306 s->handler_opaque = opaque;
Gal Hammerac1b84d2014-02-25 12:12:35 +0200307 if (fe_open && s->chr_update_read_handler)
aliguori6f97dba2008-10-31 18:49:55 +0000308 s->chr_update_read_handler(s);
Alexander Graf73cdf3f2010-04-01 18:42:39 +0200309
Hans de Goede19083222013-03-26 11:07:56 +0100310 if (!s->explicit_fe_open) {
Hans de Goede8e25daa2013-03-26 11:07:57 +0100311 qemu_chr_fe_set_open(s, fe_open);
Hans de Goede19083222013-03-26 11:07:56 +0100312 }
313
Alexander Graf73cdf3f2010-04-01 18:42:39 +0200314 /* We're connecting to an already opened device, so let's make sure we
315 also get the open event */
Hans de Goedea59bcd32013-03-26 11:08:00 +0100316 if (fe_open && s->be_open) {
Hans de Goedefee204f2013-03-26 11:07:54 +0100317 qemu_chr_be_generic_open(s);
Alexander Graf73cdf3f2010-04-01 18:42:39 +0200318 }
aliguori6f97dba2008-10-31 18:49:55 +0000319}
320
321static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
322{
323 return len;
324}
325
Gerd Hoffmann80dca9e2013-02-21 11:41:26 +0100326static CharDriverState *qemu_chr_open_null(void)
aliguori6f97dba2008-10-31 18:49:55 +0000327{
328 CharDriverState *chr;
329
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +0200330 chr = qemu_chr_alloc();
aliguori6f97dba2008-10-31 18:49:55 +0000331 chr->chr_write = null_chr_write;
Michael Rothbd5c51e2013-06-07 15:19:53 -0500332 chr->explicit_be_open = true;
Markus Armbruster1f514702012-02-07 15:09:08 +0100333 return chr;
aliguori6f97dba2008-10-31 18:49:55 +0000334}
335
336/* MUX driver for serial I/O splitting */
aliguori6f97dba2008-10-31 18:49:55 +0000337#define MAX_MUX 4
338#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
339#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
340typedef struct {
Juan Quintela7b27a762010-03-11 17:55:39 +0100341 IOCanReadHandler *chr_can_read[MAX_MUX];
aliguori6f97dba2008-10-31 18:49:55 +0000342 IOReadHandler *chr_read[MAX_MUX];
343 IOEventHandler *chr_event[MAX_MUX];
344 void *ext_opaque[MAX_MUX];
345 CharDriverState *drv;
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200346 int focus;
aliguori6f97dba2008-10-31 18:49:55 +0000347 int mux_cnt;
348 int term_got_escape;
349 int max_size;
aliguoria80bf992009-03-05 23:00:02 +0000350 /* Intermediate input buffer allows to catch escape sequences even if the
351 currently active device is not accepting any input - but only until it
352 is full as well. */
353 unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
354 int prod[MAX_MUX];
355 int cons[MAX_MUX];
Jan Kiszka2d229592009-06-15 22:25:30 +0200356 int timestamps;
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200357
358 /* Protected by the CharDriverState chr_write_lock. */
Jan Kiszka4ab312f2009-06-15 22:25:34 +0200359 int linestart;
Jan Kiszka2d229592009-06-15 22:25:30 +0200360 int64_t timestamps_start;
aliguori6f97dba2008-10-31 18:49:55 +0000361} MuxDriver;
362
363
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200364/* Called with chr_write_lock held. */
aliguori6f97dba2008-10-31 18:49:55 +0000365static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
366{
367 MuxDriver *d = chr->opaque;
368 int ret;
Jan Kiszka2d229592009-06-15 22:25:30 +0200369 if (!d->timestamps) {
Paolo Bonzini6975b712014-06-18 08:43:56 +0200370 ret = qemu_chr_fe_write(d->drv, buf, len);
aliguori6f97dba2008-10-31 18:49:55 +0000371 } else {
372 int i;
373
374 ret = 0;
Jan Kiszka4ab312f2009-06-15 22:25:34 +0200375 for (i = 0; i < len; i++) {
376 if (d->linestart) {
aliguori6f97dba2008-10-31 18:49:55 +0000377 char buf1[64];
378 int64_t ti;
379 int secs;
380
Alex Blighbc72ad62013-08-21 16:03:08 +0100381 ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
Jan Kiszka2d229592009-06-15 22:25:30 +0200382 if (d->timestamps_start == -1)
383 d->timestamps_start = ti;
384 ti -= d->timestamps_start;
aliguoria4bb1db2009-01-22 17:15:16 +0000385 secs = ti / 1000;
aliguori6f97dba2008-10-31 18:49:55 +0000386 snprintf(buf1, sizeof(buf1),
387 "[%02d:%02d:%02d.%03d] ",
388 secs / 3600,
389 (secs / 60) % 60,
390 secs % 60,
aliguoria4bb1db2009-01-22 17:15:16 +0000391 (int)(ti % 1000));
Paolo Bonzini6975b712014-06-18 08:43:56 +0200392 qemu_chr_fe_write(d->drv, (uint8_t *)buf1, strlen(buf1));
Jan Kiszka4ab312f2009-06-15 22:25:34 +0200393 d->linestart = 0;
394 }
Paolo Bonzini6975b712014-06-18 08:43:56 +0200395 ret += qemu_chr_fe_write(d->drv, buf+i, 1);
Jan Kiszka4ab312f2009-06-15 22:25:34 +0200396 if (buf[i] == '\n') {
397 d->linestart = 1;
aliguori6f97dba2008-10-31 18:49:55 +0000398 }
399 }
400 }
401 return ret;
402}
403
404static const char * const mux_help[] = {
405 "% h print this help\n\r",
406 "% x exit emulator\n\r",
407 "% s save disk data back to file (if -snapshot)\n\r",
408 "% t toggle console timestamps\n\r"
409 "% b send break (magic sysrq)\n\r",
410 "% c switch between console and monitor\n\r",
411 "% % sends %\n\r",
412 NULL
413};
414
415int term_escape_char = 0x01; /* ctrl-a is used for escape */
416static void mux_print_help(CharDriverState *chr)
417{
418 int i, j;
419 char ebuf[15] = "Escape-Char";
420 char cbuf[50] = "\n\r";
421
422 if (term_escape_char > 0 && term_escape_char < 26) {
423 snprintf(cbuf, sizeof(cbuf), "\n\r");
424 snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
425 } else {
426 snprintf(cbuf, sizeof(cbuf),
427 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
428 term_escape_char);
429 }
Paolo Bonzini6975b712014-06-18 08:43:56 +0200430 qemu_chr_fe_write(chr, (uint8_t *)cbuf, strlen(cbuf));
aliguori6f97dba2008-10-31 18:49:55 +0000431 for (i = 0; mux_help[i] != NULL; i++) {
432 for (j=0; mux_help[i][j] != '\0'; j++) {
433 if (mux_help[i][j] == '%')
Paolo Bonzini6975b712014-06-18 08:43:56 +0200434 qemu_chr_fe_write(chr, (uint8_t *)ebuf, strlen(ebuf));
aliguori6f97dba2008-10-31 18:49:55 +0000435 else
Paolo Bonzini6975b712014-06-18 08:43:56 +0200436 qemu_chr_fe_write(chr, (uint8_t *)&mux_help[i][j], 1);
aliguori6f97dba2008-10-31 18:49:55 +0000437 }
438 }
439}
440
aliguori2724b182009-03-05 23:01:47 +0000441static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event)
442{
443 if (d->chr_event[mux_nr])
444 d->chr_event[mux_nr](d->ext_opaque[mux_nr], event);
445}
446
aliguori6f97dba2008-10-31 18:49:55 +0000447static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
448{
449 if (d->term_got_escape) {
450 d->term_got_escape = 0;
451 if (ch == term_escape_char)
452 goto send_char;
453 switch(ch) {
454 case '?':
455 case 'h':
456 mux_print_help(chr);
457 break;
458 case 'x':
459 {
460 const char *term = "QEMU: Terminated\n\r";
Paolo Bonzini6975b712014-06-18 08:43:56 +0200461 qemu_chr_fe_write(chr, (uint8_t *)term, strlen(term));
aliguori6f97dba2008-10-31 18:49:55 +0000462 exit(0);
463 break;
464 }
465 case 's':
Markus Armbruster6ab4b5a2010-06-02 18:55:18 +0200466 bdrv_commit_all();
aliguori6f97dba2008-10-31 18:49:55 +0000467 break;
468 case 'b':
Hans de Goedea425d232011-11-19 10:22:43 +0100469 qemu_chr_be_event(chr, CHR_EVENT_BREAK);
aliguori6f97dba2008-10-31 18:49:55 +0000470 break;
471 case 'c':
472 /* Switch to the next registered device */
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200473 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
474 d->focus++;
475 if (d->focus >= d->mux_cnt)
476 d->focus = 0;
477 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
aliguori6f97dba2008-10-31 18:49:55 +0000478 break;
Jan Kiszka2d229592009-06-15 22:25:30 +0200479 case 't':
480 d->timestamps = !d->timestamps;
481 d->timestamps_start = -1;
Jan Kiszka4ab312f2009-06-15 22:25:34 +0200482 d->linestart = 0;
Jan Kiszka2d229592009-06-15 22:25:30 +0200483 break;
aliguori6f97dba2008-10-31 18:49:55 +0000484 }
485 } else if (ch == term_escape_char) {
486 d->term_got_escape = 1;
487 } else {
488 send_char:
489 return 1;
490 }
491 return 0;
492}
493
494static void mux_chr_accept_input(CharDriverState *chr)
495{
aliguori6f97dba2008-10-31 18:49:55 +0000496 MuxDriver *d = chr->opaque;
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200497 int m = d->focus;
aliguori6f97dba2008-10-31 18:49:55 +0000498
aliguoria80bf992009-03-05 23:00:02 +0000499 while (d->prod[m] != d->cons[m] &&
aliguori6f97dba2008-10-31 18:49:55 +0000500 d->chr_can_read[m] &&
501 d->chr_can_read[m](d->ext_opaque[m])) {
502 d->chr_read[m](d->ext_opaque[m],
aliguoria80bf992009-03-05 23:00:02 +0000503 &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
aliguori6f97dba2008-10-31 18:49:55 +0000504 }
505}
506
507static int mux_chr_can_read(void *opaque)
508{
509 CharDriverState *chr = opaque;
510 MuxDriver *d = chr->opaque;
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200511 int m = d->focus;
aliguori6f97dba2008-10-31 18:49:55 +0000512
aliguoria80bf992009-03-05 23:00:02 +0000513 if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
aliguori6f97dba2008-10-31 18:49:55 +0000514 return 1;
aliguoria80bf992009-03-05 23:00:02 +0000515 if (d->chr_can_read[m])
516 return d->chr_can_read[m](d->ext_opaque[m]);
aliguori6f97dba2008-10-31 18:49:55 +0000517 return 0;
518}
519
520static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
521{
522 CharDriverState *chr = opaque;
523 MuxDriver *d = chr->opaque;
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200524 int m = d->focus;
aliguori6f97dba2008-10-31 18:49:55 +0000525 int i;
526
527 mux_chr_accept_input (opaque);
528
529 for(i = 0; i < size; i++)
530 if (mux_proc_byte(chr, d, buf[i])) {
aliguoria80bf992009-03-05 23:00:02 +0000531 if (d->prod[m] == d->cons[m] &&
aliguori6f97dba2008-10-31 18:49:55 +0000532 d->chr_can_read[m] &&
533 d->chr_can_read[m](d->ext_opaque[m]))
534 d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
535 else
aliguoria80bf992009-03-05 23:00:02 +0000536 d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
aliguori6f97dba2008-10-31 18:49:55 +0000537 }
538}
539
540static void mux_chr_event(void *opaque, int event)
541{
542 CharDriverState *chr = opaque;
543 MuxDriver *d = chr->opaque;
544 int i;
545
546 /* Send the event to all registered listeners */
547 for (i = 0; i < d->mux_cnt; i++)
aliguori2724b182009-03-05 23:01:47 +0000548 mux_chr_send_event(d, i, event);
aliguori6f97dba2008-10-31 18:49:55 +0000549}
550
551static void mux_chr_update_read_handler(CharDriverState *chr)
552{
553 MuxDriver *d = chr->opaque;
554
555 if (d->mux_cnt >= MAX_MUX) {
556 fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
557 return;
558 }
559 d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
560 d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
561 d->chr_read[d->mux_cnt] = chr->chr_read;
562 d->chr_event[d->mux_cnt] = chr->chr_event;
563 /* Fix up the real driver with mux routines */
564 if (d->mux_cnt == 0) {
565 qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
566 mux_chr_event, chr);
567 }
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200568 if (d->focus != -1) {
569 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +0200570 }
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200571 d->focus = d->mux_cnt;
aliguori6f97dba2008-10-31 18:49:55 +0000572 d->mux_cnt++;
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200573 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
aliguori6f97dba2008-10-31 18:49:55 +0000574}
575
Michael Roth7b7ab182013-07-30 13:04:22 -0500576static bool muxes_realized;
577
578/**
579 * Called after processing of default and command-line-specified
580 * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
581 * to a mux chardev. This is done here to ensure that
582 * output/prompts/banners are only displayed for the FE that has
583 * focus when initial command-line processing/machine init is
584 * completed.
585 *
586 * After this point, any new FE attached to any new or existing
587 * mux will receive CHR_EVENT_OPENED notifications for the BE
588 * immediately.
589 */
590static void muxes_realize_done(Notifier *notifier, void *unused)
591{
592 CharDriverState *chr;
593
594 QTAILQ_FOREACH(chr, &chardevs, next) {
595 if (chr->is_mux) {
596 MuxDriver *d = chr->opaque;
597 int i;
598
599 /* send OPENED to all already-attached FEs */
600 for (i = 0; i < d->mux_cnt; i++) {
601 mux_chr_send_event(d, i, CHR_EVENT_OPENED);
602 }
603 /* mark mux as OPENED so any new FEs will immediately receive
604 * OPENED event
605 */
606 qemu_chr_be_generic_open(chr);
607 }
608 }
609 muxes_realized = true;
610}
611
612static Notifier muxes_realize_notify = {
613 .notify = muxes_realize_done,
614};
615
Kirill Batuzov3f0838a2014-07-04 16:43:15 +0400616static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond)
617{
618 MuxDriver *d = s->opaque;
619 return d->drv->chr_add_watch(d->drv, cond);
620}
621
aliguori6f97dba2008-10-31 18:49:55 +0000622static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
623{
624 CharDriverState *chr;
625 MuxDriver *d;
626
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +0200627 chr = qemu_chr_alloc();
Anthony Liguori7267c092011-08-20 22:09:37 -0500628 d = g_malloc0(sizeof(MuxDriver));
aliguori6f97dba2008-10-31 18:49:55 +0000629
630 chr->opaque = d;
631 d->drv = drv;
Gerd Hoffmann799f1f22009-09-10 10:58:55 +0200632 d->focus = -1;
aliguori6f97dba2008-10-31 18:49:55 +0000633 chr->chr_write = mux_chr_write;
634 chr->chr_update_read_handler = mux_chr_update_read_handler;
635 chr->chr_accept_input = mux_chr_accept_input;
Hans de Goede7c32c4f2011-03-24 11:12:02 +0100636 /* Frontend guest-open / -close notification is not support with muxes */
Hans de Goede574b7112013-03-26 11:07:58 +0100637 chr->chr_set_fe_open = NULL;
Kirill Batuzov3f0838a2014-07-04 16:43:15 +0400638 if (drv->chr_add_watch) {
639 chr->chr_add_watch = mux_chr_add_watch;
640 }
Michael Roth7b7ab182013-07-30 13:04:22 -0500641 /* only default to opened state if we've realized the initial
642 * set of muxes
643 */
644 chr->explicit_be_open = muxes_realized ? 0 : 1;
645 chr->is_mux = 1;
Alexander Graf73cdf3f2010-04-01 18:42:39 +0200646
aliguori6f97dba2008-10-31 18:49:55 +0000647 return chr;
648}
649
650
651#ifdef _WIN32
aliguorid247d252008-11-11 20:46:40 +0000652int send_all(int fd, const void *buf, int len1)
aliguori6f97dba2008-10-31 18:49:55 +0000653{
654 int ret, len;
655
656 len = len1;
657 while (len > 0) {
658 ret = send(fd, buf, len, 0);
659 if (ret < 0) {
aliguori6f97dba2008-10-31 18:49:55 +0000660 errno = WSAGetLastError();
661 if (errno != WSAEWOULDBLOCK) {
662 return -1;
663 }
664 } else if (ret == 0) {
665 break;
666 } else {
667 buf += ret;
668 len -= ret;
669 }
670 }
671 return len1 - len;
672}
673
674#else
675
Jes Sorensen5fc9cfe2010-11-01 20:02:23 +0100676int send_all(int fd, const void *_buf, int len1)
aliguori6f97dba2008-10-31 18:49:55 +0000677{
678 int ret, len;
Jes Sorensen5fc9cfe2010-11-01 20:02:23 +0100679 const uint8_t *buf = _buf;
aliguori6f97dba2008-10-31 18:49:55 +0000680
681 len = len1;
682 while (len > 0) {
683 ret = write(fd, buf, len);
684 if (ret < 0) {
685 if (errno != EINTR && errno != EAGAIN)
686 return -1;
687 } else if (ret == 0) {
688 break;
689 } else {
690 buf += ret;
691 len -= ret;
692 }
693 }
694 return len1 - len;
695}
Stefan Berger4549a8b2013-02-27 12:47:53 -0500696
697int recv_all(int fd, void *_buf, int len1, bool single_read)
698{
699 int ret, len;
700 uint8_t *buf = _buf;
701
702 len = len1;
703 while ((len > 0) && (ret = read(fd, buf, len)) != 0) {
704 if (ret < 0) {
705 if (errno != EINTR && errno != EAGAIN) {
706 return -1;
707 }
708 continue;
709 } else {
710 if (single_read) {
711 return ret;
712 }
713 buf += ret;
714 len -= ret;
715 }
716 }
717 return len1 - len;
718}
719
aliguori6f97dba2008-10-31 18:49:55 +0000720#endif /* !_WIN32 */
721
Anthony Liguori96c63842013-03-05 23:21:18 +0530722typedef struct IOWatchPoll
723{
Paolo Bonzinid185c092013-04-05 17:59:33 +0200724 GSource parent;
725
Paolo Bonzini1e885b22013-04-08 15:03:15 +0200726 GIOChannel *channel;
Anthony Liguori96c63842013-03-05 23:21:18 +0530727 GSource *src;
Anthony Liguori96c63842013-03-05 23:21:18 +0530728
729 IOCanReadHandler *fd_can_read;
Paolo Bonzini1e885b22013-04-08 15:03:15 +0200730 GSourceFunc fd_read;
Anthony Liguori96c63842013-03-05 23:21:18 +0530731 void *opaque;
Anthony Liguori96c63842013-03-05 23:21:18 +0530732} IOWatchPoll;
733
Anthony Liguori96c63842013-03-05 23:21:18 +0530734static IOWatchPoll *io_watch_poll_from_source(GSource *source)
735{
Paolo Bonzinid185c092013-04-05 17:59:33 +0200736 return container_of(source, IOWatchPoll, parent);
Anthony Liguori96c63842013-03-05 23:21:18 +0530737}
738
739static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
740{
741 IOWatchPoll *iwp = io_watch_poll_from_source(source);
Paolo Bonzinid185c092013-04-05 17:59:33 +0200742 bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
Paolo Bonzini1e885b22013-04-08 15:03:15 +0200743 bool was_active = iwp->src != NULL;
Paolo Bonzinid185c092013-04-05 17:59:33 +0200744 if (was_active == now_active) {
Anthony Liguori96c63842013-03-05 23:21:18 +0530745 return FALSE;
746 }
747
Paolo Bonzinid185c092013-04-05 17:59:33 +0200748 if (now_active) {
Paolo Bonzini1e885b22013-04-08 15:03:15 +0200749 iwp->src = g_io_create_watch(iwp->channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
750 g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
Paolo Bonzinid185c092013-04-05 17:59:33 +0200751 g_source_attach(iwp->src, NULL);
752 } else {
Paolo Bonzini1e885b22013-04-08 15:03:15 +0200753 g_source_destroy(iwp->src);
754 g_source_unref(iwp->src);
755 iwp->src = NULL;
Paolo Bonzinid185c092013-04-05 17:59:33 +0200756 }
757 return FALSE;
Anthony Liguori96c63842013-03-05 23:21:18 +0530758}
759
760static gboolean io_watch_poll_check(GSource *source)
761{
Paolo Bonzinid185c092013-04-05 17:59:33 +0200762 return FALSE;
Anthony Liguori96c63842013-03-05 23:21:18 +0530763}
764
765static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
766 gpointer user_data)
767{
Paolo Bonzinid185c092013-04-05 17:59:33 +0200768 abort();
Anthony Liguori96c63842013-03-05 23:21:18 +0530769}
770
771static void io_watch_poll_finalize(GSource *source)
772{
Paolo Bonzini2b316772013-04-19 17:32:09 +0200773 /* Due to a glib bug, removing the last reference to a source
774 * inside a finalize callback causes recursive locking (and a
775 * deadlock). This is not a problem inside other callbacks,
776 * including dispatch callbacks, so we call io_remove_watch_poll
777 * to remove this source. At this point, iwp->src must
778 * be NULL, or we would leak it.
779 *
780 * This would be solved much more elegantly by child sources,
781 * but we support older glib versions that do not have them.
782 */
Anthony Liguori96c63842013-03-05 23:21:18 +0530783 IOWatchPoll *iwp = io_watch_poll_from_source(source);
Paolo Bonzini2b316772013-04-19 17:32:09 +0200784 assert(iwp->src == NULL);
Anthony Liguori96c63842013-03-05 23:21:18 +0530785}
786
787static GSourceFuncs io_watch_poll_funcs = {
788 .prepare = io_watch_poll_prepare,
789 .check = io_watch_poll_check,
790 .dispatch = io_watch_poll_dispatch,
791 .finalize = io_watch_poll_finalize,
792};
793
794/* Can only be used for read */
795static guint io_add_watch_poll(GIOChannel *channel,
796 IOCanReadHandler *fd_can_read,
797 GIOFunc fd_read,
798 gpointer user_data)
799{
800 IOWatchPoll *iwp;
Paolo Bonzini0ca5aa42013-04-10 15:23:27 +0200801 int tag;
Anthony Liguori96c63842013-03-05 23:21:18 +0530802
Paolo Bonzinid185c092013-04-05 17:59:33 +0200803 iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs, sizeof(IOWatchPoll));
Anthony Liguori96c63842013-03-05 23:21:18 +0530804 iwp->fd_can_read = fd_can_read;
805 iwp->opaque = user_data;
Paolo Bonzini1e885b22013-04-08 15:03:15 +0200806 iwp->channel = channel;
807 iwp->fd_read = (GSourceFunc) fd_read;
808 iwp->src = NULL;
Anthony Liguori96c63842013-03-05 23:21:18 +0530809
Paolo Bonzini0ca5aa42013-04-10 15:23:27 +0200810 tag = g_source_attach(&iwp->parent, NULL);
811 g_source_unref(&iwp->parent);
812 return tag;
Anthony Liguori96c63842013-03-05 23:21:18 +0530813}
814
Paolo Bonzini2b316772013-04-19 17:32:09 +0200815static void io_remove_watch_poll(guint tag)
816{
817 GSource *source;
818 IOWatchPoll *iwp;
819
820 g_return_if_fail (tag > 0);
821
822 source = g_main_context_find_source_by_id(NULL, tag);
823 g_return_if_fail (source != NULL);
824
825 iwp = io_watch_poll_from_source(source);
826 if (iwp->src) {
827 g_source_destroy(iwp->src);
828 g_source_unref(iwp->src);
829 iwp->src = NULL;
830 }
831 g_source_destroy(&iwp->parent);
832}
833
Amit Shah26da70c2013-08-28 15:23:37 +0530834static void remove_fd_in_watch(CharDriverState *chr)
835{
836 if (chr->fd_in_tag) {
837 io_remove_watch_poll(chr->fd_in_tag);
838 chr->fd_in_tag = 0;
839 }
840}
841
Blue Swirl44ab9ed2013-03-09 09:56:04 +0000842#ifndef _WIN32
Anthony Liguori96c63842013-03-05 23:21:18 +0530843static GIOChannel *io_channel_from_fd(int fd)
844{
845 GIOChannel *chan;
846
847 if (fd == -1) {
848 return NULL;
849 }
850
851 chan = g_io_channel_unix_new(fd);
852
853 g_io_channel_set_encoding(chan, NULL, NULL);
854 g_io_channel_set_buffered(chan, FALSE);
855
856 return chan;
857}
Blue Swirl44ab9ed2013-03-09 09:56:04 +0000858#endif
Anthony Liguori96c63842013-03-05 23:21:18 +0530859
Anthony Liguori76a96442013-03-05 23:21:21 +0530860static GIOChannel *io_channel_from_socket(int fd)
861{
862 GIOChannel *chan;
863
864 if (fd == -1) {
865 return NULL;
866 }
867
868#ifdef _WIN32
869 chan = g_io_channel_win32_new_socket(fd);
870#else
871 chan = g_io_channel_unix_new(fd);
872#endif
873
874 g_io_channel_set_encoding(chan, NULL, NULL);
875 g_io_channel_set_buffered(chan, FALSE);
876
877 return chan;
878}
879
Anthony Liguori684a0962013-03-29 11:39:50 -0500880static int io_channel_send(GIOChannel *fd, const void *buf, size_t len)
Anthony Liguori96c63842013-03-05 23:21:18 +0530881{
Laszlo Ersekac8c26f2013-07-16 20:19:40 +0200882 size_t offset = 0;
883 GIOStatus status = G_IO_STATUS_NORMAL;
Anthony Liguori96c63842013-03-05 23:21:18 +0530884
Laszlo Ersekac8c26f2013-07-16 20:19:40 +0200885 while (offset < len && status == G_IO_STATUS_NORMAL) {
886 gsize bytes_written = 0;
Anthony Liguori684a0962013-03-29 11:39:50 -0500887
888 status = g_io_channel_write_chars(fd, buf + offset, len - offset,
Anthony Liguori96c63842013-03-05 23:21:18 +0530889 &bytes_written, NULL);
Anthony Liguori684a0962013-03-29 11:39:50 -0500890 offset += bytes_written;
Anthony Liguori96c63842013-03-05 23:21:18 +0530891 }
Anthony Liguori684a0962013-03-29 11:39:50 -0500892
Laszlo Ersekac8c26f2013-07-16 20:19:40 +0200893 if (offset > 0) {
894 return offset;
895 }
896 switch (status) {
897 case G_IO_STATUS_NORMAL:
898 g_assert(len == 0);
899 return 0;
900 case G_IO_STATUS_AGAIN:
901 errno = EAGAIN;
902 return -1;
903 default:
904 break;
905 }
906 errno = EINVAL;
907 return -1;
Anthony Liguori96c63842013-03-05 23:21:18 +0530908}
Anthony Liguori96c63842013-03-05 23:21:18 +0530909
Blue Swirl44ab9ed2013-03-09 09:56:04 +0000910#ifndef _WIN32
911
Anthony Liguoria29753f2013-03-05 23:21:19 +0530912typedef struct FDCharDriver {
913 CharDriverState *chr;
914 GIOChannel *fd_in, *fd_out;
aliguori6f97dba2008-10-31 18:49:55 +0000915 int max_size;
Anthony Liguoria29753f2013-03-05 23:21:19 +0530916 QTAILQ_ENTRY(FDCharDriver) node;
aliguori6f97dba2008-10-31 18:49:55 +0000917} FDCharDriver;
918
Paolo Bonzini9005b2a2014-06-18 08:43:58 +0200919/* Called with chr_write_lock held. */
aliguori6f97dba2008-10-31 18:49:55 +0000920static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
921{
922 FDCharDriver *s = chr->opaque;
Anthony Liguoria29753f2013-03-05 23:21:19 +0530923
Anthony Liguori684a0962013-03-29 11:39:50 -0500924 return io_channel_send(s->fd_out, buf, len);
Anthony Liguoria29753f2013-03-05 23:21:19 +0530925}
926
927static gboolean fd_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
928{
929 CharDriverState *chr = opaque;
930 FDCharDriver *s = chr->opaque;
931 int len;
932 uint8_t buf[READ_BUF_LEN];
933 GIOStatus status;
934 gsize bytes_read;
935
936 len = sizeof(buf);
937 if (len > s->max_size) {
938 len = s->max_size;
939 }
940 if (len == 0) {
Paolo Bonzinicdbf6e12013-04-19 17:32:08 +0200941 return TRUE;
Anthony Liguoria29753f2013-03-05 23:21:19 +0530942 }
943
944 status = g_io_channel_read_chars(chan, (gchar *)buf,
945 len, &bytes_read, NULL);
946 if (status == G_IO_STATUS_EOF) {
Amit Shah26da70c2013-08-28 15:23:37 +0530947 remove_fd_in_watch(chr);
Anthony Liguoria29753f2013-03-05 23:21:19 +0530948 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
949 return FALSE;
950 }
951 if (status == G_IO_STATUS_NORMAL) {
952 qemu_chr_be_write(chr, buf, bytes_read);
953 }
954
955 return TRUE;
aliguori6f97dba2008-10-31 18:49:55 +0000956}
957
958static int fd_chr_read_poll(void *opaque)
959{
960 CharDriverState *chr = opaque;
961 FDCharDriver *s = chr->opaque;
962
Anthony Liguori909cda12011-08-15 11:17:31 -0500963 s->max_size = qemu_chr_be_can_write(chr);
aliguori6f97dba2008-10-31 18:49:55 +0000964 return s->max_size;
965}
966
Anthony Liguori23673ca2013-03-05 23:21:23 +0530967static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
968{
969 FDCharDriver *s = chr->opaque;
970 return g_io_create_watch(s->fd_out, cond);
971}
972
aliguori6f97dba2008-10-31 18:49:55 +0000973static void fd_chr_update_read_handler(CharDriverState *chr)
974{
975 FDCharDriver *s = chr->opaque;
976
Amit Shah26da70c2013-08-28 15:23:37 +0530977 remove_fd_in_watch(chr);
Anthony Liguoria29753f2013-03-05 23:21:19 +0530978 if (s->fd_in) {
Amit Shah7ba9add2013-08-28 15:18:29 +0530979 chr->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll,
980 fd_chr_read, chr);
aliguori6f97dba2008-10-31 18:49:55 +0000981 }
982}
983
984static void fd_chr_close(struct CharDriverState *chr)
985{
986 FDCharDriver *s = chr->opaque;
987
Amit Shah26da70c2013-08-28 15:23:37 +0530988 remove_fd_in_watch(chr);
Anthony Liguoria29753f2013-03-05 23:21:19 +0530989 if (s->fd_in) {
990 g_io_channel_unref(s->fd_in);
991 }
992 if (s->fd_out) {
993 g_io_channel_unref(s->fd_out);
aliguori6f97dba2008-10-31 18:49:55 +0000994 }
995
Anthony Liguori7267c092011-08-20 22:09:37 -0500996 g_free(s);
Hans de Goedea425d232011-11-19 10:22:43 +0100997 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
aliguori6f97dba2008-10-31 18:49:55 +0000998}
999
1000/* open a character device to a unix fd */
1001static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
1002{
1003 CharDriverState *chr;
1004 FDCharDriver *s;
1005
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02001006 chr = qemu_chr_alloc();
Anthony Liguori7267c092011-08-20 22:09:37 -05001007 s = g_malloc0(sizeof(FDCharDriver));
Anthony Liguoria29753f2013-03-05 23:21:19 +05301008 s->fd_in = io_channel_from_fd(fd_in);
1009 s->fd_out = io_channel_from_fd(fd_out);
Gonglei4ff12bd2014-08-11 17:34:20 +08001010 qemu_set_nonblock(fd_out);
Anthony Liguoria29753f2013-03-05 23:21:19 +05301011 s->chr = chr;
aliguori6f97dba2008-10-31 18:49:55 +00001012 chr->opaque = s;
Anthony Liguori23673ca2013-03-05 23:21:23 +05301013 chr->chr_add_watch = fd_chr_add_watch;
aliguori6f97dba2008-10-31 18:49:55 +00001014 chr->chr_write = fd_chr_write;
1015 chr->chr_update_read_handler = fd_chr_update_read_handler;
1016 chr->chr_close = fd_chr_close;
1017
aliguori6f97dba2008-10-31 18:49:55 +00001018 return chr;
1019}
1020
Gerd Hoffmann548cbb32013-02-25 11:50:55 +01001021static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
aliguori6f97dba2008-10-31 18:49:55 +00001022{
1023 int fd_in, fd_out;
Corey Minyard9f781162014-10-02 11:17:33 -05001024 char filename_in[CHR_MAX_FILENAME_SIZE];
1025 char filename_out[CHR_MAX_FILENAME_SIZE];
Gerd Hoffmann548cbb32013-02-25 11:50:55 +01001026 const char *filename = opts->device;
Gerd Hoffmann7d315442009-09-10 10:58:36 +02001027
1028 if (filename == NULL) {
1029 fprintf(stderr, "chardev: pipe: no filename given\n");
Markus Armbruster1f514702012-02-07 15:09:08 +01001030 return NULL;
Gerd Hoffmann7d315442009-09-10 10:58:36 +02001031 }
aliguori6f97dba2008-10-31 18:49:55 +00001032
Corey Minyard9f781162014-10-02 11:17:33 -05001033 snprintf(filename_in, CHR_MAX_FILENAME_SIZE, "%s.in", filename);
1034 snprintf(filename_out, CHR_MAX_FILENAME_SIZE, "%s.out", filename);
Kevin Wolf40ff6d72009-12-02 12:24:42 +01001035 TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
1036 TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
aliguori6f97dba2008-10-31 18:49:55 +00001037 if (fd_in < 0 || fd_out < 0) {
1038 if (fd_in >= 0)
1039 close(fd_in);
1040 if (fd_out >= 0)
1041 close(fd_out);
Markus Armbrusterb181e042012-02-07 15:09:09 +01001042 TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
Markus Armbrustera89dd6c2012-02-07 15:09:10 +01001043 if (fd_in < 0) {
Markus Armbruster1f514702012-02-07 15:09:08 +01001044 return NULL;
Markus Armbrustera89dd6c2012-02-07 15:09:10 +01001045 }
aliguori6f97dba2008-10-31 18:49:55 +00001046 }
Markus Armbruster1f514702012-02-07 15:09:08 +01001047 return qemu_chr_open_fd(fd_in, fd_out);
aliguori6f97dba2008-10-31 18:49:55 +00001048}
1049
aliguori6f97dba2008-10-31 18:49:55 +00001050/* init terminal so that we can grab keys */
1051static struct termios oldtty;
1052static int old_fd0_flags;
Li Liuc88930a2014-09-09 19:19:48 +08001053static bool stdio_in_use;
Paolo Bonzinibb002512010-12-23 13:42:50 +01001054static bool stdio_allow_signal;
aliguori6f97dba2008-10-31 18:49:55 +00001055
1056static void term_exit(void)
1057{
1058 tcsetattr (0, TCSANOW, &oldtty);
1059 fcntl(0, F_SETFL, old_fd0_flags);
1060}
1061
Paolo Bonzinibb002512010-12-23 13:42:50 +01001062static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
aliguori6f97dba2008-10-31 18:49:55 +00001063{
1064 struct termios tty;
1065
Paolo Bonzini03693642010-12-23 13:42:49 +01001066 tty = oldtty;
Paolo Bonzinibb002512010-12-23 13:42:50 +01001067 if (!echo) {
1068 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
aliguori6f97dba2008-10-31 18:49:55 +00001069 |INLCR|IGNCR|ICRNL|IXON);
Paolo Bonzinibb002512010-12-23 13:42:50 +01001070 tty.c_oflag |= OPOST;
1071 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
1072 tty.c_cflag &= ~(CSIZE|PARENB);
1073 tty.c_cflag |= CS8;
1074 tty.c_cc[VMIN] = 1;
1075 tty.c_cc[VTIME] = 0;
1076 }
Paolo Bonzinibb002512010-12-23 13:42:50 +01001077 if (!stdio_allow_signal)
aliguori6f97dba2008-10-31 18:49:55 +00001078 tty.c_lflag &= ~ISIG;
aliguori6f97dba2008-10-31 18:49:55 +00001079
1080 tcsetattr (0, TCSANOW, &tty);
aliguori6f97dba2008-10-31 18:49:55 +00001081}
1082
1083static void qemu_chr_close_stdio(struct CharDriverState *chr)
1084{
1085 term_exit();
aliguori6f97dba2008-10-31 18:49:55 +00001086 fd_chr_close(chr);
1087}
1088
Gerd Hoffmann7c358032013-02-21 12:34:58 +01001089static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
aliguori6f97dba2008-10-31 18:49:55 +00001090{
1091 CharDriverState *chr;
1092
Michael Tokarevab51b1d2012-12-30 12:48:14 +04001093 if (is_daemonized()) {
1094 error_report("cannot use stdio with -daemonize");
1095 return NULL;
1096 }
Li Liuc88930a2014-09-09 19:19:48 +08001097
1098 if (stdio_in_use) {
1099 error_report("cannot use stdio by multiple character devices");
1100 exit(1);
1101 }
1102
1103 stdio_in_use = true;
Anthony Liguoried7a1542013-03-05 23:21:17 +05301104 old_fd0_flags = fcntl(0, F_GETFL);
Li Liuc88930a2014-09-09 19:19:48 +08001105 tcgetattr(0, &oldtty);
Gonglei4ff12bd2014-08-11 17:34:20 +08001106 qemu_set_nonblock(0);
Anthony Liguoried7a1542013-03-05 23:21:17 +05301107 atexit(term_exit);
Paolo Bonzini03693642010-12-23 13:42:49 +01001108
aliguori6f97dba2008-10-31 18:49:55 +00001109 chr = qemu_chr_open_fd(0, 1);
1110 chr->chr_close = qemu_chr_close_stdio;
Paolo Bonzinibb002512010-12-23 13:42:50 +01001111 chr->chr_set_echo = qemu_chr_set_echo_stdio;
Gerd Hoffmann7c358032013-02-21 12:34:58 +01001112 if (opts->has_signal) {
1113 stdio_allow_signal = opts->signal;
1114 }
Anthony Liguori15f31512011-08-15 11:17:35 -05001115 qemu_chr_fe_set_echo(chr, false);
aliguori6f97dba2008-10-31 18:49:55 +00001116
Markus Armbruster1f514702012-02-07 15:09:08 +01001117 return chr;
aliguori6f97dba2008-10-31 18:49:55 +00001118}
1119
aliguori6f97dba2008-10-31 18:49:55 +00001120#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
Aurelien Jarnoa167ba52009-11-29 18:00:41 +01001121 || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
1122 || defined(__GLIBC__)
aliguori6f97dba2008-10-31 18:49:55 +00001123
Gerd Hoffmanne5514982012-12-19 16:35:42 +01001124#define HAVE_CHARDEV_TTY 1
1125
aliguori6f97dba2008-10-31 18:49:55 +00001126typedef struct {
Anthony Liguori093d3a22013-03-05 23:21:20 +05301127 GIOChannel *fd;
aliguori6f97dba2008-10-31 18:49:55 +00001128 int read_bytes;
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001129
1130 /* Protected by the CharDriverState chr_write_lock. */
1131 int connected;
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301132 guint timer_tag;
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001133 guint open_tag;
aliguori6f97dba2008-10-31 18:49:55 +00001134} PtyCharDriver;
1135
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001136static void pty_chr_update_read_handler_locked(CharDriverState *chr);
aliguori6f97dba2008-10-31 18:49:55 +00001137static void pty_chr_state(CharDriverState *chr, int connected);
1138
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301139static gboolean pty_chr_timer(gpointer opaque)
1140{
1141 struct CharDriverState *chr = opaque;
1142 PtyCharDriver *s = chr->opaque;
1143
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001144 qemu_mutex_lock(&chr->chr_write_lock);
Hans de Goede79f20072013-04-25 13:53:02 +02001145 s->timer_tag = 0;
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001146 s->open_tag = 0;
Gerd Hoffmannb0d768c2013-08-22 11:43:58 +02001147 if (!s->connected) {
1148 /* Next poll ... */
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001149 pty_chr_update_read_handler_locked(chr);
Gerd Hoffmannb0d768c2013-08-22 11:43:58 +02001150 }
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001151 qemu_mutex_unlock(&chr->chr_write_lock);
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301152 return FALSE;
1153}
1154
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001155/* Called with chr_write_lock held. */
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301156static void pty_chr_rearm_timer(CharDriverState *chr, int ms)
1157{
1158 PtyCharDriver *s = chr->opaque;
1159
1160 if (s->timer_tag) {
1161 g_source_remove(s->timer_tag);
1162 s->timer_tag = 0;
1163 }
1164
1165 if (ms == 1000) {
1166 s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
1167 } else {
1168 s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
1169 }
1170}
1171
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001172/* Called with chr_write_lock held. */
1173static void pty_chr_update_read_handler_locked(CharDriverState *chr)
Paolo Bonzini1bb7fe72014-06-18 08:43:57 +02001174{
1175 PtyCharDriver *s = chr->opaque;
1176 GPollFD pfd;
1177
1178 pfd.fd = g_io_channel_unix_get_fd(s->fd);
1179 pfd.events = G_IO_OUT;
1180 pfd.revents = 0;
1181 g_poll(&pfd, 1, 0);
1182 if (pfd.revents & G_IO_HUP) {
1183 pty_chr_state(chr, 0);
1184 } else {
1185 pty_chr_state(chr, 1);
1186 }
1187}
1188
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001189static void pty_chr_update_read_handler(CharDriverState *chr)
1190{
1191 qemu_mutex_lock(&chr->chr_write_lock);
1192 pty_chr_update_read_handler_locked(chr);
1193 qemu_mutex_unlock(&chr->chr_write_lock);
1194}
1195
1196/* Called with chr_write_lock held. */
aliguori6f97dba2008-10-31 18:49:55 +00001197static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1198{
1199 PtyCharDriver *s = chr->opaque;
1200
1201 if (!s->connected) {
1202 /* guest sends data, check for (re-)connect */
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001203 pty_chr_update_read_handler_locked(chr);
Sebastian Tanasecf7330c2014-07-28 13:39:14 +02001204 if (!s->connected) {
1205 return 0;
1206 }
aliguori6f97dba2008-10-31 18:49:55 +00001207 }
Anthony Liguori684a0962013-03-29 11:39:50 -05001208 return io_channel_send(s->fd, buf, len);
aliguori6f97dba2008-10-31 18:49:55 +00001209}
1210
Anthony Liguorie6a87ed2013-03-05 23:21:24 +05301211static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond)
1212{
1213 PtyCharDriver *s = chr->opaque;
Paolo Bonzini62c339c2014-07-24 16:08:04 +02001214 if (!s->connected) {
1215 return NULL;
1216 }
Anthony Liguorie6a87ed2013-03-05 23:21:24 +05301217 return g_io_create_watch(s->fd, cond);
1218}
1219
aliguori6f97dba2008-10-31 18:49:55 +00001220static int pty_chr_read_poll(void *opaque)
1221{
1222 CharDriverState *chr = opaque;
1223 PtyCharDriver *s = chr->opaque;
1224
Anthony Liguori909cda12011-08-15 11:17:31 -05001225 s->read_bytes = qemu_chr_be_can_write(chr);
aliguori6f97dba2008-10-31 18:49:55 +00001226 return s->read_bytes;
1227}
1228
Anthony Liguori093d3a22013-03-05 23:21:20 +05301229static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
aliguori6f97dba2008-10-31 18:49:55 +00001230{
1231 CharDriverState *chr = opaque;
1232 PtyCharDriver *s = chr->opaque;
Anthony Liguori093d3a22013-03-05 23:21:20 +05301233 gsize size, len;
Amit Shah9bd78542009-11-03 19:59:54 +05301234 uint8_t buf[READ_BUF_LEN];
Anthony Liguori093d3a22013-03-05 23:21:20 +05301235 GIOStatus status;
aliguori6f97dba2008-10-31 18:49:55 +00001236
1237 len = sizeof(buf);
1238 if (len > s->read_bytes)
1239 len = s->read_bytes;
Paolo Bonzinicdbf6e12013-04-19 17:32:08 +02001240 if (len == 0) {
1241 return TRUE;
1242 }
Anthony Liguori093d3a22013-03-05 23:21:20 +05301243 status = g_io_channel_read_chars(s->fd, (gchar *)buf, len, &size, NULL);
1244 if (status != G_IO_STATUS_NORMAL) {
aliguori6f97dba2008-10-31 18:49:55 +00001245 pty_chr_state(chr, 0);
Anthony Liguori093d3a22013-03-05 23:21:20 +05301246 return FALSE;
1247 } else {
aliguori6f97dba2008-10-31 18:49:55 +00001248 pty_chr_state(chr, 1);
Anthony Liguorifa5efcc2011-08-15 11:17:30 -05001249 qemu_chr_be_write(chr, buf, size);
aliguori6f97dba2008-10-31 18:49:55 +00001250 }
Anthony Liguori093d3a22013-03-05 23:21:20 +05301251 return TRUE;
aliguori6f97dba2008-10-31 18:49:55 +00001252}
1253
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001254static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
1255{
1256 CharDriverState *chr = opaque;
1257 PtyCharDriver *s = chr->opaque;
1258
1259 s->open_tag = 0;
1260 qemu_chr_be_generic_open(chr);
1261 return FALSE;
1262}
1263
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001264/* Called with chr_write_lock held. */
aliguori6f97dba2008-10-31 18:49:55 +00001265static void pty_chr_state(CharDriverState *chr, int connected)
1266{
1267 PtyCharDriver *s = chr->opaque;
1268
1269 if (!connected) {
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001270 if (s->open_tag) {
1271 g_source_remove(s->open_tag);
1272 s->open_tag = 0;
1273 }
Amit Shah26da70c2013-08-28 15:23:37 +05301274 remove_fd_in_watch(chr);
aliguori6f97dba2008-10-31 18:49:55 +00001275 s->connected = 0;
aliguori6f97dba2008-10-31 18:49:55 +00001276 /* (re-)connect poll interval for idle guests: once per second.
1277 * We check more frequently in case the guests sends data to
1278 * the virtual device linked to our pty. */
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301279 pty_chr_rearm_timer(chr, 1000);
aliguori6f97dba2008-10-31 18:49:55 +00001280 } else {
Paolo Bonzini85a67692013-04-19 17:32:07 +02001281 if (s->timer_tag) {
1282 g_source_remove(s->timer_tag);
1283 s->timer_tag = 0;
1284 }
1285 if (!s->connected) {
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001286 g_assert(s->open_tag == 0);
Paolo Bonzini85a67692013-04-19 17:32:07 +02001287 s->connected = 1;
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001288 s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
Gal Hammerac1b84d2014-02-25 12:12:35 +02001289 }
1290 if (!chr->fd_in_tag) {
Amit Shah7ba9add2013-08-28 15:18:29 +05301291 chr->fd_in_tag = io_add_watch_poll(s->fd, pty_chr_read_poll,
1292 pty_chr_read, chr);
Paolo Bonzini85a67692013-04-19 17:32:07 +02001293 }
aliguori6f97dba2008-10-31 18:49:55 +00001294 }
1295}
1296
aliguori6f97dba2008-10-31 18:49:55 +00001297static void pty_chr_close(struct CharDriverState *chr)
1298{
1299 PtyCharDriver *s = chr->opaque;
Anthony Liguori093d3a22013-03-05 23:21:20 +05301300 int fd;
aliguori6f97dba2008-10-31 18:49:55 +00001301
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001302 qemu_mutex_lock(&chr->chr_write_lock);
1303 pty_chr_state(chr, 0);
Anthony Liguori093d3a22013-03-05 23:21:20 +05301304 fd = g_io_channel_unix_get_fd(s->fd);
1305 g_io_channel_unref(s->fd);
1306 close(fd);
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301307 if (s->timer_tag) {
1308 g_source_remove(s->timer_tag);
Paolo Bonzini910b6362013-04-19 17:32:06 +02001309 s->timer_tag = 0;
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301310 }
Paolo Bonzini7b3621f2014-07-11 12:11:38 +02001311 qemu_mutex_unlock(&chr->chr_write_lock);
Anthony Liguori7267c092011-08-20 22:09:37 -05001312 g_free(s);
Hans de Goedea425d232011-11-19 10:22:43 +01001313 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
aliguori6f97dba2008-10-31 18:49:55 +00001314}
1315
Gerd Hoffmanne68c5952013-02-25 10:16:46 +01001316static CharDriverState *qemu_chr_open_pty(const char *id,
1317 ChardevReturn *ret)
aliguori6f97dba2008-10-31 18:49:55 +00001318{
1319 CharDriverState *chr;
1320 PtyCharDriver *s;
Gerd Hoffmanne68c5952013-02-25 10:16:46 +01001321 int master_fd, slave_fd;
aliguori6f97dba2008-10-31 18:49:55 +00001322 char pty_name[PATH_MAX];
aliguori6f97dba2008-10-31 18:49:55 +00001323
Michael Tokarev4efeabb2013-06-05 18:44:54 +04001324 master_fd = qemu_openpty_raw(&slave_fd, pty_name);
1325 if (master_fd < 0) {
Markus Armbruster1f514702012-02-07 15:09:08 +01001326 return NULL;
aliguori6f97dba2008-10-31 18:49:55 +00001327 }
1328
aliguori6f97dba2008-10-31 18:49:55 +00001329 close(slave_fd);
1330
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02001331 chr = qemu_chr_alloc();
aliguori6f97dba2008-10-31 18:49:55 +00001332
Michael Tokarev4efeabb2013-06-05 18:44:54 +04001333 chr->filename = g_strdup_printf("pty:%s", pty_name);
1334 ret->pty = g_strdup(pty_name);
Gerd Hoffmanne68c5952013-02-25 10:16:46 +01001335 ret->has_pty = true;
Lei Li58650212012-12-21 12:26:38 +08001336
Gerd Hoffmanne68c5952013-02-25 10:16:46 +01001337 fprintf(stderr, "char device redirected to %s (label %s)\n",
Michael Tokarev4efeabb2013-06-05 18:44:54 +04001338 pty_name, id);
Markus Armbrustera4e26042011-11-11 10:40:05 +01001339
1340 s = g_malloc0(sizeof(PtyCharDriver));
aliguori6f97dba2008-10-31 18:49:55 +00001341 chr->opaque = s;
1342 chr->chr_write = pty_chr_write;
1343 chr->chr_update_read_handler = pty_chr_update_read_handler;
1344 chr->chr_close = pty_chr_close;
Anthony Liguorie6a87ed2013-03-05 23:21:24 +05301345 chr->chr_add_watch = pty_chr_add_watch;
Michael Rothbd5c51e2013-06-07 15:19:53 -05001346 chr->explicit_be_open = true;
aliguori6f97dba2008-10-31 18:49:55 +00001347
Anthony Liguori093d3a22013-03-05 23:21:20 +05301348 s->fd = io_channel_from_fd(master_fd);
Anthony Liguori8aa33ca2013-03-05 23:21:26 +05301349 s->timer_tag = 0;
aliguori6f97dba2008-10-31 18:49:55 +00001350
Markus Armbruster1f514702012-02-07 15:09:08 +01001351 return chr;
aliguori6f97dba2008-10-31 18:49:55 +00001352}
1353
1354static void tty_serial_init(int fd, int speed,
1355 int parity, int data_bits, int stop_bits)
1356{
1357 struct termios tty;
1358 speed_t spd;
1359
1360#if 0
1361 printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
1362 speed, parity, data_bits, stop_bits);
1363#endif
1364 tcgetattr (fd, &tty);
1365
Stefan Weil45eea132009-10-26 16:10:10 +01001366#define check_speed(val) if (speed <= val) { spd = B##val; break; }
1367 speed = speed * 10 / 11;
1368 do {
1369 check_speed(50);
1370 check_speed(75);
1371 check_speed(110);
1372 check_speed(134);
1373 check_speed(150);
1374 check_speed(200);
1375 check_speed(300);
1376 check_speed(600);
1377 check_speed(1200);
1378 check_speed(1800);
1379 check_speed(2400);
1380 check_speed(4800);
1381 check_speed(9600);
1382 check_speed(19200);
1383 check_speed(38400);
1384 /* Non-Posix values follow. They may be unsupported on some systems. */
1385 check_speed(57600);
1386 check_speed(115200);
1387#ifdef B230400
1388 check_speed(230400);
1389#endif
1390#ifdef B460800
1391 check_speed(460800);
1392#endif
1393#ifdef B500000
1394 check_speed(500000);
1395#endif
1396#ifdef B576000
1397 check_speed(576000);
1398#endif
1399#ifdef B921600
1400 check_speed(921600);
1401#endif
1402#ifdef B1000000
1403 check_speed(1000000);
1404#endif
1405#ifdef B1152000
1406 check_speed(1152000);
1407#endif
1408#ifdef B1500000
1409 check_speed(1500000);
1410#endif
1411#ifdef B2000000
1412 check_speed(2000000);
1413#endif
1414#ifdef B2500000
1415 check_speed(2500000);
1416#endif
1417#ifdef B3000000
1418 check_speed(3000000);
1419#endif
1420#ifdef B3500000
1421 check_speed(3500000);
1422#endif
1423#ifdef B4000000
1424 check_speed(4000000);
1425#endif
aliguori6f97dba2008-10-31 18:49:55 +00001426 spd = B115200;
Stefan Weil45eea132009-10-26 16:10:10 +01001427 } while (0);
aliguori6f97dba2008-10-31 18:49:55 +00001428
1429 cfsetispeed(&tty, spd);
1430 cfsetospeed(&tty, spd);
1431
1432 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1433 |INLCR|IGNCR|ICRNL|IXON);
1434 tty.c_oflag |= OPOST;
1435 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
1436 tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
1437 switch(data_bits) {
1438 default:
1439 case 8:
1440 tty.c_cflag |= CS8;
1441 break;
1442 case 7:
1443 tty.c_cflag |= CS7;
1444 break;
1445 case 6:
1446 tty.c_cflag |= CS6;
1447 break;
1448 case 5:
1449 tty.c_cflag |= CS5;
1450 break;
1451 }
1452 switch(parity) {
1453 default:
1454 case 'N':
1455 break;
1456 case 'E':
1457 tty.c_cflag |= PARENB;
1458 break;
1459 case 'O':
1460 tty.c_cflag |= PARENB | PARODD;
1461 break;
1462 }
1463 if (stop_bits == 2)
1464 tty.c_cflag |= CSTOPB;
1465
1466 tcsetattr (fd, TCSANOW, &tty);
1467}
1468
1469static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
1470{
1471 FDCharDriver *s = chr->opaque;
1472
1473 switch(cmd) {
1474 case CHR_IOCTL_SERIAL_SET_PARAMS:
1475 {
1476 QEMUSerialSetParams *ssp = arg;
Anthony Liguoria29753f2013-03-05 23:21:19 +05301477 tty_serial_init(g_io_channel_unix_get_fd(s->fd_in),
1478 ssp->speed, ssp->parity,
aliguori6f97dba2008-10-31 18:49:55 +00001479 ssp->data_bits, ssp->stop_bits);
1480 }
1481 break;
1482 case CHR_IOCTL_SERIAL_SET_BREAK:
1483 {
1484 int enable = *(int *)arg;
Anthony Liguoria29753f2013-03-05 23:21:19 +05301485 if (enable) {
1486 tcsendbreak(g_io_channel_unix_get_fd(s->fd_in), 1);
1487 }
aliguori6f97dba2008-10-31 18:49:55 +00001488 }
1489 break;
1490 case CHR_IOCTL_SERIAL_GET_TIOCM:
1491 {
1492 int sarg = 0;
1493 int *targ = (int *)arg;
Anthony Liguoria29753f2013-03-05 23:21:19 +05301494 ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &sarg);
aliguori6f97dba2008-10-31 18:49:55 +00001495 *targ = 0;
aurel32b4abdfa2009-02-08 14:46:17 +00001496 if (sarg & TIOCM_CTS)
aliguori6f97dba2008-10-31 18:49:55 +00001497 *targ |= CHR_TIOCM_CTS;
aurel32b4abdfa2009-02-08 14:46:17 +00001498 if (sarg & TIOCM_CAR)
aliguori6f97dba2008-10-31 18:49:55 +00001499 *targ |= CHR_TIOCM_CAR;
aurel32b4abdfa2009-02-08 14:46:17 +00001500 if (sarg & TIOCM_DSR)
aliguori6f97dba2008-10-31 18:49:55 +00001501 *targ |= CHR_TIOCM_DSR;
aurel32b4abdfa2009-02-08 14:46:17 +00001502 if (sarg & TIOCM_RI)
aliguori6f97dba2008-10-31 18:49:55 +00001503 *targ |= CHR_TIOCM_RI;
aurel32b4abdfa2009-02-08 14:46:17 +00001504 if (sarg & TIOCM_DTR)
aliguori6f97dba2008-10-31 18:49:55 +00001505 *targ |= CHR_TIOCM_DTR;
aurel32b4abdfa2009-02-08 14:46:17 +00001506 if (sarg & TIOCM_RTS)
aliguori6f97dba2008-10-31 18:49:55 +00001507 *targ |= CHR_TIOCM_RTS;
1508 }
1509 break;
1510 case CHR_IOCTL_SERIAL_SET_TIOCM:
1511 {
1512 int sarg = *(int *)arg;
1513 int targ = 0;
Anthony Liguoria29753f2013-03-05 23:21:19 +05301514 ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &targ);
aurel32b4abdfa2009-02-08 14:46:17 +00001515 targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
1516 | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
1517 if (sarg & CHR_TIOCM_CTS)
1518 targ |= TIOCM_CTS;
1519 if (sarg & CHR_TIOCM_CAR)
1520 targ |= TIOCM_CAR;
1521 if (sarg & CHR_TIOCM_DSR)
1522 targ |= TIOCM_DSR;
1523 if (sarg & CHR_TIOCM_RI)
1524 targ |= TIOCM_RI;
1525 if (sarg & CHR_TIOCM_DTR)
aliguori6f97dba2008-10-31 18:49:55 +00001526 targ |= TIOCM_DTR;
aurel32b4abdfa2009-02-08 14:46:17 +00001527 if (sarg & CHR_TIOCM_RTS)
aliguori6f97dba2008-10-31 18:49:55 +00001528 targ |= TIOCM_RTS;
Anthony Liguoria29753f2013-03-05 23:21:19 +05301529 ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ);
aliguori6f97dba2008-10-31 18:49:55 +00001530 }
1531 break;
1532 default:
1533 return -ENOTSUP;
1534 }
1535 return 0;
1536}
1537
David Ahern4266a132010-02-10 18:27:17 -07001538static void qemu_chr_close_tty(CharDriverState *chr)
1539{
1540 FDCharDriver *s = chr->opaque;
1541 int fd = -1;
1542
1543 if (s) {
Anthony Liguoria29753f2013-03-05 23:21:19 +05301544 fd = g_io_channel_unix_get_fd(s->fd_in);
David Ahern4266a132010-02-10 18:27:17 -07001545 }
1546
1547 fd_chr_close(chr);
1548
1549 if (fd >= 0) {
1550 close(fd);
1551 }
1552}
1553
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01001554static CharDriverState *qemu_chr_open_tty_fd(int fd)
1555{
1556 CharDriverState *chr;
1557
1558 tty_serial_init(fd, 115200, 'N', 8, 1);
1559 chr = qemu_chr_open_fd(fd, fd);
1560 chr->chr_ioctl = tty_serial_ioctl;
1561 chr->chr_close = qemu_chr_close_tty;
1562 return chr;
1563}
aliguori6f97dba2008-10-31 18:49:55 +00001564#endif /* __linux__ || __sun__ */
1565
1566#if defined(__linux__)
Gerd Hoffmanne5514982012-12-19 16:35:42 +01001567
1568#define HAVE_CHARDEV_PARPORT 1
1569
aliguori6f97dba2008-10-31 18:49:55 +00001570typedef struct {
1571 int fd;
1572 int mode;
1573} ParallelCharDriver;
1574
1575static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
1576{
1577 if (s->mode != mode) {
1578 int m = mode;
1579 if (ioctl(s->fd, PPSETMODE, &m) < 0)
1580 return 0;
1581 s->mode = mode;
1582 }
1583 return 1;
1584}
1585
1586static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1587{
1588 ParallelCharDriver *drv = chr->opaque;
1589 int fd = drv->fd;
1590 uint8_t b;
1591
1592 switch(cmd) {
1593 case CHR_IOCTL_PP_READ_DATA:
1594 if (ioctl(fd, PPRDATA, &b) < 0)
1595 return -ENOTSUP;
1596 *(uint8_t *)arg = b;
1597 break;
1598 case CHR_IOCTL_PP_WRITE_DATA:
1599 b = *(uint8_t *)arg;
1600 if (ioctl(fd, PPWDATA, &b) < 0)
1601 return -ENOTSUP;
1602 break;
1603 case CHR_IOCTL_PP_READ_CONTROL:
1604 if (ioctl(fd, PPRCONTROL, &b) < 0)
1605 return -ENOTSUP;
1606 /* Linux gives only the lowest bits, and no way to know data
1607 direction! For better compatibility set the fixed upper
1608 bits. */
1609 *(uint8_t *)arg = b | 0xc0;
1610 break;
1611 case CHR_IOCTL_PP_WRITE_CONTROL:
1612 b = *(uint8_t *)arg;
1613 if (ioctl(fd, PPWCONTROL, &b) < 0)
1614 return -ENOTSUP;
1615 break;
1616 case CHR_IOCTL_PP_READ_STATUS:
1617 if (ioctl(fd, PPRSTATUS, &b) < 0)
1618 return -ENOTSUP;
1619 *(uint8_t *)arg = b;
1620 break;
1621 case CHR_IOCTL_PP_DATA_DIR:
1622 if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
1623 return -ENOTSUP;
1624 break;
1625 case CHR_IOCTL_PP_EPP_READ_ADDR:
1626 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1627 struct ParallelIOArg *parg = arg;
1628 int n = read(fd, parg->buffer, parg->count);
1629 if (n != parg->count) {
1630 return -EIO;
1631 }
1632 }
1633 break;
1634 case CHR_IOCTL_PP_EPP_READ:
1635 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1636 struct ParallelIOArg *parg = arg;
1637 int n = read(fd, parg->buffer, parg->count);
1638 if (n != parg->count) {
1639 return -EIO;
1640 }
1641 }
1642 break;
1643 case CHR_IOCTL_PP_EPP_WRITE_ADDR:
1644 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1645 struct ParallelIOArg *parg = arg;
1646 int n = write(fd, parg->buffer, parg->count);
1647 if (n != parg->count) {
1648 return -EIO;
1649 }
1650 }
1651 break;
1652 case CHR_IOCTL_PP_EPP_WRITE:
1653 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1654 struct ParallelIOArg *parg = arg;
1655 int n = write(fd, parg->buffer, parg->count);
1656 if (n != parg->count) {
1657 return -EIO;
1658 }
1659 }
1660 break;
1661 default:
1662 return -ENOTSUP;
1663 }
1664 return 0;
1665}
1666
1667static void pp_close(CharDriverState *chr)
1668{
1669 ParallelCharDriver *drv = chr->opaque;
1670 int fd = drv->fd;
1671
1672 pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
1673 ioctl(fd, PPRELEASE);
1674 close(fd);
Anthony Liguori7267c092011-08-20 22:09:37 -05001675 g_free(drv);
Hans de Goedea425d232011-11-19 10:22:43 +01001676 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
aliguori6f97dba2008-10-31 18:49:55 +00001677}
1678
Gerd Hoffmann88a946d2013-01-10 14:20:58 +01001679static CharDriverState *qemu_chr_open_pp_fd(int fd)
aliguori6f97dba2008-10-31 18:49:55 +00001680{
1681 CharDriverState *chr;
1682 ParallelCharDriver *drv;
aliguori6f97dba2008-10-31 18:49:55 +00001683
1684 if (ioctl(fd, PPCLAIM) < 0) {
1685 close(fd);
Markus Armbruster1f514702012-02-07 15:09:08 +01001686 return NULL;
aliguori6f97dba2008-10-31 18:49:55 +00001687 }
1688
Anthony Liguori7267c092011-08-20 22:09:37 -05001689 drv = g_malloc0(sizeof(ParallelCharDriver));
aliguori6f97dba2008-10-31 18:49:55 +00001690 drv->fd = fd;
1691 drv->mode = IEEE1284_MODE_COMPAT;
1692
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02001693 chr = qemu_chr_alloc();
aliguori6f97dba2008-10-31 18:49:55 +00001694 chr->chr_write = null_chr_write;
1695 chr->chr_ioctl = pp_ioctl;
1696 chr->chr_close = pp_close;
1697 chr->opaque = drv;
1698
Markus Armbruster1f514702012-02-07 15:09:08 +01001699 return chr;
aliguori6f97dba2008-10-31 18:49:55 +00001700}
1701#endif /* __linux__ */
1702
Aurelien Jarnoa167ba52009-11-29 18:00:41 +01001703#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
Gerd Hoffmanne5514982012-12-19 16:35:42 +01001704
1705#define HAVE_CHARDEV_PARPORT 1
1706
blueswir16972f932008-11-22 20:49:12 +00001707static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1708{
Stefan Weile0efb992011-02-23 19:09:16 +01001709 int fd = (int)(intptr_t)chr->opaque;
blueswir16972f932008-11-22 20:49:12 +00001710 uint8_t b;
1711
1712 switch(cmd) {
1713 case CHR_IOCTL_PP_READ_DATA:
1714 if (ioctl(fd, PPIGDATA, &b) < 0)
1715 return -ENOTSUP;
1716 *(uint8_t *)arg = b;
1717 break;
1718 case CHR_IOCTL_PP_WRITE_DATA:
1719 b = *(uint8_t *)arg;
1720 if (ioctl(fd, PPISDATA, &b) < 0)
1721 return -ENOTSUP;
1722 break;
1723 case CHR_IOCTL_PP_READ_CONTROL:
1724 if (ioctl(fd, PPIGCTRL, &b) < 0)
1725 return -ENOTSUP;
1726 *(uint8_t *)arg = b;
1727 break;
1728 case CHR_IOCTL_PP_WRITE_CONTROL:
1729 b = *(uint8_t *)arg;
1730 if (ioctl(fd, PPISCTRL, &b) < 0)
1731 return -ENOTSUP;
1732 break;
1733 case CHR_IOCTL_PP_READ_STATUS:
1734 if (ioctl(fd, PPIGSTATUS, &b) < 0)
1735 return -ENOTSUP;
1736 *(uint8_t *)arg = b;
1737 break;
1738 default:
1739 return -ENOTSUP;
1740 }
1741 return 0;
1742}
1743
Gerd Hoffmann88a946d2013-01-10 14:20:58 +01001744static CharDriverState *qemu_chr_open_pp_fd(int fd)
blueswir16972f932008-11-22 20:49:12 +00001745{
1746 CharDriverState *chr;
blueswir16972f932008-11-22 20:49:12 +00001747
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02001748 chr = qemu_chr_alloc();
Stefan Weile0efb992011-02-23 19:09:16 +01001749 chr->opaque = (void *)(intptr_t)fd;
blueswir16972f932008-11-22 20:49:12 +00001750 chr->chr_write = null_chr_write;
1751 chr->chr_ioctl = pp_ioctl;
Michael Rothbd5c51e2013-06-07 15:19:53 -05001752 chr->explicit_be_open = true;
Markus Armbruster1f514702012-02-07 15:09:08 +01001753 return chr;
blueswir16972f932008-11-22 20:49:12 +00001754}
1755#endif
1756
aliguori6f97dba2008-10-31 18:49:55 +00001757#else /* _WIN32 */
1758
1759typedef struct {
1760 int max_size;
1761 HANDLE hcom, hrecv, hsend;
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001762 OVERLAPPED orecv;
aliguori6f97dba2008-10-31 18:49:55 +00001763 BOOL fpipe;
1764 DWORD len;
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001765
1766 /* Protected by the CharDriverState chr_write_lock. */
1767 OVERLAPPED osend;
aliguori6f97dba2008-10-31 18:49:55 +00001768} WinCharState;
1769
Fabien Chouteaudb418a02011-10-06 16:37:51 +02001770typedef struct {
1771 HANDLE hStdIn;
1772 HANDLE hInputReadyEvent;
1773 HANDLE hInputDoneEvent;
1774 HANDLE hInputThread;
1775 uint8_t win_stdio_buf;
1776} WinStdioCharState;
1777
aliguori6f97dba2008-10-31 18:49:55 +00001778#define NSENDBUF 2048
1779#define NRECVBUF 2048
1780#define MAXCONNECT 1
1781#define NTIMEOUT 5000
1782
1783static int win_chr_poll(void *opaque);
1784static int win_chr_pipe_poll(void *opaque);
1785
1786static void win_chr_close(CharDriverState *chr)
1787{
1788 WinCharState *s = chr->opaque;
1789
1790 if (s->hsend) {
1791 CloseHandle(s->hsend);
1792 s->hsend = NULL;
1793 }
1794 if (s->hrecv) {
1795 CloseHandle(s->hrecv);
1796 s->hrecv = NULL;
1797 }
1798 if (s->hcom) {
1799 CloseHandle(s->hcom);
1800 s->hcom = NULL;
1801 }
1802 if (s->fpipe)
1803 qemu_del_polling_cb(win_chr_pipe_poll, chr);
1804 else
1805 qemu_del_polling_cb(win_chr_poll, chr);
Amit Shah793cbfb2009-08-11 21:27:48 +05301806
Hans de Goedea425d232011-11-19 10:22:43 +01001807 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
aliguori6f97dba2008-10-31 18:49:55 +00001808}
1809
1810static int win_chr_init(CharDriverState *chr, const char *filename)
1811{
1812 WinCharState *s = chr->opaque;
1813 COMMCONFIG comcfg;
1814 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
1815 COMSTAT comstat;
1816 DWORD size;
1817 DWORD err;
1818
1819 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1820 if (!s->hsend) {
1821 fprintf(stderr, "Failed CreateEvent\n");
1822 goto fail;
1823 }
1824 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1825 if (!s->hrecv) {
1826 fprintf(stderr, "Failed CreateEvent\n");
1827 goto fail;
1828 }
1829
1830 s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1831 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
1832 if (s->hcom == INVALID_HANDLE_VALUE) {
1833 fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
1834 s->hcom = NULL;
1835 goto fail;
1836 }
1837
1838 if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
1839 fprintf(stderr, "Failed SetupComm\n");
1840 goto fail;
1841 }
1842
1843 ZeroMemory(&comcfg, sizeof(COMMCONFIG));
1844 size = sizeof(COMMCONFIG);
1845 GetDefaultCommConfig(filename, &comcfg, &size);
1846 comcfg.dcb.DCBlength = sizeof(DCB);
1847 CommConfigDialog(filename, NULL, &comcfg);
1848
1849 if (!SetCommState(s->hcom, &comcfg.dcb)) {
1850 fprintf(stderr, "Failed SetCommState\n");
1851 goto fail;
1852 }
1853
1854 if (!SetCommMask(s->hcom, EV_ERR)) {
1855 fprintf(stderr, "Failed SetCommMask\n");
1856 goto fail;
1857 }
1858
1859 cto.ReadIntervalTimeout = MAXDWORD;
1860 if (!SetCommTimeouts(s->hcom, &cto)) {
1861 fprintf(stderr, "Failed SetCommTimeouts\n");
1862 goto fail;
1863 }
1864
1865 if (!ClearCommError(s->hcom, &err, &comstat)) {
1866 fprintf(stderr, "Failed ClearCommError\n");
1867 goto fail;
1868 }
1869 qemu_add_polling_cb(win_chr_poll, chr);
1870 return 0;
1871
1872 fail:
1873 win_chr_close(chr);
1874 return -1;
1875}
1876
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02001877/* Called with chr_write_lock held. */
aliguori6f97dba2008-10-31 18:49:55 +00001878static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
1879{
1880 WinCharState *s = chr->opaque;
1881 DWORD len, ret, size, err;
1882
1883 len = len1;
1884 ZeroMemory(&s->osend, sizeof(s->osend));
1885 s->osend.hEvent = s->hsend;
1886 while (len > 0) {
1887 if (s->hsend)
1888 ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
1889 else
1890 ret = WriteFile(s->hcom, buf, len, &size, NULL);
1891 if (!ret) {
1892 err = GetLastError();
1893 if (err == ERROR_IO_PENDING) {
1894 ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
1895 if (ret) {
1896 buf += size;
1897 len -= size;
1898 } else {
1899 break;
1900 }
1901 } else {
1902 break;
1903 }
1904 } else {
1905 buf += size;
1906 len -= size;
1907 }
1908 }
1909 return len1 - len;
1910}
1911
1912static int win_chr_read_poll(CharDriverState *chr)
1913{
1914 WinCharState *s = chr->opaque;
1915
Anthony Liguori909cda12011-08-15 11:17:31 -05001916 s->max_size = qemu_chr_be_can_write(chr);
aliguori6f97dba2008-10-31 18:49:55 +00001917 return s->max_size;
1918}
1919
1920static void win_chr_readfile(CharDriverState *chr)
1921{
1922 WinCharState *s = chr->opaque;
1923 int ret, err;
Amit Shah9bd78542009-11-03 19:59:54 +05301924 uint8_t buf[READ_BUF_LEN];
aliguori6f97dba2008-10-31 18:49:55 +00001925 DWORD size;
1926
1927 ZeroMemory(&s->orecv, sizeof(s->orecv));
1928 s->orecv.hEvent = s->hrecv;
1929 ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
1930 if (!ret) {
1931 err = GetLastError();
1932 if (err == ERROR_IO_PENDING) {
1933 ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
1934 }
1935 }
1936
1937 if (size > 0) {
Anthony Liguorifa5efcc2011-08-15 11:17:30 -05001938 qemu_chr_be_write(chr, buf, size);
aliguori6f97dba2008-10-31 18:49:55 +00001939 }
1940}
1941
1942static void win_chr_read(CharDriverState *chr)
1943{
1944 WinCharState *s = chr->opaque;
1945
1946 if (s->len > s->max_size)
1947 s->len = s->max_size;
1948 if (s->len == 0)
1949 return;
1950
1951 win_chr_readfile(chr);
1952}
1953
1954static int win_chr_poll(void *opaque)
1955{
1956 CharDriverState *chr = opaque;
1957 WinCharState *s = chr->opaque;
1958 COMSTAT status;
1959 DWORD comerr;
1960
1961 ClearCommError(s->hcom, &comerr, &status);
1962 if (status.cbInQue > 0) {
1963 s->len = status.cbInQue;
1964 win_chr_read_poll(chr);
1965 win_chr_read(chr);
1966 return 1;
1967 }
1968 return 0;
1969}
1970
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01001971static CharDriverState *qemu_chr_open_win_path(const char *filename)
aliguori6f97dba2008-10-31 18:49:55 +00001972{
1973 CharDriverState *chr;
1974 WinCharState *s;
1975
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02001976 chr = qemu_chr_alloc();
Anthony Liguori7267c092011-08-20 22:09:37 -05001977 s = g_malloc0(sizeof(WinCharState));
aliguori6f97dba2008-10-31 18:49:55 +00001978 chr->opaque = s;
1979 chr->chr_write = win_chr_write;
1980 chr->chr_close = win_chr_close;
1981
1982 if (win_chr_init(chr, filename) < 0) {
Stefan Weil2e02e182011-10-07 07:38:46 +02001983 g_free(s);
1984 g_free(chr);
Markus Armbruster1f514702012-02-07 15:09:08 +01001985 return NULL;
aliguori6f97dba2008-10-31 18:49:55 +00001986 }
Markus Armbruster1f514702012-02-07 15:09:08 +01001987 return chr;
aliguori6f97dba2008-10-31 18:49:55 +00001988}
1989
1990static int win_chr_pipe_poll(void *opaque)
1991{
1992 CharDriverState *chr = opaque;
1993 WinCharState *s = chr->opaque;
1994 DWORD size;
1995
1996 PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
1997 if (size > 0) {
1998 s->len = size;
1999 win_chr_read_poll(chr);
2000 win_chr_read(chr);
2001 return 1;
2002 }
2003 return 0;
2004}
2005
2006static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
2007{
2008 WinCharState *s = chr->opaque;
2009 OVERLAPPED ov;
2010 int ret;
2011 DWORD size;
Corey Minyard9f781162014-10-02 11:17:33 -05002012 char openname[CHR_MAX_FILENAME_SIZE];
aliguori6f97dba2008-10-31 18:49:55 +00002013
2014 s->fpipe = TRUE;
2015
2016 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2017 if (!s->hsend) {
2018 fprintf(stderr, "Failed CreateEvent\n");
2019 goto fail;
2020 }
2021 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2022 if (!s->hrecv) {
2023 fprintf(stderr, "Failed CreateEvent\n");
2024 goto fail;
2025 }
2026
2027 snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
2028 s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2029 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
2030 PIPE_WAIT,
2031 MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
2032 if (s->hcom == INVALID_HANDLE_VALUE) {
2033 fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
2034 s->hcom = NULL;
2035 goto fail;
2036 }
2037
2038 ZeroMemory(&ov, sizeof(ov));
2039 ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2040 ret = ConnectNamedPipe(s->hcom, &ov);
2041 if (ret) {
2042 fprintf(stderr, "Failed ConnectNamedPipe\n");
2043 goto fail;
2044 }
2045
2046 ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
2047 if (!ret) {
2048 fprintf(stderr, "Failed GetOverlappedResult\n");
2049 if (ov.hEvent) {
2050 CloseHandle(ov.hEvent);
2051 ov.hEvent = NULL;
2052 }
2053 goto fail;
2054 }
2055
2056 if (ov.hEvent) {
2057 CloseHandle(ov.hEvent);
2058 ov.hEvent = NULL;
2059 }
2060 qemu_add_polling_cb(win_chr_pipe_poll, chr);
2061 return 0;
2062
2063 fail:
2064 win_chr_close(chr);
2065 return -1;
2066}
2067
2068
Gerd Hoffmann548cbb32013-02-25 11:50:55 +01002069static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
aliguori6f97dba2008-10-31 18:49:55 +00002070{
Gerd Hoffmann548cbb32013-02-25 11:50:55 +01002071 const char *filename = opts->device;
aliguori6f97dba2008-10-31 18:49:55 +00002072 CharDriverState *chr;
2073 WinCharState *s;
2074
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02002075 chr = qemu_chr_alloc();
Anthony Liguori7267c092011-08-20 22:09:37 -05002076 s = g_malloc0(sizeof(WinCharState));
aliguori6f97dba2008-10-31 18:49:55 +00002077 chr->opaque = s;
2078 chr->chr_write = win_chr_write;
2079 chr->chr_close = win_chr_close;
2080
2081 if (win_chr_pipe_init(chr, filename) < 0) {
Stefan Weil2e02e182011-10-07 07:38:46 +02002082 g_free(s);
2083 g_free(chr);
Markus Armbruster1f514702012-02-07 15:09:08 +01002084 return NULL;
aliguori6f97dba2008-10-31 18:49:55 +00002085 }
Markus Armbruster1f514702012-02-07 15:09:08 +01002086 return chr;
aliguori6f97dba2008-10-31 18:49:55 +00002087}
2088
Markus Armbruster1f514702012-02-07 15:09:08 +01002089static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
aliguori6f97dba2008-10-31 18:49:55 +00002090{
2091 CharDriverState *chr;
2092 WinCharState *s;
2093
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02002094 chr = qemu_chr_alloc();
Anthony Liguori7267c092011-08-20 22:09:37 -05002095 s = g_malloc0(sizeof(WinCharState));
aliguori6f97dba2008-10-31 18:49:55 +00002096 s->hcom = fd_out;
2097 chr->opaque = s;
2098 chr->chr_write = win_chr_write;
Markus Armbruster1f514702012-02-07 15:09:08 +01002099 return chr;
aliguori6f97dba2008-10-31 18:49:55 +00002100}
2101
Gerd Hoffmannd9ac3742013-02-25 11:48:06 +01002102static CharDriverState *qemu_chr_open_win_con(void)
aliguori6f97dba2008-10-31 18:49:55 +00002103{
Markus Armbruster1f514702012-02-07 15:09:08 +01002104 return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
aliguori6f97dba2008-10-31 18:49:55 +00002105}
2106
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002107static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
2108{
2109 HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
2110 DWORD dwSize;
2111 int len1;
2112
2113 len1 = len;
2114
2115 while (len1 > 0) {
2116 if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
2117 break;
2118 }
2119 buf += dwSize;
2120 len1 -= dwSize;
2121 }
2122
2123 return len - len1;
2124}
2125
2126static void win_stdio_wait_func(void *opaque)
2127{
2128 CharDriverState *chr = opaque;
2129 WinStdioCharState *stdio = chr->opaque;
2130 INPUT_RECORD buf[4];
2131 int ret;
2132 DWORD dwSize;
2133 int i;
2134
Stefan Weildff74242013-12-07 14:48:04 +01002135 ret = ReadConsoleInput(stdio->hStdIn, buf, ARRAY_SIZE(buf), &dwSize);
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002136
2137 if (!ret) {
2138 /* Avoid error storm */
2139 qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
2140 return;
2141 }
2142
2143 for (i = 0; i < dwSize; i++) {
2144 KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;
2145
2146 if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
2147 int j;
2148 if (kev->uChar.AsciiChar != 0) {
2149 for (j = 0; j < kev->wRepeatCount; j++) {
2150 if (qemu_chr_be_can_write(chr)) {
2151 uint8_t c = kev->uChar.AsciiChar;
2152 qemu_chr_be_write(chr, &c, 1);
2153 }
2154 }
2155 }
2156 }
2157 }
2158}
2159
2160static DWORD WINAPI win_stdio_thread(LPVOID param)
2161{
2162 CharDriverState *chr = param;
2163 WinStdioCharState *stdio = chr->opaque;
2164 int ret;
2165 DWORD dwSize;
2166
2167 while (1) {
2168
2169 /* Wait for one byte */
2170 ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);
2171
2172 /* Exit in case of error, continue if nothing read */
2173 if (!ret) {
2174 break;
2175 }
2176 if (!dwSize) {
2177 continue;
2178 }
2179
2180 /* Some terminal emulator returns \r\n for Enter, just pass \n */
2181 if (stdio->win_stdio_buf == '\r') {
2182 continue;
2183 }
2184
2185 /* Signal the main thread and wait until the byte was eaten */
2186 if (!SetEvent(stdio->hInputReadyEvent)) {
2187 break;
2188 }
2189 if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
2190 != WAIT_OBJECT_0) {
2191 break;
2192 }
2193 }
2194
2195 qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
2196 return 0;
2197}
2198
2199static void win_stdio_thread_wait_func(void *opaque)
2200{
2201 CharDriverState *chr = opaque;
2202 WinStdioCharState *stdio = chr->opaque;
2203
2204 if (qemu_chr_be_can_write(chr)) {
2205 qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
2206 }
2207
2208 SetEvent(stdio->hInputDoneEvent);
2209}
2210
2211static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo)
2212{
2213 WinStdioCharState *stdio = chr->opaque;
2214 DWORD dwMode = 0;
2215
2216 GetConsoleMode(stdio->hStdIn, &dwMode);
2217
2218 if (echo) {
2219 SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
2220 } else {
2221 SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
2222 }
2223}
2224
2225static void win_stdio_close(CharDriverState *chr)
2226{
2227 WinStdioCharState *stdio = chr->opaque;
2228
2229 if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
2230 CloseHandle(stdio->hInputReadyEvent);
2231 }
2232 if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
2233 CloseHandle(stdio->hInputDoneEvent);
2234 }
2235 if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
2236 TerminateThread(stdio->hInputThread, 0);
2237 }
2238
2239 g_free(chr->opaque);
2240 g_free(chr);
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002241}
2242
Gerd Hoffmann7c358032013-02-21 12:34:58 +01002243static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002244{
2245 CharDriverState *chr;
2246 WinStdioCharState *stdio;
2247 DWORD dwMode;
2248 int is_console = 0;
2249
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02002250 chr = qemu_chr_alloc();
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002251 stdio = g_malloc0(sizeof(WinStdioCharState));
2252
2253 stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
2254 if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
2255 fprintf(stderr, "cannot open stdio: invalid handle\n");
2256 exit(1);
2257 }
2258
2259 is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
2260
2261 chr->opaque = stdio;
2262 chr->chr_write = win_stdio_write;
2263 chr->chr_close = win_stdio_close;
2264
Anthony Liguoried7a1542013-03-05 23:21:17 +05302265 if (is_console) {
2266 if (qemu_add_wait_object(stdio->hStdIn,
2267 win_stdio_wait_func, chr)) {
2268 fprintf(stderr, "qemu_add_wait_object: failed\n");
2269 }
2270 } else {
2271 DWORD dwId;
2272
2273 stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2274 stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2275 stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread,
2276 chr, 0, &dwId);
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002277
Anthony Liguoried7a1542013-03-05 23:21:17 +05302278 if (stdio->hInputThread == INVALID_HANDLE_VALUE
2279 || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
2280 || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
2281 fprintf(stderr, "cannot create stdio thread or event\n");
2282 exit(1);
2283 }
2284 if (qemu_add_wait_object(stdio->hInputReadyEvent,
2285 win_stdio_thread_wait_func, chr)) {
2286 fprintf(stderr, "qemu_add_wait_object: failed\n");
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002287 }
2288 }
2289
2290 dwMode |= ENABLE_LINE_INPUT;
2291
Anthony Liguoried7a1542013-03-05 23:21:17 +05302292 if (is_console) {
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002293 /* set the terminal in raw mode */
2294 /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
2295 dwMode |= ENABLE_PROCESSED_INPUT;
2296 }
2297
2298 SetConsoleMode(stdio->hStdIn, dwMode);
2299
2300 chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
2301 qemu_chr_fe_set_echo(chr, false);
2302
Markus Armbruster1f514702012-02-07 15:09:08 +01002303 return chr;
Fabien Chouteaudb418a02011-10-06 16:37:51 +02002304}
aliguori6f97dba2008-10-31 18:49:55 +00002305#endif /* !_WIN32 */
2306
Anthony Liguori5ab82112013-03-05 23:21:31 +05302307
aliguori6f97dba2008-10-31 18:49:55 +00002308/***********************************************************/
2309/* UDP Net console */
2310
2311typedef struct {
2312 int fd;
Anthony Liguori76a96442013-03-05 23:21:21 +05302313 GIOChannel *chan;
Amit Shah9bd78542009-11-03 19:59:54 +05302314 uint8_t buf[READ_BUF_LEN];
aliguori6f97dba2008-10-31 18:49:55 +00002315 int bufcnt;
2316 int bufptr;
2317 int max_size;
2318} NetCharDriver;
2319
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02002320/* Called with chr_write_lock held. */
aliguori6f97dba2008-10-31 18:49:55 +00002321static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2322{
2323 NetCharDriver *s = chr->opaque;
Anthony Liguori76a96442013-03-05 23:21:21 +05302324 gsize bytes_written;
2325 GIOStatus status;
aliguori6f97dba2008-10-31 18:49:55 +00002326
Anthony Liguori76a96442013-03-05 23:21:21 +05302327 status = g_io_channel_write_chars(s->chan, (const gchar *)buf, len, &bytes_written, NULL);
2328 if (status == G_IO_STATUS_EOF) {
2329 return 0;
2330 } else if (status != G_IO_STATUS_NORMAL) {
2331 return -1;
2332 }
2333
2334 return bytes_written;
aliguori6f97dba2008-10-31 18:49:55 +00002335}
2336
2337static int udp_chr_read_poll(void *opaque)
2338{
2339 CharDriverState *chr = opaque;
2340 NetCharDriver *s = chr->opaque;
2341
Anthony Liguori909cda12011-08-15 11:17:31 -05002342 s->max_size = qemu_chr_be_can_write(chr);
aliguori6f97dba2008-10-31 18:49:55 +00002343
2344 /* If there were any stray characters in the queue process them
2345 * first
2346 */
2347 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
Anthony Liguorifa5efcc2011-08-15 11:17:30 -05002348 qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
aliguori6f97dba2008-10-31 18:49:55 +00002349 s->bufptr++;
Anthony Liguori909cda12011-08-15 11:17:31 -05002350 s->max_size = qemu_chr_be_can_write(chr);
aliguori6f97dba2008-10-31 18:49:55 +00002351 }
2352 return s->max_size;
2353}
2354
Anthony Liguori76a96442013-03-05 23:21:21 +05302355static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
aliguori6f97dba2008-10-31 18:49:55 +00002356{
2357 CharDriverState *chr = opaque;
2358 NetCharDriver *s = chr->opaque;
Anthony Liguori76a96442013-03-05 23:21:21 +05302359 gsize bytes_read = 0;
2360 GIOStatus status;
aliguori6f97dba2008-10-31 18:49:55 +00002361
Paolo Bonzinicdbf6e12013-04-19 17:32:08 +02002362 if (s->max_size == 0) {
2363 return TRUE;
2364 }
Anthony Liguori76a96442013-03-05 23:21:21 +05302365 status = g_io_channel_read_chars(s->chan, (gchar *)s->buf, sizeof(s->buf),
2366 &bytes_read, NULL);
2367 s->bufcnt = bytes_read;
aliguori6f97dba2008-10-31 18:49:55 +00002368 s->bufptr = s->bufcnt;
Anthony Liguori76a96442013-03-05 23:21:21 +05302369 if (status != G_IO_STATUS_NORMAL) {
Amit Shah26da70c2013-08-28 15:23:37 +05302370 remove_fd_in_watch(chr);
Anthony Liguori76a96442013-03-05 23:21:21 +05302371 return FALSE;
2372 }
aliguori6f97dba2008-10-31 18:49:55 +00002373
2374 s->bufptr = 0;
2375 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
Anthony Liguorifa5efcc2011-08-15 11:17:30 -05002376 qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
aliguori6f97dba2008-10-31 18:49:55 +00002377 s->bufptr++;
Anthony Liguori909cda12011-08-15 11:17:31 -05002378 s->max_size = qemu_chr_be_can_write(chr);
aliguori6f97dba2008-10-31 18:49:55 +00002379 }
Anthony Liguori76a96442013-03-05 23:21:21 +05302380
2381 return TRUE;
aliguori6f97dba2008-10-31 18:49:55 +00002382}
2383
2384static void udp_chr_update_read_handler(CharDriverState *chr)
2385{
2386 NetCharDriver *s = chr->opaque;
2387
Amit Shah26da70c2013-08-28 15:23:37 +05302388 remove_fd_in_watch(chr);
Anthony Liguori76a96442013-03-05 23:21:21 +05302389 if (s->chan) {
Amit Shah7ba9add2013-08-28 15:18:29 +05302390 chr->fd_in_tag = io_add_watch_poll(s->chan, udp_chr_read_poll,
2391 udp_chr_read, chr);
aliguori6f97dba2008-10-31 18:49:55 +00002392 }
2393}
2394
aliguori819f56b2009-03-28 17:58:14 +00002395static void udp_chr_close(CharDriverState *chr)
2396{
2397 NetCharDriver *s = chr->opaque;
Amit Shah26da70c2013-08-28 15:23:37 +05302398
2399 remove_fd_in_watch(chr);
Anthony Liguori76a96442013-03-05 23:21:21 +05302400 if (s->chan) {
2401 g_io_channel_unref(s->chan);
aliguori819f56b2009-03-28 17:58:14 +00002402 closesocket(s->fd);
2403 }
Anthony Liguori7267c092011-08-20 22:09:37 -05002404 g_free(s);
Hans de Goedea425d232011-11-19 10:22:43 +01002405 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
aliguori819f56b2009-03-28 17:58:14 +00002406}
2407
Gerd Hoffmann3ecc0592013-02-27 14:10:47 +01002408static CharDriverState *qemu_chr_open_udp_fd(int fd)
aliguori6f97dba2008-10-31 18:49:55 +00002409{
2410 CharDriverState *chr = NULL;
2411 NetCharDriver *s = NULL;
aliguori6f97dba2008-10-31 18:49:55 +00002412
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02002413 chr = qemu_chr_alloc();
Anthony Liguori7267c092011-08-20 22:09:37 -05002414 s = g_malloc0(sizeof(NetCharDriver));
aliguori6f97dba2008-10-31 18:49:55 +00002415
aliguori6f97dba2008-10-31 18:49:55 +00002416 s->fd = fd;
Anthony Liguori76a96442013-03-05 23:21:21 +05302417 s->chan = io_channel_from_socket(s->fd);
aliguori6f97dba2008-10-31 18:49:55 +00002418 s->bufcnt = 0;
2419 s->bufptr = 0;
2420 chr->opaque = s;
2421 chr->chr_write = udp_chr_write;
2422 chr->chr_update_read_handler = udp_chr_update_read_handler;
aliguori819f56b2009-03-28 17:58:14 +00002423 chr->chr_close = udp_chr_close;
Michael Rothbd5c51e2013-06-07 15:19:53 -05002424 /* be isn't opened until we get a connection */
2425 chr->explicit_be_open = true;
Markus Armbruster1f514702012-02-07 15:09:08 +01002426 return chr;
Gerd Hoffmann3ecc0592013-02-27 14:10:47 +01002427}
aliguori6f97dba2008-10-31 18:49:55 +00002428
aliguori6f97dba2008-10-31 18:49:55 +00002429/***********************************************************/
2430/* TCP Net console */
2431
2432typedef struct {
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302433
2434 GIOChannel *chan, *listen_chan;
Amit Shah7ba9add2013-08-28 15:18:29 +05302435 guint listen_tag;
aliguori6f97dba2008-10-31 18:49:55 +00002436 int fd, listen_fd;
2437 int connected;
2438 int max_size;
2439 int do_telnetopt;
2440 int do_nodelay;
2441 int is_unix;
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002442 int *read_msgfds;
2443 int read_msgfds_num;
Nikolay Nikolaevd39aac72014-05-27 15:04:02 +03002444 int *write_msgfds;
2445 int write_msgfds_num;
Corey Minyardcfb429c2014-10-02 11:17:35 -05002446
2447 SocketAddress *addr;
2448 bool is_listen;
2449 bool is_telnet;
aliguori6f97dba2008-10-31 18:49:55 +00002450} TCPCharDriver;
2451
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302452static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
aliguori6f97dba2008-10-31 18:49:55 +00002453
Nikolay Nikolaevd39aac72014-05-27 15:04:02 +03002454#ifndef _WIN32
2455static int unix_send_msgfds(CharDriverState *chr, const uint8_t *buf, int len)
2456{
2457 TCPCharDriver *s = chr->opaque;
2458 struct msghdr msgh;
2459 struct iovec iov;
2460 int r;
2461
2462 size_t fd_size = s->write_msgfds_num * sizeof(int);
2463 char control[CMSG_SPACE(fd_size)];
2464 struct cmsghdr *cmsg;
2465
2466 memset(&msgh, 0, sizeof(msgh));
2467 memset(control, 0, sizeof(control));
2468
2469 /* set the payload */
2470 iov.iov_base = (uint8_t *) buf;
2471 iov.iov_len = len;
2472
2473 msgh.msg_iov = &iov;
2474 msgh.msg_iovlen = 1;
2475
2476 msgh.msg_control = control;
2477 msgh.msg_controllen = sizeof(control);
2478
2479 cmsg = CMSG_FIRSTHDR(&msgh);
2480
2481 cmsg->cmsg_len = CMSG_LEN(fd_size);
2482 cmsg->cmsg_level = SOL_SOCKET;
2483 cmsg->cmsg_type = SCM_RIGHTS;
2484 memcpy(CMSG_DATA(cmsg), s->write_msgfds, fd_size);
2485
2486 do {
2487 r = sendmsg(s->fd, &msgh, 0);
2488 } while (r < 0 && errno == EINTR);
2489
2490 /* free the written msgfds, no matter what */
2491 if (s->write_msgfds_num) {
2492 g_free(s->write_msgfds);
2493 s->write_msgfds = 0;
2494 s->write_msgfds_num = 0;
2495 }
2496
2497 return r;
2498}
2499#endif
2500
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02002501/* Called with chr_write_lock held. */
aliguori6f97dba2008-10-31 18:49:55 +00002502static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2503{
2504 TCPCharDriver *s = chr->opaque;
2505 if (s->connected) {
Nikolay Nikolaevd39aac72014-05-27 15:04:02 +03002506#ifndef _WIN32
2507 if (s->is_unix && s->write_msgfds_num) {
2508 return unix_send_msgfds(chr, buf, len);
2509 } else
2510#endif
2511 {
2512 return io_channel_send(s->chan, buf, len);
2513 }
Anthony Liguori455aa1e2012-09-05 13:52:49 -05002514 } else {
Anthony Liguori6db0fdc2012-09-12 14:34:07 -05002515 /* XXX: indicate an error ? */
Anthony Liguori455aa1e2012-09-05 13:52:49 -05002516 return len;
aliguori6f97dba2008-10-31 18:49:55 +00002517 }
2518}
2519
2520static int tcp_chr_read_poll(void *opaque)
2521{
2522 CharDriverState *chr = opaque;
2523 TCPCharDriver *s = chr->opaque;
2524 if (!s->connected)
2525 return 0;
Anthony Liguori909cda12011-08-15 11:17:31 -05002526 s->max_size = qemu_chr_be_can_write(chr);
aliguori6f97dba2008-10-31 18:49:55 +00002527 return s->max_size;
2528}
2529
2530#define IAC 255
2531#define IAC_BREAK 243
2532static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
2533 TCPCharDriver *s,
2534 uint8_t *buf, int *size)
2535{
2536 /* Handle any telnet client's basic IAC options to satisfy char by
2537 * char mode with no echo. All IAC options will be removed from
2538 * the buf and the do_telnetopt variable will be used to track the
2539 * state of the width of the IAC information.
2540 *
2541 * IAC commands come in sets of 3 bytes with the exception of the
2542 * "IAC BREAK" command and the double IAC.
2543 */
2544
2545 int i;
2546 int j = 0;
2547
2548 for (i = 0; i < *size; i++) {
2549 if (s->do_telnetopt > 1) {
2550 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
2551 /* Double IAC means send an IAC */
2552 if (j != i)
2553 buf[j] = buf[i];
2554 j++;
2555 s->do_telnetopt = 1;
2556 } else {
2557 if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
2558 /* Handle IAC break commands by sending a serial break */
Hans de Goedea425d232011-11-19 10:22:43 +01002559 qemu_chr_be_event(chr, CHR_EVENT_BREAK);
aliguori6f97dba2008-10-31 18:49:55 +00002560 s->do_telnetopt++;
2561 }
2562 s->do_telnetopt++;
2563 }
2564 if (s->do_telnetopt >= 4) {
2565 s->do_telnetopt = 1;
2566 }
2567 } else {
2568 if ((unsigned char)buf[i] == IAC) {
2569 s->do_telnetopt = 2;
2570 } else {
2571 if (j != i)
2572 buf[j] = buf[i];
2573 j++;
2574 }
2575 }
2576 }
2577 *size = j;
2578}
2579
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002580static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num)
Mark McLoughlin7d174052009-07-22 09:11:39 +01002581{
2582 TCPCharDriver *s = chr->opaque;
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002583 int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
2584
2585 if (to_copy) {
Stefan Hajnoczid2fc39b2014-06-22 10:38:37 +08002586 int i;
2587
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002588 memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
2589
Stefan Hajnoczid2fc39b2014-06-22 10:38:37 +08002590 /* Close unused fds */
2591 for (i = to_copy; i < s->read_msgfds_num; i++) {
2592 close(s->read_msgfds[i]);
2593 }
2594
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002595 g_free(s->read_msgfds);
2596 s->read_msgfds = 0;
2597 s->read_msgfds_num = 0;
2598 }
2599
2600 return to_copy;
Mark McLoughlin7d174052009-07-22 09:11:39 +01002601}
2602
Nikolay Nikolaevd39aac72014-05-27 15:04:02 +03002603static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num)
2604{
2605 TCPCharDriver *s = chr->opaque;
2606
2607 /* clear old pending fd array */
2608 if (s->write_msgfds) {
2609 g_free(s->write_msgfds);
2610 }
2611
2612 if (num) {
2613 s->write_msgfds = g_malloc(num * sizeof(int));
2614 memcpy(s->write_msgfds, fds, num * sizeof(int));
2615 }
2616
2617 s->write_msgfds_num = num;
2618
2619 return 0;
2620}
2621
Anthony Liguori73bcc2a2009-07-27 14:55:25 -05002622#ifndef _WIN32
Mark McLoughlin7d174052009-07-22 09:11:39 +01002623static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
2624{
2625 TCPCharDriver *s = chr->opaque;
2626 struct cmsghdr *cmsg;
2627
2628 for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002629 int fd_size, i;
Mark McLoughlin7d174052009-07-22 09:11:39 +01002630
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002631 if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) ||
Mark McLoughlin7d174052009-07-22 09:11:39 +01002632 cmsg->cmsg_level != SOL_SOCKET ||
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002633 cmsg->cmsg_type != SCM_RIGHTS) {
Mark McLoughlin7d174052009-07-22 09:11:39 +01002634 continue;
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002635 }
Mark McLoughlin7d174052009-07-22 09:11:39 +01002636
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002637 fd_size = cmsg->cmsg_len - CMSG_LEN(0);
2638
2639 if (!fd_size) {
Mark McLoughlin7d174052009-07-22 09:11:39 +01002640 continue;
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002641 }
Mark McLoughlin7d174052009-07-22 09:11:39 +01002642
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002643 /* close and clean read_msgfds */
2644 for (i = 0; i < s->read_msgfds_num; i++) {
2645 close(s->read_msgfds[i]);
2646 }
Stefan Hajnoczi9b938c72013-03-27 10:10:46 +01002647
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002648 if (s->read_msgfds_num) {
2649 g_free(s->read_msgfds);
2650 }
2651
2652 s->read_msgfds_num = fd_size / sizeof(int);
2653 s->read_msgfds = g_malloc(fd_size);
2654 memcpy(s->read_msgfds, CMSG_DATA(cmsg), fd_size);
2655
2656 for (i = 0; i < s->read_msgfds_num; i++) {
2657 int fd = s->read_msgfds[i];
2658 if (fd < 0) {
2659 continue;
2660 }
2661
2662 /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
2663 qemu_set_block(fd);
2664
2665 #ifndef MSG_CMSG_CLOEXEC
2666 qemu_set_cloexec(fd);
2667 #endif
2668 }
Mark McLoughlin7d174052009-07-22 09:11:39 +01002669 }
2670}
2671
Mark McLoughlin9977c892009-07-22 09:11:38 +01002672static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2673{
2674 TCPCharDriver *s = chr->opaque;
Blue Swirl7cba04f2009-08-01 10:13:20 +00002675 struct msghdr msg = { NULL, };
Mark McLoughlin9977c892009-07-22 09:11:38 +01002676 struct iovec iov[1];
Mark McLoughlin7d174052009-07-22 09:11:39 +01002677 union {
2678 struct cmsghdr cmsg;
2679 char control[CMSG_SPACE(sizeof(int))];
2680 } msg_control;
Corey Bryant06138652012-08-14 16:43:42 -04002681 int flags = 0;
Mark McLoughlin7d174052009-07-22 09:11:39 +01002682 ssize_t ret;
Mark McLoughlin9977c892009-07-22 09:11:38 +01002683
2684 iov[0].iov_base = buf;
2685 iov[0].iov_len = len;
2686
2687 msg.msg_iov = iov;
2688 msg.msg_iovlen = 1;
Mark McLoughlin7d174052009-07-22 09:11:39 +01002689 msg.msg_control = &msg_control;
2690 msg.msg_controllen = sizeof(msg_control);
Mark McLoughlin9977c892009-07-22 09:11:38 +01002691
Corey Bryant06138652012-08-14 16:43:42 -04002692#ifdef MSG_CMSG_CLOEXEC
2693 flags |= MSG_CMSG_CLOEXEC;
2694#endif
2695 ret = recvmsg(s->fd, &msg, flags);
2696 if (ret > 0 && s->is_unix) {
Mark McLoughlin7d174052009-07-22 09:11:39 +01002697 unix_process_msgfd(chr, &msg);
Corey Bryant06138652012-08-14 16:43:42 -04002698 }
Mark McLoughlin7d174052009-07-22 09:11:39 +01002699
2700 return ret;
Mark McLoughlin9977c892009-07-22 09:11:38 +01002701}
2702#else
2703static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2704{
2705 TCPCharDriver *s = chr->opaque;
Blue Swirl00aa0042011-07-23 20:04:29 +00002706 return qemu_recv(s->fd, buf, len, 0);
Mark McLoughlin9977c892009-07-22 09:11:38 +01002707}
2708#endif
2709
Amit Shahd3cc5bc2013-03-05 23:21:25 +05302710static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond)
2711{
2712 TCPCharDriver *s = chr->opaque;
2713 return g_io_create_watch(s->chan, cond);
2714}
2715
Nikolay Nikolaev7b0bfdf2014-05-27 15:03:48 +03002716static void tcp_chr_disconnect(CharDriverState *chr)
2717{
2718 TCPCharDriver *s = chr->opaque;
2719
2720 s->connected = 0;
2721 if (s->listen_chan) {
2722 s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN,
2723 tcp_chr_accept, chr);
2724 }
2725 remove_fd_in_watch(chr);
2726 g_io_channel_unref(s->chan);
2727 s->chan = NULL;
2728 closesocket(s->fd);
2729 s->fd = -1;
2730 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
2731}
2732
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302733static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
aliguori6f97dba2008-10-31 18:49:55 +00002734{
2735 CharDriverState *chr = opaque;
2736 TCPCharDriver *s = chr->opaque;
Amit Shah9bd78542009-11-03 19:59:54 +05302737 uint8_t buf[READ_BUF_LEN];
aliguori6f97dba2008-10-31 18:49:55 +00002738 int len, size;
2739
Kirill Batuzov812c1052014-07-01 15:52:32 +04002740 if (cond & G_IO_HUP) {
2741 /* connection closed */
2742 tcp_chr_disconnect(chr);
2743 return TRUE;
2744 }
2745
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302746 if (!s->connected || s->max_size <= 0) {
Paolo Bonzinicdbf6e12013-04-19 17:32:08 +02002747 return TRUE;
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302748 }
aliguori6f97dba2008-10-31 18:49:55 +00002749 len = sizeof(buf);
2750 if (len > s->max_size)
2751 len = s->max_size;
Mark McLoughlin9977c892009-07-22 09:11:38 +01002752 size = tcp_chr_recv(chr, (void *)buf, len);
aliguori6f97dba2008-10-31 18:49:55 +00002753 if (size == 0) {
2754 /* connection closed */
Nikolay Nikolaev7b0bfdf2014-05-27 15:03:48 +03002755 tcp_chr_disconnect(chr);
aliguori6f97dba2008-10-31 18:49:55 +00002756 } else if (size > 0) {
2757 if (s->do_telnetopt)
2758 tcp_chr_process_IAC_bytes(chr, s, buf, &size);
2759 if (size > 0)
Anthony Liguorifa5efcc2011-08-15 11:17:30 -05002760 qemu_chr_be_write(chr, buf, size);
aliguori6f97dba2008-10-31 18:49:55 +00002761 }
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302762
2763 return TRUE;
aliguori6f97dba2008-10-31 18:49:55 +00002764}
2765
Nikolay Nikolaev7b0bfdf2014-05-27 15:03:48 +03002766static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len)
2767{
2768 TCPCharDriver *s = chr->opaque;
2769 int size;
2770
2771 if (!s->connected) {
2772 return 0;
2773 }
2774
2775 size = tcp_chr_recv(chr, (void *) buf, len);
2776 if (size == 0) {
2777 /* connection closed */
2778 tcp_chr_disconnect(chr);
2779 }
2780
2781 return size;
2782}
2783
Blue Swirl68c18d12010-08-15 09:46:24 +00002784#ifndef _WIN32
2785CharDriverState *qemu_chr_open_eventfd(int eventfd)
2786{
David Marchande9d21c42014-06-11 17:25:16 +02002787 CharDriverState *chr = qemu_chr_open_fd(eventfd, eventfd);
2788
2789 if (chr) {
2790 chr->avail_connections = 1;
2791 }
2792
2793 return chr;
Cam Macdonell6cbf4c82010-07-27 10:54:13 -06002794}
Blue Swirl68c18d12010-08-15 09:46:24 +00002795#endif
Cam Macdonell6cbf4c82010-07-27 10:54:13 -06002796
aliguori6f97dba2008-10-31 18:49:55 +00002797static void tcp_chr_connect(void *opaque)
2798{
2799 CharDriverState *chr = opaque;
2800 TCPCharDriver *s = chr->opaque;
2801
2802 s->connected = 1;
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302803 if (s->chan) {
Amit Shah7ba9add2013-08-28 15:18:29 +05302804 chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll,
2805 tcp_chr_read, chr);
David Gibsonbbdd2ad2012-09-10 12:30:56 +10002806 }
Hans de Goedefee204f2013-03-26 11:07:54 +01002807 qemu_chr_be_generic_open(chr);
aliguori6f97dba2008-10-31 18:49:55 +00002808}
2809
Gal Hammerac1b84d2014-02-25 12:12:35 +02002810static void tcp_chr_update_read_handler(CharDriverState *chr)
2811{
2812 TCPCharDriver *s = chr->opaque;
2813
2814 remove_fd_in_watch(chr);
2815 if (s->chan) {
2816 chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll,
2817 tcp_chr_read, chr);
2818 }
2819}
2820
aliguori6f97dba2008-10-31 18:49:55 +00002821#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
2822static void tcp_chr_telnet_init(int fd)
2823{
2824 char buf[3];
2825 /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
2826 IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
2827 send(fd, (char *)buf, 3, 0);
2828 IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
2829 send(fd, (char *)buf, 3, 0);
2830 IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
2831 send(fd, (char *)buf, 3, 0);
2832 IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
2833 send(fd, (char *)buf, 3, 0);
2834}
2835
Daniel P. Berrange13661082011-06-23 13:31:42 +01002836static int tcp_chr_add_client(CharDriverState *chr, int fd)
2837{
2838 TCPCharDriver *s = chr->opaque;
2839 if (s->fd != -1)
2840 return -1;
2841
Stefan Hajnoczif9e8cac2013-03-27 10:10:43 +01002842 qemu_set_nonblock(fd);
Daniel P. Berrange13661082011-06-23 13:31:42 +01002843 if (s->do_nodelay)
2844 socket_set_nodelay(fd);
2845 s->fd = fd;
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302846 s->chan = io_channel_from_socket(fd);
Paolo Bonzini910b6362013-04-19 17:32:06 +02002847 if (s->listen_tag) {
2848 g_source_remove(s->listen_tag);
2849 s->listen_tag = 0;
2850 }
Daniel P. Berrange13661082011-06-23 13:31:42 +01002851 tcp_chr_connect(chr);
2852
2853 return 0;
2854}
2855
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302856static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque)
aliguori6f97dba2008-10-31 18:49:55 +00002857{
2858 CharDriverState *chr = opaque;
2859 TCPCharDriver *s = chr->opaque;
2860 struct sockaddr_in saddr;
2861#ifndef _WIN32
2862 struct sockaddr_un uaddr;
2863#endif
2864 struct sockaddr *addr;
2865 socklen_t len;
2866 int fd;
2867
2868 for(;;) {
2869#ifndef _WIN32
2870 if (s->is_unix) {
2871 len = sizeof(uaddr);
2872 addr = (struct sockaddr *)&uaddr;
2873 } else
2874#endif
2875 {
2876 len = sizeof(saddr);
2877 addr = (struct sockaddr *)&saddr;
2878 }
Kevin Wolf40ff6d72009-12-02 12:24:42 +01002879 fd = qemu_accept(s->listen_fd, addr, &len);
aliguori6f97dba2008-10-31 18:49:55 +00002880 if (fd < 0 && errno != EINTR) {
Hans de Goede79f20072013-04-25 13:53:02 +02002881 s->listen_tag = 0;
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302882 return FALSE;
aliguori6f97dba2008-10-31 18:49:55 +00002883 } else if (fd >= 0) {
2884 if (s->do_telnetopt)
2885 tcp_chr_telnet_init(fd);
2886 break;
2887 }
2888 }
Daniel P. Berrange13661082011-06-23 13:31:42 +01002889 if (tcp_chr_add_client(chr, fd) < 0)
2890 close(fd);
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302891
2892 return TRUE;
aliguori6f97dba2008-10-31 18:49:55 +00002893}
2894
2895static void tcp_chr_close(CharDriverState *chr)
2896{
2897 TCPCharDriver *s = chr->opaque;
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002898 int i;
Corey Minyardcfb429c2014-10-02 11:17:35 -05002899
2900 qapi_free_SocketAddress(s->addr);
aliguori819f56b2009-03-28 17:58:14 +00002901 if (s->fd >= 0) {
Amit Shah26da70c2013-08-28 15:23:37 +05302902 remove_fd_in_watch(chr);
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302903 if (s->chan) {
2904 g_io_channel_unref(s->chan);
2905 }
aliguori6f97dba2008-10-31 18:49:55 +00002906 closesocket(s->fd);
aliguori819f56b2009-03-28 17:58:14 +00002907 }
2908 if (s->listen_fd >= 0) {
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302909 if (s->listen_tag) {
2910 g_source_remove(s->listen_tag);
Paolo Bonzini910b6362013-04-19 17:32:06 +02002911 s->listen_tag = 0;
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302912 }
2913 if (s->listen_chan) {
2914 g_io_channel_unref(s->listen_chan);
2915 }
aliguori6f97dba2008-10-31 18:49:55 +00002916 closesocket(s->listen_fd);
aliguori819f56b2009-03-28 17:58:14 +00002917 }
Nikolay Nikolaevc76bf6b2014-05-27 15:04:15 +03002918 if (s->read_msgfds_num) {
2919 for (i = 0; i < s->read_msgfds_num; i++) {
2920 close(s->read_msgfds[i]);
2921 }
2922 g_free(s->read_msgfds);
2923 }
Nikolay Nikolaevd39aac72014-05-27 15:04:02 +03002924 if (s->write_msgfds_num) {
2925 g_free(s->write_msgfds);
2926 }
Anthony Liguori7267c092011-08-20 22:09:37 -05002927 g_free(s);
Hans de Goedea425d232011-11-19 10:22:43 +01002928 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
aliguori6f97dba2008-10-31 18:49:55 +00002929}
2930
Corey Minyard43ded1a2014-10-02 11:17:34 -05002931static bool qemu_chr_finish_socket_connection(CharDriverState *chr, int fd,
Corey Minyard43ded1a2014-10-02 11:17:34 -05002932 Error **errp)
aliguori6f97dba2008-10-31 18:49:55 +00002933{
Corey Minyard43ded1a2014-10-02 11:17:34 -05002934 TCPCharDriver *s = chr->opaque;
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002935 char host[NI_MAXHOST], serv[NI_MAXSERV];
2936 const char *left = "", *right = "";
2937 struct sockaddr_storage ss;
2938 socklen_t ss_len = sizeof(ss);
2939
2940 memset(&ss, 0, ss_len);
2941 if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
Corey Minyard43ded1a2014-10-02 11:17:34 -05002942 closesocket(fd);
Gerd Hoffmann20c39762013-06-24 08:39:48 +02002943 error_setg_errno(errp, errno, "getsockname");
Corey Minyard43ded1a2014-10-02 11:17:34 -05002944 return false;
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002945 }
2946
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002947 switch (ss.ss_family) {
2948#ifndef _WIN32
2949 case AF_UNIX:
Corey Minyard9f781162014-10-02 11:17:33 -05002950 snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "unix:%s%s",
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002951 ((struct sockaddr_un *)(&ss))->sun_path,
Corey Minyardcfb429c2014-10-02 11:17:35 -05002952 s->is_listen ? ",server" : "");
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002953 break;
2954#endif
2955 case AF_INET6:
2956 left = "[";
2957 right = "]";
2958 /* fall through */
2959 case AF_INET:
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002960 getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
2961 serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
Corey Minyard9f781162014-10-02 11:17:33 -05002962 snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, "%s:%s%s%s:%s%s",
Corey Minyardcfb429c2014-10-02 11:17:35 -05002963 s->is_telnet ? "telnet" : "tcp",
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002964 left, host, right, serv,
Corey Minyardcfb429c2014-10-02 11:17:35 -05002965 s->is_listen ? ",server" : "");
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002966 break;
2967 }
2968
Corey Minyardcfb429c2014-10-02 11:17:35 -05002969 if (s->is_listen) {
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002970 s->listen_fd = fd;
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302971 s->listen_chan = io_channel_from_socket(s->listen_fd);
Corey Minyard43ded1a2014-10-02 11:17:34 -05002972 s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN,
2973 tcp_chr_accept, chr);
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002974 } else {
2975 s->connected = 1;
2976 s->fd = fd;
2977 socket_set_nodelay(fd);
Anthony Liguori2ea5a7a2013-03-05 23:21:22 +05302978 s->chan = io_channel_from_socket(s->fd);
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002979 tcp_chr_connect(chr);
2980 }
2981
Corey Minyard43ded1a2014-10-02 11:17:34 -05002982 return true;
2983}
2984
Corey Minyardcfb429c2014-10-02 11:17:35 -05002985static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp)
Corey Minyard43ded1a2014-10-02 11:17:34 -05002986{
Corey Minyardcfb429c2014-10-02 11:17:35 -05002987 TCPCharDriver *s = chr->opaque;
Corey Minyard43ded1a2014-10-02 11:17:34 -05002988 int fd;
2989
Corey Minyardcfb429c2014-10-02 11:17:35 -05002990 if (s->is_listen) {
2991 fd = socket_listen(s->addr, errp);
Corey Minyard43ded1a2014-10-02 11:17:34 -05002992 } else {
Corey Minyardcfb429c2014-10-02 11:17:35 -05002993 fd = socket_connect(s->addr, errp, NULL, NULL);
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01002994 }
Corey Minyard43ded1a2014-10-02 11:17:34 -05002995 if (fd < 0) {
2996 return false;
2997 }
2998
Corey Minyardcfb429c2014-10-02 11:17:35 -05002999 return qemu_chr_finish_socket_connection(chr, fd, errp);
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01003000}
3001
Lei Li51767e72013-01-25 00:03:19 +08003002/*********************************************************/
Markus Armbruster3949e592013-02-06 21:27:24 +01003003/* Ring buffer chardev */
Lei Li51767e72013-01-25 00:03:19 +08003004
3005typedef struct {
3006 size_t size;
3007 size_t prod;
3008 size_t cons;
3009 uint8_t *cbuf;
Markus Armbruster3949e592013-02-06 21:27:24 +01003010} RingBufCharDriver;
Lei Li51767e72013-01-25 00:03:19 +08003011
Markus Armbruster3949e592013-02-06 21:27:24 +01003012static size_t ringbuf_count(const CharDriverState *chr)
Lei Li51767e72013-01-25 00:03:19 +08003013{
Markus Armbruster3949e592013-02-06 21:27:24 +01003014 const RingBufCharDriver *d = chr->opaque;
Lei Li51767e72013-01-25 00:03:19 +08003015
Markus Armbruster5c230102013-02-06 21:27:23 +01003016 return d->prod - d->cons;
Lei Li51767e72013-01-25 00:03:19 +08003017}
3018
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02003019/* Called with chr_write_lock held. */
Markus Armbruster3949e592013-02-06 21:27:24 +01003020static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
Lei Li51767e72013-01-25 00:03:19 +08003021{
Markus Armbruster3949e592013-02-06 21:27:24 +01003022 RingBufCharDriver *d = chr->opaque;
Lei Li51767e72013-01-25 00:03:19 +08003023 int i;
3024
3025 if (!buf || (len < 0)) {
3026 return -1;
3027 }
3028
3029 for (i = 0; i < len; i++ ) {
Markus Armbruster5c230102013-02-06 21:27:23 +01003030 d->cbuf[d->prod++ & (d->size - 1)] = buf[i];
3031 if (d->prod - d->cons > d->size) {
Lei Li51767e72013-01-25 00:03:19 +08003032 d->cons = d->prod - d->size;
3033 }
3034 }
3035
3036 return 0;
3037}
3038
Markus Armbruster3949e592013-02-06 21:27:24 +01003039static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len)
Lei Li51767e72013-01-25 00:03:19 +08003040{
Markus Armbruster3949e592013-02-06 21:27:24 +01003041 RingBufCharDriver *d = chr->opaque;
Lei Li51767e72013-01-25 00:03:19 +08003042 int i;
3043
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02003044 qemu_mutex_lock(&chr->chr_write_lock);
Markus Armbruster5c230102013-02-06 21:27:23 +01003045 for (i = 0; i < len && d->cons != d->prod; i++) {
3046 buf[i] = d->cbuf[d->cons++ & (d->size - 1)];
Lei Li51767e72013-01-25 00:03:19 +08003047 }
Paolo Bonzini9005b2a2014-06-18 08:43:58 +02003048 qemu_mutex_unlock(&chr->chr_write_lock);
Lei Li51767e72013-01-25 00:03:19 +08003049
3050 return i;
3051}
3052
Markus Armbruster3949e592013-02-06 21:27:24 +01003053static void ringbuf_chr_close(struct CharDriverState *chr)
Lei Li51767e72013-01-25 00:03:19 +08003054{
Markus Armbruster3949e592013-02-06 21:27:24 +01003055 RingBufCharDriver *d = chr->opaque;
Lei Li51767e72013-01-25 00:03:19 +08003056
3057 g_free(d->cbuf);
3058 g_free(d);
3059 chr->opaque = NULL;
3060}
3061
Markus Armbruster4f573782013-07-26 16:44:32 +02003062static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
3063 Error **errp)
Lei Li51767e72013-01-25 00:03:19 +08003064{
3065 CharDriverState *chr;
Markus Armbruster3949e592013-02-06 21:27:24 +01003066 RingBufCharDriver *d;
Lei Li51767e72013-01-25 00:03:19 +08003067
Paolo Bonzinidb39fcf2014-06-18 08:43:55 +02003068 chr = qemu_chr_alloc();
Lei Li51767e72013-01-25 00:03:19 +08003069 d = g_malloc(sizeof(*d));
3070
Gerd Hoffmann1da48c62013-02-26 16:21:11 +01003071 d->size = opts->has_size ? opts->size : 65536;
Lei Li51767e72013-01-25 00:03:19 +08003072
3073 /* The size must be power of 2 */
3074 if (d->size & (d->size - 1)) {
Markus Armbruster4f573782013-07-26 16:44:32 +02003075 error_setg(errp, "size of ringbuf chardev must be power of two");
Lei Li51767e72013-01-25 00:03:19 +08003076 goto fail;
3077 }
3078
3079 d->prod = 0;
3080 d->cons = 0;
3081 d->cbuf = g_malloc0(d->size);
3082
3083 chr->opaque = d;
Markus Armbruster3949e592013-02-06 21:27:24 +01003084 chr->chr_write = ringbuf_chr_write;
3085 chr->chr_close = ringbuf_chr_close;
Lei Li51767e72013-01-25 00:03:19 +08003086
3087 return chr;
3088
3089fail:
3090 g_free(d);
3091 g_free(chr);
3092 return NULL;
3093}
3094
Hani Benhabiles8e597772014-05-27 23:39:30 +01003095bool chr_is_ringbuf(const CharDriverState *chr)
Lei Li1f590cf2013-01-25 00:03:20 +08003096{
Markus Armbruster3949e592013-02-06 21:27:24 +01003097 return chr->chr_write == ringbuf_chr_write;
Lei Li1f590cf2013-01-25 00:03:20 +08003098}
3099
Markus Armbruster3949e592013-02-06 21:27:24 +01003100void qmp_ringbuf_write(const char *device, const char *data,
Markus Armbruster82e59a62013-02-06 21:27:14 +01003101 bool has_format, enum DataFormat format,
Lei Li1f590cf2013-01-25 00:03:20 +08003102 Error **errp)
3103{
3104 CharDriverState *chr;
Markus Armbrusterc4f331b2013-02-06 21:27:17 +01003105 const uint8_t *write_data;
Lei Li1f590cf2013-01-25 00:03:20 +08003106 int ret;
Peter Crosthwaite3d1bba22013-05-22 13:01:43 +10003107 gsize write_count;
Lei Li1f590cf2013-01-25 00:03:20 +08003108
3109 chr = qemu_chr_find(device);
3110 if (!chr) {
Markus Armbruster1a692782013-02-06 21:27:16 +01003111 error_setg(errp, "Device '%s' not found", device);
Lei Li1f590cf2013-01-25 00:03:20 +08003112 return;
3113 }
3114
Markus Armbruster3949e592013-02-06 21:27:24 +01003115 if (!chr_is_ringbuf(chr)) {
3116 error_setg(errp,"%s is not a ringbuf device", device);
Lei Li1f590cf2013-01-25 00:03:20 +08003117 return;
3118 }
3119
Lei Li1f590cf2013-01-25 00:03:20 +08003120 if (has_format && (format == DATA_FORMAT_BASE64)) {
3121 write_data = g_base64_decode(data, &write_count);
3122 } else {
3123 write_data = (uint8_t *)data;
Markus Armbruster82e59a62013-02-06 21:27:14 +01003124 write_count = strlen(data);
Lei Li1f590cf2013-01-25 00:03:20 +08003125 }
3126
Markus Armbruster3949e592013-02-06 21:27:24 +01003127 ret = ringbuf_chr_write(chr, write_data, write_count);
Lei Li1f590cf2013-01-25 00:03:20 +08003128
Markus Armbruster13289fb2013-02-06 21:27:18 +01003129 if (write_data != (uint8_t *)data) {
3130 g_free((void *)write_data);
3131 }
3132
Lei Li1f590cf2013-01-25 00:03:20 +08003133 if (ret < 0) {
3134 error_setg(errp, "Failed to write to device %s", device);
3135 return;
3136 }
3137}
3138
Markus Armbruster3949e592013-02-06 21:27:24 +01003139char *qmp_ringbuf_read(const char *device, int64_t size,
Markus Armbruster3ab651f2013-02-06 21:27:15 +01003140 bool has_format, enum DataFormat format,
3141 Error **errp)
Lei Li49b6d722013-01-25 00:03:21 +08003142{
3143 CharDriverState *chr;
Markus Armbrusterc4f331b2013-02-06 21:27:17 +01003144 uint8_t *read_data;
Lei Li49b6d722013-01-25 00:03:21 +08003145 size_t count;
Markus Armbruster3ab651f2013-02-06 21:27:15 +01003146 char *data;
Lei Li49b6d722013-01-25 00:03:21 +08003147
3148 chr = qemu_chr_find(device);
3149 if (!chr) {
Markus Armbruster1a692782013-02-06 21:27:16 +01003150 error_setg(errp, "Device '%s' not found", device);
Lei Li49b6d722013-01-25 00:03:21 +08003151 return NULL;
3152 }
3153
Markus Armbruster3949e592013-02-06 21:27:24 +01003154 if (!chr_is_ringbuf(chr)) {
3155 error_setg(errp,"%s is not a ringbuf device", device);
Lei Li49b6d722013-01-25 00:03:21 +08003156 return NULL;
3157 }
3158
3159 if (size <= 0) {
3160 error_setg(errp, "size must be greater than zero");
3161 return NULL;
3162 }
3163
Markus Armbruster3949e592013-02-06 21:27:24 +01003164 count = ringbuf_count(chr);
Lei Li49b6d722013-01-25 00:03:21 +08003165 size = size > count ? count : size;
Markus Armbruster44f3bcd2013-02-06 21:27:20 +01003166 read_data = g_malloc(size + 1);
Lei Li49b6d722013-01-25 00:03:21 +08003167
Markus Armbruster3949e592013-02-06 21:27:24 +01003168 ringbuf_chr_read(chr, read_data, size);
Lei Li49b6d722013-01-25 00:03:21 +08003169
3170 if (has_format && (format == DATA_FORMAT_BASE64)) {
Markus Armbruster3ab651f2013-02-06 21:27:15 +01003171 data = g_base64_encode(read_data, size);
Markus Armbruster13289fb2013-02-06 21:27:18 +01003172 g_free(read_data);
Lei Li49b6d722013-01-25 00:03:21 +08003173 } else {
Markus Armbruster3949e592013-02-06 21:27:24 +01003174 /*
3175 * FIXME should read only complete, valid UTF-8 characters up
3176 * to @size bytes. Invalid sequences should be replaced by a
3177 * suitable replacement character. Except when (and only
3178 * when) ring buffer lost characters since last read, initial
3179 * continuation characters should be dropped.
3180 */
Markus Armbruster44f3bcd2013-02-06 21:27:20 +01003181 read_data[size] = 0;
Markus Armbruster3ab651f2013-02-06 21:27:15 +01003182 data = (char *)read_data;
Lei Li49b6d722013-01-25 00:03:21 +08003183 }
3184
Markus Armbruster3ab651f2013-02-06 21:27:15 +01003185 return data;
Lei Li49b6d722013-01-25 00:03:21 +08003186}
3187
Gerd Hoffmann33521632009-12-08 13:11:49 +01003188QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003189{
Gerd Hoffmann6ea314d2009-09-10 10:58:49 +02003190 char host[65], port[33], width[8], height[8];
Gerd Hoffmannaeb2c472009-09-10 10:58:42 +02003191 int pos;
Gerd Hoffmann7d315442009-09-10 10:58:36 +02003192 const char *p;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003193 QemuOpts *opts;
Luiz Capitulino8be7e7e2012-03-20 15:51:57 -03003194 Error *local_err = NULL;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003195
Luiz Capitulino8be7e7e2012-03-20 15:51:57 -03003196 opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
Markus Armbruster84d18f02014-01-30 15:07:28 +01003197 if (local_err) {
Luiz Capitulino8be7e7e2012-03-20 15:51:57 -03003198 qerror_report_err(local_err);
3199 error_free(local_err);
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003200 return NULL;
Luiz Capitulino8be7e7e2012-03-20 15:51:57 -03003201 }
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003202
Gerd Hoffmann7591c5c2009-09-10 10:58:50 +02003203 if (strstart(filename, "mon:", &p)) {
3204 filename = p;
3205 qemu_opt_set(opts, "mux", "on");
Paolo Bonzini02c4bdf2013-07-03 20:29:45 +04003206 if (strcmp(filename, "stdio") == 0) {
3207 /* Monitor is muxed to stdio: do not exit on Ctrl+C by default
3208 * but pass it to the guest. Handle this only for compat syntax,
3209 * for -chardev syntax we have special option for this.
3210 * This is what -nographic did, redirecting+muxing serial+monitor
3211 * to stdio causing Ctrl+C to be passed to guest. */
3212 qemu_opt_set(opts, "signal", "off");
3213 }
Gerd Hoffmann7591c5c2009-09-10 10:58:50 +02003214 }
3215
Gerd Hoffmannf0457e82009-09-10 10:58:45 +02003216 if (strcmp(filename, "null") == 0 ||
3217 strcmp(filename, "pty") == 0 ||
3218 strcmp(filename, "msmouse") == 0 ||
Gerd Hoffmanndc1c21e2009-09-10 10:58:46 +02003219 strcmp(filename, "braille") == 0 ||
Paolo Bonzini56923992014-07-11 09:44:26 +02003220 strcmp(filename, "testdev") == 0 ||
Gerd Hoffmannf0457e82009-09-10 10:58:45 +02003221 strcmp(filename, "stdio") == 0) {
Gerd Hoffmann4490dad2009-09-10 10:58:43 +02003222 qemu_opt_set(opts, "backend", filename);
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003223 return opts;
3224 }
Gerd Hoffmann6ea314d2009-09-10 10:58:49 +02003225 if (strstart(filename, "vc", &p)) {
3226 qemu_opt_set(opts, "backend", "vc");
3227 if (*p == ':') {
Stefan Weil49aa4052013-09-30 23:04:49 +02003228 if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
Gerd Hoffmann6ea314d2009-09-10 10:58:49 +02003229 /* pixels */
3230 qemu_opt_set(opts, "width", width);
3231 qemu_opt_set(opts, "height", height);
Stefan Weil49aa4052013-09-30 23:04:49 +02003232 } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
Gerd Hoffmann6ea314d2009-09-10 10:58:49 +02003233 /* chars */
3234 qemu_opt_set(opts, "cols", width);
3235 qemu_opt_set(opts, "rows", height);
3236 } else {
3237 goto fail;
3238 }
3239 }
3240 return opts;
3241 }
Gerd Hoffmannd6c983c2009-09-10 10:58:47 +02003242 if (strcmp(filename, "con:") == 0) {
3243 qemu_opt_set(opts, "backend", "console");
3244 return opts;
3245 }
Gerd Hoffmann48b76492009-09-10 10:58:48 +02003246 if (strstart(filename, "COM", NULL)) {
3247 qemu_opt_set(opts, "backend", "serial");
3248 qemu_opt_set(opts, "path", filename);
3249 return opts;
3250 }
Gerd Hoffmann7d315442009-09-10 10:58:36 +02003251 if (strstart(filename, "file:", &p)) {
3252 qemu_opt_set(opts, "backend", "file");
3253 qemu_opt_set(opts, "path", p);
3254 return opts;
3255 }
3256 if (strstart(filename, "pipe:", &p)) {
3257 qemu_opt_set(opts, "backend", "pipe");
3258 qemu_opt_set(opts, "path", p);
3259 return opts;
3260 }
Gerd Hoffmannaeb2c472009-09-10 10:58:42 +02003261 if (strstart(filename, "tcp:", &p) ||
3262 strstart(filename, "telnet:", &p)) {
3263 if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
3264 host[0] = 0;
3265 if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
3266 goto fail;
3267 }
3268 qemu_opt_set(opts, "backend", "socket");
3269 qemu_opt_set(opts, "host", host);
3270 qemu_opt_set(opts, "port", port);
3271 if (p[pos] == ',') {
3272 if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)
3273 goto fail;
3274 }
3275 if (strstart(filename, "telnet:", &p))
3276 qemu_opt_set(opts, "telnet", "on");
3277 return opts;
3278 }
Gerd Hoffmann7e1b35b2009-09-10 10:58:51 +02003279 if (strstart(filename, "udp:", &p)) {
3280 qemu_opt_set(opts, "backend", "udp");
3281 if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
3282 host[0] = 0;
Jan Kiszka39324ca2010-03-07 11:28:48 +01003283 if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
Gerd Hoffmann7e1b35b2009-09-10 10:58:51 +02003284 goto fail;
3285 }
3286 }
3287 qemu_opt_set(opts, "host", host);
3288 qemu_opt_set(opts, "port", port);
3289 if (p[pos] == '@') {
3290 p += pos + 1;
3291 if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
3292 host[0] = 0;
3293 if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
Gerd Hoffmann7e1b35b2009-09-10 10:58:51 +02003294 goto fail;
3295 }
3296 }
3297 qemu_opt_set(opts, "localaddr", host);
3298 qemu_opt_set(opts, "localport", port);
3299 }
3300 return opts;
3301 }
Gerd Hoffmannaeb2c472009-09-10 10:58:42 +02003302 if (strstart(filename, "unix:", &p)) {
3303 qemu_opt_set(opts, "backend", "socket");
3304 if (qemu_opts_do_parse(opts, p, "path") != 0)
3305 goto fail;
3306 return opts;
3307 }
Gerd Hoffmann48b76492009-09-10 10:58:48 +02003308 if (strstart(filename, "/dev/parport", NULL) ||
3309 strstart(filename, "/dev/ppi", NULL)) {
3310 qemu_opt_set(opts, "backend", "parport");
3311 qemu_opt_set(opts, "path", filename);
3312 return opts;
3313 }
3314 if (strstart(filename, "/dev/", NULL)) {
3315 qemu_opt_set(opts, "backend", "tty");
3316 qemu_opt_set(opts, "path", filename);
3317 return opts;
3318 }
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003319
Gerd Hoffmannaeb2c472009-09-10 10:58:42 +02003320fail:
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003321 qemu_opts_del(opts);
3322 return NULL;
3323}
3324
Gerd Hoffmann846e2e42013-02-21 12:07:14 +01003325static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
3326 Error **errp)
3327{
3328 const char *path = qemu_opt_get(opts, "path");
3329
3330 if (path == NULL) {
3331 error_setg(errp, "chardev: file: no filename given");
3332 return;
3333 }
3334 backend->file = g_new0(ChardevFile, 1);
3335 backend->file->out = g_strdup(path);
3336}
3337
Gerd Hoffmann7c358032013-02-21 12:34:58 +01003338static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
3339 Error **errp)
3340{
3341 backend->stdio = g_new0(ChardevStdio, 1);
3342 backend->stdio->has_signal = true;
Paolo Bonzini02c4bdf2013-07-03 20:29:45 +04003343 backend->stdio->signal = qemu_opt_get_bool(opts, "signal", true);
Gerd Hoffmann7c358032013-02-21 12:34:58 +01003344}
3345
Gerd Hoffmann0f1cb512013-02-22 15:48:05 +01003346static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
3347 Error **errp)
3348{
3349 const char *device = qemu_opt_get(opts, "path");
3350
3351 if (device == NULL) {
3352 error_setg(errp, "chardev: serial/tty: no device path given");
3353 return;
3354 }
3355 backend->serial = g_new0(ChardevHostdev, 1);
3356 backend->serial->device = g_strdup(device);
3357}
3358
Gerd Hoffmanndc375092013-02-22 16:17:01 +01003359static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
3360 Error **errp)
3361{
3362 const char *device = qemu_opt_get(opts, "path");
3363
3364 if (device == NULL) {
3365 error_setg(errp, "chardev: parallel: no device path given");
3366 return;
3367 }
3368 backend->parallel = g_new0(ChardevHostdev, 1);
3369 backend->parallel->device = g_strdup(device);
3370}
3371
Gerd Hoffmann548cbb32013-02-25 11:50:55 +01003372static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
3373 Error **errp)
3374{
3375 const char *device = qemu_opt_get(opts, "path");
3376
3377 if (device == NULL) {
3378 error_setg(errp, "chardev: pipe: no device path given");
3379 return;
3380 }
3381 backend->pipe = g_new0(ChardevHostdev, 1);
3382 backend->pipe->device = g_strdup(device);
3383}
3384
Markus Armbruster4f573782013-07-26 16:44:32 +02003385static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
3386 Error **errp)
Gerd Hoffmann1da48c62013-02-26 16:21:11 +01003387{
3388 int val;
3389
Markus Armbruster3a1da422013-07-26 16:44:34 +02003390 backend->ringbuf = g_new0(ChardevRingbuf, 1);
Gerd Hoffmann1da48c62013-02-26 16:21:11 +01003391
Markus Armbruster0f953052013-06-27 16:22:07 +02003392 val = qemu_opt_get_size(opts, "size", 0);
Gerd Hoffmann1da48c62013-02-26 16:21:11 +01003393 if (val != 0) {
Markus Armbruster3a1da422013-07-26 16:44:34 +02003394 backend->ringbuf->has_size = true;
3395 backend->ringbuf->size = val;
Gerd Hoffmann1da48c62013-02-26 16:21:11 +01003396 }
3397}
3398
Gerd Hoffmannbb6fb7c2013-06-24 08:39:54 +02003399static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
3400 Error **errp)
3401{
3402 const char *chardev = qemu_opt_get(opts, "chardev");
3403
3404 if (chardev == NULL) {
3405 error_setg(errp, "chardev: mux: no chardev given");
3406 return;
3407 }
3408 backend->mux = g_new0(ChardevMux, 1);
3409 backend->mux->chardev = g_strdup(chardev);
3410}
3411
Peter Maydelldafd3252014-09-02 11:24:13 +01003412static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
3413 Error **errp)
3414{
3415 bool is_listen = qemu_opt_get_bool(opts, "server", false);
3416 bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
3417 bool is_telnet = qemu_opt_get_bool(opts, "telnet", false);
3418 bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true);
3419 const char *path = qemu_opt_get(opts, "path");
3420 const char *host = qemu_opt_get(opts, "host");
3421 const char *port = qemu_opt_get(opts, "port");
3422 SocketAddress *addr;
3423
3424 if (!path) {
3425 if (!host) {
3426 error_setg(errp, "chardev: socket: no host given");
3427 return;
3428 }
3429 if (!port) {
3430 error_setg(errp, "chardev: socket: no port given");
3431 return;
3432 }
3433 }
3434
3435 backend->socket = g_new0(ChardevSocket, 1);
3436
3437 backend->socket->has_nodelay = true;
3438 backend->socket->nodelay = do_nodelay;
3439 backend->socket->has_server = true;
3440 backend->socket->server = is_listen;
3441 backend->socket->has_telnet = true;
3442 backend->socket->telnet = is_telnet;
3443 backend->socket->has_wait = true;
3444 backend->socket->wait = is_waitconnect;
3445
3446 addr = g_new0(SocketAddress, 1);
3447 if (path) {
3448 addr->kind = SOCKET_ADDRESS_KIND_UNIX;
3449 addr->q_unix = g_new0(UnixSocketAddress, 1);
3450 addr->q_unix->path = g_strdup(path);
3451 } else {
3452 addr->kind = SOCKET_ADDRESS_KIND_INET;
3453 addr->inet = g_new0(InetSocketAddress, 1);
3454 addr->inet->host = g_strdup(host);
3455 addr->inet->port = g_strdup(port);
3456 addr->inet->has_to = qemu_opt_get(opts, "to");
3457 addr->inet->to = qemu_opt_get_number(opts, "to", 0);
3458 addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
3459 addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
3460 addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
3461 addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
3462 }
3463 backend->socket->addr = addr;
3464}
3465
Peter Maydell90a14bf2014-09-02 11:24:15 +01003466static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
3467 Error **errp)
3468{
3469 const char *host = qemu_opt_get(opts, "host");
3470 const char *port = qemu_opt_get(opts, "port");
3471 const char *localaddr = qemu_opt_get(opts, "localaddr");
3472 const char *localport = qemu_opt_get(opts, "localport");
3473 bool has_local = false;
3474 SocketAddress *addr;
3475
3476 if (host == NULL || strlen(host) == 0) {
3477 host = "localhost";
3478 }
3479 if (port == NULL || strlen(port) == 0) {
3480 error_setg(errp, "chardev: udp: remote port not specified");
3481 return;
3482 }
3483 if (localport == NULL || strlen(localport) == 0) {
3484 localport = "0";
3485 } else {
3486 has_local = true;
3487 }
3488 if (localaddr == NULL || strlen(localaddr) == 0) {
3489 localaddr = "";
3490 } else {
3491 has_local = true;
3492 }
3493
3494 backend->udp = g_new0(ChardevUdp, 1);
3495
3496 addr = g_new0(SocketAddress, 1);
3497 addr->kind = SOCKET_ADDRESS_KIND_INET;
3498 addr->inet = g_new0(InetSocketAddress, 1);
3499 addr->inet->host = g_strdup(host);
3500 addr->inet->port = g_strdup(port);
3501 addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
3502 addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
3503 addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
3504 addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
3505 backend->udp->remote = addr;
3506
3507 if (has_local) {
3508 backend->udp->has_local = true;
3509 addr = g_new0(SocketAddress, 1);
3510 addr->kind = SOCKET_ADDRESS_KIND_INET;
3511 addr->inet = g_new0(InetSocketAddress, 1);
3512 addr->inet->host = g_strdup(localaddr);
3513 addr->inet->port = g_strdup(localport);
3514 backend->udp->local = addr;
3515 }
3516}
3517
Anthony Liguorid654f342013-03-05 23:21:28 +05303518typedef struct CharDriver {
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003519 const char *name;
Gerd Hoffmann99aec012013-06-24 08:39:52 +02003520 ChardevBackendKind kind;
Gerd Hoffmann2c5f4882013-02-21 11:39:12 +01003521 void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
Anthony Liguorid654f342013-03-05 23:21:28 +05303522} CharDriver;
3523
3524static GSList *backends;
3525
Peter Maydelle4d50d42014-09-02 11:24:17 +01003526void register_char_driver(const char *name, ChardevBackendKind kind,
Gerd Hoffmann2c5f4882013-02-21 11:39:12 +01003527 void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
3528{
3529 CharDriver *s;
3530
3531 s = g_malloc0(sizeof(*s));
3532 s->name = g_strdup(name);
3533 s->kind = kind;
3534 s->parse = parse;
3535
3536 backends = g_slist_append(backends, s);
3537}
3538
Anthony Liguorif69554b2011-08-15 11:17:37 -05003539CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
Gerd Hoffmannbd2d80b2012-10-15 09:28:05 +02003540 void (*init)(struct CharDriverState *s),
3541 Error **errp)
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003542{
Markus Armbruster0aff6372014-05-19 18:57:35 +02003543 Error *local_err = NULL;
Anthony Liguorid654f342013-03-05 23:21:28 +05303544 CharDriver *cd;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003545 CharDriverState *chr;
Anthony Liguorid654f342013-03-05 23:21:28 +05303546 GSList *i;
Peter Maydella61ae7f2014-09-02 11:24:16 +01003547 ChardevReturn *ret = NULL;
3548 ChardevBackend *backend;
3549 const char *id = qemu_opts_id(opts);
3550 char *bid = NULL;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003551
Peter Maydella61ae7f2014-09-02 11:24:16 +01003552 if (id == NULL) {
Markus Armbruster312fd5f2013-02-08 21:22:16 +01003553 error_setg(errp, "chardev: no id specified");
Gerd Hoffmann2274ae92012-10-15 09:30:59 +02003554 goto err;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003555 }
3556
Stefan Hajnoczi1bbd1852011-01-22 13:07:26 +00003557 if (qemu_opt_get(opts, "backend") == NULL) {
Markus Armbruster312fd5f2013-02-08 21:22:16 +01003558 error_setg(errp, "chardev: \"%s\" missing backend",
Gerd Hoffmannbd2d80b2012-10-15 09:28:05 +02003559 qemu_opts_id(opts));
Gerd Hoffmann2274ae92012-10-15 09:30:59 +02003560 goto err;
Stefan Hajnoczi1bbd1852011-01-22 13:07:26 +00003561 }
Anthony Liguorid654f342013-03-05 23:21:28 +05303562 for (i = backends; i; i = i->next) {
3563 cd = i->data;
3564
3565 if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) {
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003566 break;
Anthony Liguorid654f342013-03-05 23:21:28 +05303567 }
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003568 }
Anthony Liguorid654f342013-03-05 23:21:28 +05303569 if (i == NULL) {
Markus Armbruster312fd5f2013-02-08 21:22:16 +01003570 error_setg(errp, "chardev: backend \"%s\" not found",
Gerd Hoffmannbd2d80b2012-10-15 09:28:05 +02003571 qemu_opt_get(opts, "backend"));
Gerd Hoffmanne6682872013-06-24 08:39:51 +02003572 goto err;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003573 }
3574
Peter Maydella61ae7f2014-09-02 11:24:16 +01003575 backend = g_new0(ChardevBackend, 1);
Gerd Hoffmann7591c5c2009-09-10 10:58:50 +02003576
3577 if (qemu_opt_get_bool(opts, "mux", 0)) {
Peter Maydella61ae7f2014-09-02 11:24:16 +01003578 bid = g_strdup_printf("%s-base", id);
Gerd Hoffmann7591c5c2009-09-10 10:58:50 +02003579 }
Peter Maydella61ae7f2014-09-02 11:24:16 +01003580
3581 chr = NULL;
3582 backend->kind = cd->kind;
3583 if (cd->parse) {
3584 cd->parse(opts, backend, &local_err);
3585 if (local_err) {
3586 error_propagate(errp, local_err);
3587 goto qapi_out;
3588 }
3589 }
3590 ret = qmp_chardev_add(bid ? bid : id, backend, errp);
3591 if (!ret) {
3592 goto qapi_out;
3593 }
3594
3595 if (bid) {
3596 qapi_free_ChardevBackend(backend);
3597 qapi_free_ChardevReturn(ret);
3598 backend = g_new0(ChardevBackend, 1);
3599 backend->mux = g_new0(ChardevMux, 1);
3600 backend->kind = CHARDEV_BACKEND_KIND_MUX;
3601 backend->mux->chardev = g_strdup(bid);
3602 ret = qmp_chardev_add(id, backend, errp);
3603 if (!ret) {
3604 chr = qemu_chr_find(bid);
3605 qemu_chr_delete(chr);
3606 chr = NULL;
3607 goto qapi_out;
3608 }
3609 }
3610
3611 chr = qemu_chr_find(id);
Gerd Hoffmann2274ae92012-10-15 09:30:59 +02003612 chr->opts = opts;
Peter Maydella61ae7f2014-09-02 11:24:16 +01003613
3614qapi_out:
3615 qapi_free_ChardevBackend(backend);
3616 qapi_free_ChardevReturn(ret);
3617 g_free(bid);
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003618 return chr;
Gerd Hoffmann2274ae92012-10-15 09:30:59 +02003619
3620err:
3621 qemu_opts_del(opts);
3622 return NULL;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003623}
3624
Anthony Liguori27143a42011-08-15 11:17:36 -05003625CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
aliguori6f97dba2008-10-31 18:49:55 +00003626{
3627 const char *p;
3628 CharDriverState *chr;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003629 QemuOpts *opts;
Gerd Hoffmannbd2d80b2012-10-15 09:28:05 +02003630 Error *err = NULL;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003631
Gerd Hoffmannc845f402009-09-10 10:58:52 +02003632 if (strstart(filename, "chardev:", &p)) {
3633 return qemu_chr_find(p);
3634 }
3635
Gerd Hoffmann191bc012009-09-10 10:58:35 +02003636 opts = qemu_chr_parse_compat(label, filename);
Gerd Hoffmann7e1b35b2009-09-10 10:58:51 +02003637 if (!opts)
3638 return NULL;
aliguori6f97dba2008-10-31 18:49:55 +00003639
Gerd Hoffmannbd2d80b2012-10-15 09:28:05 +02003640 chr = qemu_chr_new_from_opts(opts, init, &err);
Markus Armbruster84d18f02014-01-30 15:07:28 +01003641 if (err) {
Seiji Aguchi4a44d852013-08-05 15:40:44 -04003642 error_report("%s", error_get_pretty(err));
Gerd Hoffmannbd2d80b2012-10-15 09:28:05 +02003643 error_free(err);
3644 }
Gerd Hoffmann7e1b35b2009-09-10 10:58:51 +02003645 if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
Hans de Goede456d6062013-03-27 20:29:40 +01003646 qemu_chr_fe_claim_no_fail(chr);
Gerd Hoffmann7e1b35b2009-09-10 10:58:51 +02003647 monitor_init(chr, MONITOR_USE_READLINE);
aliguori6f97dba2008-10-31 18:49:55 +00003648 }
3649 return chr;
3650}
3651
Anthony Liguori15f31512011-08-15 11:17:35 -05003652void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
Paolo Bonzinic48855e2010-12-23 13:42:48 +01003653{
3654 if (chr->chr_set_echo) {
3655 chr->chr_set_echo(chr, echo);
3656 }
3657}
3658
Hans de Goede8e25daa2013-03-26 11:07:57 +01003659void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open)
Hans de Goede7c32c4f2011-03-24 11:12:02 +01003660{
Hans de Goede8e25daa2013-03-26 11:07:57 +01003661 if (chr->fe_open == fe_open) {
Hans de Goedec0c4bd22013-03-26 11:07:55 +01003662 return;
3663 }
Hans de Goede8e25daa2013-03-26 11:07:57 +01003664 chr->fe_open = fe_open;
Hans de Goede574b7112013-03-26 11:07:58 +01003665 if (chr->chr_set_fe_open) {
3666 chr->chr_set_fe_open(chr, fe_open);
Hans de Goede7c32c4f2011-03-24 11:12:02 +01003667 }
3668}
3669
Marc-André Lureaud61b0c92013-12-01 22:23:39 +01003670void qemu_chr_fe_event(struct CharDriverState *chr, int event)
3671{
3672 if (chr->chr_fe_event) {
3673 chr->chr_fe_event(chr, event);
3674 }
3675}
3676
Kevin Wolf2c8a5942013-03-19 13:38:09 +01003677int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
3678 GIOFunc func, void *user_data)
Anthony Liguori23673ca2013-03-05 23:21:23 +05303679{
3680 GSource *src;
3681 guint tag;
3682
3683 if (s->chr_add_watch == NULL) {
3684 return -ENOSYS;
3685 }
3686
3687 src = s->chr_add_watch(s, cond);
Paolo Bonzini62c339c2014-07-24 16:08:04 +02003688 if (!src) {
3689 return -EINVAL;
3690 }
3691
Anthony Liguori23673ca2013-03-05 23:21:23 +05303692 g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
3693 tag = g_source_attach(src, NULL);
3694 g_source_unref(src);
3695
3696 return tag;
3697}
3698
Hans de Goede44c473d2013-03-27 20:29:39 +01003699int qemu_chr_fe_claim(CharDriverState *s)
3700{
3701 if (s->avail_connections < 1) {
3702 return -1;
3703 }
3704 s->avail_connections--;
3705 return 0;
3706}
3707
3708void qemu_chr_fe_claim_no_fail(CharDriverState *s)
3709{
3710 if (qemu_chr_fe_claim(s) != 0) {
3711 fprintf(stderr, "%s: error chardev \"%s\" already used\n",
3712 __func__, s->label);
3713 exit(1);
3714 }
3715}
3716
3717void qemu_chr_fe_release(CharDriverState *s)
3718{
3719 s->avail_connections++;
3720}
3721
Anthony Liguori70f24fb2011-08-15 11:17:38 -05003722void qemu_chr_delete(CharDriverState *chr)
aliguori6f97dba2008-10-31 18:49:55 +00003723{
Blue Swirl72cf2d42009-09-12 07:36:22 +00003724 QTAILQ_REMOVE(&chardevs, chr, next);
Gerd Hoffmann2274ae92012-10-15 09:30:59 +02003725 if (chr->chr_close) {
aliguori6f97dba2008-10-31 18:49:55 +00003726 chr->chr_close(chr);
Gerd Hoffmann2274ae92012-10-15 09:30:59 +02003727 }
Anthony Liguori7267c092011-08-20 22:09:37 -05003728 g_free(chr->filename);
3729 g_free(chr->label);
Gerd Hoffmann2274ae92012-10-15 09:30:59 +02003730 if (chr->opts) {
3731 qemu_opts_del(chr->opts);
3732 }
Anthony Liguori7267c092011-08-20 22:09:37 -05003733 g_free(chr);
aliguori6f97dba2008-10-31 18:49:55 +00003734}
3735
Luiz Capitulinoc5a415a2011-09-14 16:05:49 -03003736ChardevInfoList *qmp_query_chardev(Error **errp)
aliguori6f97dba2008-10-31 18:49:55 +00003737{
Luiz Capitulinoc5a415a2011-09-14 16:05:49 -03003738 ChardevInfoList *chr_list = NULL;
aliguori6f97dba2008-10-31 18:49:55 +00003739 CharDriverState *chr;
3740
Blue Swirl72cf2d42009-09-12 07:36:22 +00003741 QTAILQ_FOREACH(chr, &chardevs, next) {
Luiz Capitulinoc5a415a2011-09-14 16:05:49 -03003742 ChardevInfoList *info = g_malloc0(sizeof(*info));
3743 info->value = g_malloc0(sizeof(*info->value));
3744 info->value->label = g_strdup(chr->label);
3745 info->value->filename = g_strdup(chr->filename);
Laszlo Ersek32a97ea2014-06-26 17:50:03 +02003746 info->value->frontend_open = chr->fe_open;
Luiz Capitulinoc5a415a2011-09-14 16:05:49 -03003747
3748 info->next = chr_list;
3749 chr_list = info;
aliguori6f97dba2008-10-31 18:49:55 +00003750 }
Luiz Capitulino588b3832009-12-10 17:16:08 -02003751
Luiz Capitulinoc5a415a2011-09-14 16:05:49 -03003752 return chr_list;
aliguori6f97dba2008-10-31 18:49:55 +00003753}
Gerd Hoffmannc845f402009-09-10 10:58:52 +02003754
Martin Kletzander77d1c3c2014-02-01 12:52:42 +01003755ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
3756{
3757 ChardevBackendInfoList *backend_list = NULL;
3758 CharDriver *c = NULL;
3759 GSList *i = NULL;
3760
3761 for (i = backends; i; i = i->next) {
3762 ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
3763 c = i->data;
3764 info->value = g_malloc0(sizeof(*info->value));
3765 info->value->name = g_strdup(c->name);
3766
3767 info->next = backend_list;
3768 backend_list = info;
3769 }
3770
3771 return backend_list;
3772}
3773
Gerd Hoffmannc845f402009-09-10 10:58:52 +02003774CharDriverState *qemu_chr_find(const char *name)
3775{
3776 CharDriverState *chr;
3777
Blue Swirl72cf2d42009-09-12 07:36:22 +00003778 QTAILQ_FOREACH(chr, &chardevs, next) {
Gerd Hoffmannc845f402009-09-10 10:58:52 +02003779 if (strcmp(chr->label, name) != 0)
3780 continue;
3781 return chr;
3782 }
3783 return NULL;
3784}
Anthony Liguori0beb4942011-12-22 15:29:25 -06003785
3786/* Get a character (serial) device interface. */
3787CharDriverState *qemu_char_get_next_serial(void)
3788{
3789 static int next_serial;
Hans de Goede456d6062013-03-27 20:29:40 +01003790 CharDriverState *chr;
Anthony Liguori0beb4942011-12-22 15:29:25 -06003791
3792 /* FIXME: This function needs to go away: use chardev properties! */
Hans de Goede456d6062013-03-27 20:29:40 +01003793
3794 while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) {
3795 chr = serial_hds[next_serial++];
3796 qemu_chr_fe_claim_no_fail(chr);
3797 return chr;
3798 }
3799 return NULL;
Anthony Liguori0beb4942011-12-22 15:29:25 -06003800}
3801
Paolo Bonzini4d454572012-11-26 16:03:42 +01003802QemuOptsList qemu_chardev_opts = {
3803 .name = "chardev",
3804 .implied_opt_name = "backend",
3805 .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
3806 .desc = {
3807 {
3808 .name = "backend",
3809 .type = QEMU_OPT_STRING,
3810 },{
3811 .name = "path",
3812 .type = QEMU_OPT_STRING,
3813 },{
3814 .name = "host",
3815 .type = QEMU_OPT_STRING,
3816 },{
3817 .name = "port",
3818 .type = QEMU_OPT_STRING,
3819 },{
3820 .name = "localaddr",
3821 .type = QEMU_OPT_STRING,
3822 },{
3823 .name = "localport",
3824 .type = QEMU_OPT_STRING,
3825 },{
3826 .name = "to",
3827 .type = QEMU_OPT_NUMBER,
3828 },{
3829 .name = "ipv4",
3830 .type = QEMU_OPT_BOOL,
3831 },{
3832 .name = "ipv6",
3833 .type = QEMU_OPT_BOOL,
3834 },{
3835 .name = "wait",
3836 .type = QEMU_OPT_BOOL,
3837 },{
3838 .name = "server",
3839 .type = QEMU_OPT_BOOL,
3840 },{
3841 .name = "delay",
3842 .type = QEMU_OPT_BOOL,
3843 },{
3844 .name = "telnet",
3845 .type = QEMU_OPT_BOOL,
3846 },{
3847 .name = "width",
3848 .type = QEMU_OPT_NUMBER,
3849 },{
3850 .name = "height",
3851 .type = QEMU_OPT_NUMBER,
3852 },{
3853 .name = "cols",
3854 .type = QEMU_OPT_NUMBER,
3855 },{
3856 .name = "rows",
3857 .type = QEMU_OPT_NUMBER,
3858 },{
3859 .name = "mux",
3860 .type = QEMU_OPT_BOOL,
3861 },{
3862 .name = "signal",
3863 .type = QEMU_OPT_BOOL,
3864 },{
3865 .name = "name",
3866 .type = QEMU_OPT_STRING,
3867 },{
3868 .name = "debug",
3869 .type = QEMU_OPT_NUMBER,
Lei Li51767e72013-01-25 00:03:19 +08003870 },{
Markus Armbruster3949e592013-02-06 21:27:24 +01003871 .name = "size",
Markus Armbrusterde1cc362013-02-06 21:27:25 +01003872 .type = QEMU_OPT_SIZE,
Gerd Hoffmannbb6fb7c2013-06-24 08:39:54 +02003873 },{
3874 .name = "chardev",
3875 .type = QEMU_OPT_STRING,
Paolo Bonzini4d454572012-11-26 16:03:42 +01003876 },
3877 { /* end of list */ }
3878 },
3879};
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01003880
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003881#ifdef _WIN32
3882
3883static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
3884{
3885 HANDLE out;
3886
Gerd Hoffmanne859eda2013-06-24 08:39:47 +02003887 if (file->has_in) {
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003888 error_setg(errp, "input file not supported");
3889 return NULL;
3890 }
3891
3892 out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3893 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3894 if (out == INVALID_HANDLE_VALUE) {
3895 error_setg(errp, "open %s failed", file->out);
3896 return NULL;
3897 }
3898 return qemu_chr_open_win_file(out);
3899}
3900
Markus Armbrusterd36b2b92013-02-13 15:54:16 +01003901static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
3902 Error **errp)
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01003903{
Markus Armbrusterd36b2b92013-02-13 15:54:16 +01003904 return qemu_chr_open_win_path(serial->device);
3905}
3906
3907static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
3908 Error **errp)
3909{
3910 error_setg(errp, "character device backend type 'parallel' not supported");
3911 return NULL;
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01003912}
3913
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003914#else /* WIN32 */
3915
3916static int qmp_chardev_open_file_source(char *src, int flags,
3917 Error **errp)
3918{
3919 int fd = -1;
3920
3921 TFR(fd = qemu_open(src, flags, 0666));
3922 if (fd == -1) {
Gerd Hoffmann20c39762013-06-24 08:39:48 +02003923 error_setg_file_open(errp, errno, src);
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003924 }
3925 return fd;
3926}
3927
3928static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
3929{
Markus Armbruster5f758362014-05-19 18:57:34 +02003930 int flags, in = -1, out;
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003931
3932 flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
3933 out = qmp_chardev_open_file_source(file->out, flags, errp);
Markus Armbruster5f758362014-05-19 18:57:34 +02003934 if (out < 0) {
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003935 return NULL;
3936 }
3937
Gerd Hoffmanne859eda2013-06-24 08:39:47 +02003938 if (file->has_in) {
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003939 flags = O_RDONLY;
3940 in = qmp_chardev_open_file_source(file->in, flags, errp);
Markus Armbruster5f758362014-05-19 18:57:34 +02003941 if (in < 0) {
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003942 qemu_close(out);
3943 return NULL;
3944 }
3945 }
3946
3947 return qemu_chr_open_fd(in, out);
3948}
3949
Markus Armbrusterd36b2b92013-02-13 15:54:16 +01003950static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
3951 Error **errp)
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01003952{
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01003953#ifdef HAVE_CHARDEV_TTY
Markus Armbrusterd36b2b92013-02-13 15:54:16 +01003954 int fd;
3955
3956 fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
Markus Armbruster5f758362014-05-19 18:57:34 +02003957 if (fd < 0) {
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01003958 return NULL;
3959 }
Stefan Hajnoczif9e8cac2013-03-27 10:10:43 +01003960 qemu_set_nonblock(fd);
Markus Armbrusterd36b2b92013-02-13 15:54:16 +01003961 return qemu_chr_open_tty_fd(fd);
3962#else
3963 error_setg(errp, "character device backend type 'serial' not supported");
3964 return NULL;
3965#endif
3966}
3967
3968static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
3969 Error **errp)
3970{
3971#ifdef HAVE_CHARDEV_PARPORT
3972 int fd;
3973
3974 fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
Markus Armbruster5f758362014-05-19 18:57:34 +02003975 if (fd < 0) {
Markus Armbrusterd36b2b92013-02-13 15:54:16 +01003976 return NULL;
3977 }
3978 return qemu_chr_open_pp_fd(fd);
3979#else
3980 error_setg(errp, "character device backend type 'parallel' not supported");
3981 return NULL;
3982#endif
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01003983}
3984
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01003985#endif /* WIN32 */
3986
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01003987static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
3988 Error **errp)
3989{
Corey Minyard43ded1a2014-10-02 11:17:34 -05003990 CharDriverState *chr;
3991 TCPCharDriver *s;
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01003992 SocketAddress *addr = sock->addr;
3993 bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
3994 bool is_listen = sock->has_server ? sock->server : true;
3995 bool is_telnet = sock->has_telnet ? sock->telnet : false;
3996 bool is_waitconnect = sock->has_wait ? sock->wait : false;
Corey Minyard43ded1a2014-10-02 11:17:34 -05003997
3998 chr = qemu_chr_alloc();
3999 s = g_malloc0(sizeof(TCPCharDriver));
4000
4001 s->fd = -1;
4002 s->listen_fd = -1;
4003 s->is_unix = addr->kind == SOCKET_ADDRESS_KIND_UNIX;
Corey Minyardcfb429c2014-10-02 11:17:35 -05004004 s->is_listen = is_listen;
4005 s->is_telnet = is_telnet;
Corey Minyard43ded1a2014-10-02 11:17:34 -05004006 s->do_nodelay = do_nodelay;
Corey Minyardcfb429c2014-10-02 11:17:35 -05004007 qapi_copy_SocketAddress(&s->addr, sock->addr);
Corey Minyard43ded1a2014-10-02 11:17:34 -05004008
4009 chr->opaque = s;
4010 chr->chr_write = tcp_chr_write;
4011 chr->chr_sync_read = tcp_chr_sync_read;
4012 chr->chr_close = tcp_chr_close;
4013 chr->get_msgfds = tcp_get_msgfds;
4014 chr->set_msgfds = tcp_set_msgfds;
4015 chr->chr_add_client = tcp_chr_add_client;
4016 chr->chr_add_watch = tcp_chr_add_watch;
4017 chr->chr_update_read_handler = tcp_chr_update_read_handler;
4018 /* be isn't opened until we get a connection */
4019 chr->explicit_be_open = true;
4020
4021 chr->filename = g_malloc(CHR_MAX_FILENAME_SIZE);
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01004022
4023 if (is_listen) {
Corey Minyard43ded1a2014-10-02 11:17:34 -05004024 if (is_telnet) {
4025 s->do_telnetopt = 1;
4026 }
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01004027 }
Corey Minyard43ded1a2014-10-02 11:17:34 -05004028
Corey Minyardcfb429c2014-10-02 11:17:35 -05004029 if (!qemu_chr_open_socket_fd(chr, errp)) {
Corey Minyard43ded1a2014-10-02 11:17:34 -05004030 g_free(s);
4031 g_free(chr->filename);
4032 g_free(chr);
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01004033 return NULL;
4034 }
Corey Minyard43ded1a2014-10-02 11:17:34 -05004035
4036 if (is_listen && is_waitconnect) {
4037 fprintf(stderr, "QEMU waiting for connection on: %s\n",
4038 chr->filename);
4039 tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
4040 qemu_set_nonblock(s->listen_fd);
4041 }
4042
4043 return chr;
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01004044}
4045
Lei Li08d0ab32013-05-20 14:51:03 +08004046static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp,
4047 Error **errp)
Gerd Hoffmann3ecc0592013-02-27 14:10:47 +01004048{
4049 int fd;
4050
Lei Li08d0ab32013-05-20 14:51:03 +08004051 fd = socket_dgram(udp->remote, udp->local, errp);
Markus Armbruster5f758362014-05-19 18:57:34 +02004052 if (fd < 0) {
Gerd Hoffmann3ecc0592013-02-27 14:10:47 +01004053 return NULL;
4054 }
4055 return qemu_chr_open_udp_fd(fd);
4056}
4057
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004058ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
4059 Error **errp)
4060{
4061 ChardevReturn *ret = g_new0(ChardevReturn, 1);
Gerd Hoffmannedb2fb32013-02-21 16:16:42 +01004062 CharDriverState *base, *chr = NULL;
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004063
4064 chr = qemu_chr_find(id);
4065 if (chr) {
4066 error_setg(errp, "Chardev '%s' already exists", id);
4067 g_free(ret);
4068 return NULL;
4069 }
4070
4071 switch (backend->kind) {
Gerd Hoffmannffbdbe52012-12-19 13:13:57 +01004072 case CHARDEV_BACKEND_KIND_FILE:
4073 chr = qmp_chardev_open_file(backend->file, errp);
4074 break;
Markus Armbrusterd36b2b92013-02-13 15:54:16 +01004075 case CHARDEV_BACKEND_KIND_SERIAL:
4076 chr = qmp_chardev_open_serial(backend->serial, errp);
4077 break;
4078 case CHARDEV_BACKEND_KIND_PARALLEL:
4079 chr = qmp_chardev_open_parallel(backend->parallel, errp);
Gerd Hoffmannd59044e2012-12-19 13:50:29 +01004080 break;
Gerd Hoffmann548cbb32013-02-25 11:50:55 +01004081 case CHARDEV_BACKEND_KIND_PIPE:
4082 chr = qemu_chr_open_pipe(backend->pipe);
4083 break;
Gerd Hoffmannf6bd5d62012-12-20 13:53:12 +01004084 case CHARDEV_BACKEND_KIND_SOCKET:
4085 chr = qmp_chardev_open_socket(backend->socket, errp);
4086 break;
Lei Li08d0ab32013-05-20 14:51:03 +08004087 case CHARDEV_BACKEND_KIND_UDP:
4088 chr = qmp_chardev_open_udp(backend->udp, errp);
Gerd Hoffmann3ecc0592013-02-27 14:10:47 +01004089 break;
Gerd Hoffmann0a1a7fa2012-12-20 14:39:13 +01004090#ifdef HAVE_CHARDEV_TTY
4091 case CHARDEV_BACKEND_KIND_PTY:
Gerd Hoffmanne68c5952013-02-25 10:16:46 +01004092 chr = qemu_chr_open_pty(id, ret);
Gerd Hoffmann0a1a7fa2012-12-20 14:39:13 +01004093 break;
Gerd Hoffmann0a1a7fa2012-12-20 14:39:13 +01004094#endif
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004095 case CHARDEV_BACKEND_KIND_NULL:
Gerd Hoffmann80dca9e2013-02-21 11:41:26 +01004096 chr = qemu_chr_open_null();
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004097 break;
Gerd Hoffmannedb2fb32013-02-21 16:16:42 +01004098 case CHARDEV_BACKEND_KIND_MUX:
4099 base = qemu_chr_find(backend->mux->chardev);
4100 if (base == NULL) {
4101 error_setg(errp, "mux: base chardev %s not found",
4102 backend->mux->chardev);
4103 break;
4104 }
4105 chr = qemu_chr_open_mux(base);
4106 break;
Gerd Hoffmannf5a51ca2013-02-21 11:58:44 +01004107 case CHARDEV_BACKEND_KIND_MSMOUSE:
4108 chr = qemu_chr_open_msmouse();
4109 break;
Gerd Hoffmann2d572862013-02-21 12:56:10 +01004110#ifdef CONFIG_BRLAPI
4111 case CHARDEV_BACKEND_KIND_BRAILLE:
4112 chr = chr_baum_init();
4113 break;
4114#endif
Paolo Bonzini56923992014-07-11 09:44:26 +02004115 case CHARDEV_BACKEND_KIND_TESTDEV:
4116 chr = chr_testdev_init();
4117 break;
Gerd Hoffmann7c358032013-02-21 12:34:58 +01004118 case CHARDEV_BACKEND_KIND_STDIO:
4119 chr = qemu_chr_open_stdio(backend->stdio);
4120 break;
Gerd Hoffmannd9ac3742013-02-25 11:48:06 +01004121#ifdef _WIN32
4122 case CHARDEV_BACKEND_KIND_CONSOLE:
4123 chr = qemu_chr_open_win_con();
4124 break;
4125#endif
Gerd Hoffmanncd153e22013-02-25 12:39:06 +01004126#ifdef CONFIG_SPICE
4127 case CHARDEV_BACKEND_KIND_SPICEVMC:
4128 chr = qemu_chr_open_spice_vmc(backend->spicevmc->type);
4129 break;
4130 case CHARDEV_BACKEND_KIND_SPICEPORT:
4131 chr = qemu_chr_open_spice_port(backend->spiceport->fqdn);
4132 break;
4133#endif
Gerd Hoffmann702ec692013-02-25 15:52:32 +01004134 case CHARDEV_BACKEND_KIND_VC:
4135 chr = vc_init(backend->vc);
4136 break;
Markus Armbruster3a1da422013-07-26 16:44:34 +02004137 case CHARDEV_BACKEND_KIND_RINGBUF:
Gerd Hoffmann1da48c62013-02-26 16:21:11 +01004138 case CHARDEV_BACKEND_KIND_MEMORY:
Markus Armbruster3a1da422013-07-26 16:44:34 +02004139 chr = qemu_chr_open_ringbuf(backend->ringbuf, errp);
Gerd Hoffmann1da48c62013-02-26 16:21:11 +01004140 break;
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004141 default:
4142 error_setg(errp, "unknown chardev backend (%d)", backend->kind);
4143 break;
4144 }
4145
Markus Armbruster3894c782014-05-19 18:57:36 +02004146 /*
4147 * Character backend open hasn't been fully converted to the Error
4148 * API. Some opens fail without setting an error. Set a generic
4149 * error then.
4150 * TODO full conversion to Error API
4151 */
4152 if (chr == NULL && errp && !*errp) {
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004153 error_setg(errp, "Failed to create chardev");
4154 }
4155 if (chr) {
4156 chr->label = g_strdup(id);
Gerd Hoffmannedb2fb32013-02-21 16:16:42 +01004157 chr->avail_connections =
4158 (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
Gerd Hoffmann60d95382013-05-27 12:41:24 +02004159 if (!chr->filename) {
4160 chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
4161 }
Michael Rothbd5c51e2013-06-07 15:19:53 -05004162 if (!chr->explicit_be_open) {
4163 qemu_chr_be_event(chr, CHR_EVENT_OPENED);
4164 }
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004165 QTAILQ_INSERT_TAIL(&chardevs, chr, next);
4166 return ret;
4167 } else {
4168 g_free(ret);
4169 return NULL;
4170 }
4171}
4172
4173void qmp_chardev_remove(const char *id, Error **errp)
4174{
4175 CharDriverState *chr;
4176
4177 chr = qemu_chr_find(id);
Gonglei8108fd32014-08-11 21:00:55 +08004178 if (chr == NULL) {
Gerd Hoffmannf1a1a352012-12-19 10:33:56 +01004179 error_setg(errp, "Chardev '%s' not found", id);
4180 return;
4181 }
4182 if (chr->chr_can_read || chr->chr_read ||
4183 chr->chr_event || chr->handler_opaque) {
4184 error_setg(errp, "Chardev '%s' is busy", id);
4185 return;
4186 }
4187 qemu_chr_delete(chr);
4188}
Anthony Liguorid654f342013-03-05 23:21:28 +05304189
4190static void register_types(void)
4191{
Peter Maydelle4d50d42014-09-02 11:24:17 +01004192 register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL);
4193 register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET,
4194 qemu_chr_parse_socket);
4195 register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp);
4196 register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
4197 qemu_chr_parse_ringbuf);
4198 register_char_driver("file", CHARDEV_BACKEND_KIND_FILE,
4199 qemu_chr_parse_file_out);
4200 register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO,
4201 qemu_chr_parse_stdio);
4202 register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL,
4203 qemu_chr_parse_serial);
4204 register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL,
4205 qemu_chr_parse_serial);
4206 register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
4207 qemu_chr_parse_parallel);
4208 register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL,
4209 qemu_chr_parse_parallel);
4210 register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL);
4211 register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
4212 register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE,
4213 qemu_chr_parse_pipe);
4214 register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux);
Markus Armbrusterc11ed962013-07-26 16:44:33 +02004215 /* Bug-compatibility: */
Peter Maydelle4d50d42014-09-02 11:24:17 +01004216 register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY,
4217 qemu_chr_parse_ringbuf);
Michael Roth7b7ab182013-07-30 13:04:22 -05004218 /* this must be done after machine init, since we register FEs with muxes
4219 * as part of realize functions like serial_isa_realizefn when -nographic
4220 * is specified
4221 */
4222 qemu_add_machine_init_done_notifier(&muxes_realize_notify);
Anthony Liguorid654f342013-03-05 23:21:28 +05304223}
4224
4225type_init(register_types);