Statistics
| Branch: | Revision:

root / qemu-char.c @ db895a1e

History | View | Annotate | Download (98.1 kB)

1 6f97dba0 aliguori
/*
2 6f97dba0 aliguori
 * QEMU System Emulator
3 6f97dba0 aliguori
 *
4 6f97dba0 aliguori
 * Copyright (c) 2003-2008 Fabrice Bellard
5 6f97dba0 aliguori
 *
6 6f97dba0 aliguori
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 6f97dba0 aliguori
 * of this software and associated documentation files (the "Software"), to deal
8 6f97dba0 aliguori
 * in the Software without restriction, including without limitation the rights
9 6f97dba0 aliguori
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 6f97dba0 aliguori
 * copies of the Software, and to permit persons to whom the Software is
11 6f97dba0 aliguori
 * furnished to do so, subject to the following conditions:
12 6f97dba0 aliguori
 *
13 6f97dba0 aliguori
 * The above copyright notice and this permission notice shall be included in
14 6f97dba0 aliguori
 * all copies or substantial portions of the Software.
15 6f97dba0 aliguori
 *
16 6f97dba0 aliguori
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 6f97dba0 aliguori
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 6f97dba0 aliguori
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 6f97dba0 aliguori
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 6f97dba0 aliguori
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 6f97dba0 aliguori
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 6f97dba0 aliguori
 * THE SOFTWARE.
23 6f97dba0 aliguori
 */
24 6f97dba0 aliguori
#include "qemu-common.h"
25 83c9089e Paolo Bonzini
#include "monitor/monitor.h"
26 28ecbaee Paolo Bonzini
#include "ui/console.h"
27 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
28 1de7afc9 Paolo Bonzini
#include "qemu/timer.h"
29 dccfcd0e Paolo Bonzini
#include "sysemu/char.h"
30 cf3ebac7 aurel32
#include "hw/usb.h"
31 c5a415a0 Luiz Capitulino
#include "qmp-commands.h"
32 6f97dba0 aliguori
33 6f97dba0 aliguori
#include <unistd.h>
34 6f97dba0 aliguori
#include <fcntl.h>
35 6f97dba0 aliguori
#include <time.h>
36 6f97dba0 aliguori
#include <errno.h>
37 6f97dba0 aliguori
#include <sys/time.h>
38 6f97dba0 aliguori
#include <zlib.h>
39 6f97dba0 aliguori
40 6f97dba0 aliguori
#ifndef _WIN32
41 6f97dba0 aliguori
#include <sys/times.h>
42 6f97dba0 aliguori
#include <sys/wait.h>
43 6f97dba0 aliguori
#include <termios.h>
44 6f97dba0 aliguori
#include <sys/mman.h>
45 6f97dba0 aliguori
#include <sys/ioctl.h>
46 24646c7e blueswir1
#include <sys/resource.h>
47 6f97dba0 aliguori
#include <sys/socket.h>
48 6f97dba0 aliguori
#include <netinet/in.h>
49 24646c7e blueswir1
#include <net/if.h>
50 24646c7e blueswir1
#include <arpa/inet.h>
51 6f97dba0 aliguori
#include <dirent.h>
52 6f97dba0 aliguori
#include <netdb.h>
53 6f97dba0 aliguori
#include <sys/select.h>
54 71e72a19 Juan Quintela
#ifdef CONFIG_BSD
55 6f97dba0 aliguori
#include <sys/stat.h>
56 3294ce18 Michael Tokarev
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
57 3294ce18 Michael Tokarev
#include <dev/ppbus/ppi.h>
58 3294ce18 Michael Tokarev
#include <dev/ppbus/ppbconf.h>
59 c5e97233 blueswir1
#elif defined(__DragonFly__)
60 c5e97233 blueswir1
#include <dev/misc/ppi/ppi.h>
61 c5e97233 blueswir1
#include <bus/ppbus/ppbconf.h>
62 6f97dba0 aliguori
#endif
63 bbe813a2 Aurelien Jarno
#else
64 6f97dba0 aliguori
#ifdef __linux__
65 6f97dba0 aliguori
#include <linux/ppdev.h>
66 6f97dba0 aliguori
#include <linux/parport.h>
67 6f97dba0 aliguori
#endif
68 6f97dba0 aliguori
#ifdef __sun__
69 6f97dba0 aliguori
#include <sys/stat.h>
70 6f97dba0 aliguori
#include <sys/ethernet.h>
71 6f97dba0 aliguori
#include <sys/sockio.h>
72 6f97dba0 aliguori
#include <netinet/arp.h>
73 6f97dba0 aliguori
#include <netinet/in.h>
74 6f97dba0 aliguori
#include <netinet/in_systm.h>
75 6f97dba0 aliguori
#include <netinet/ip.h>
76 6f97dba0 aliguori
#include <netinet/ip_icmp.h> // must come after ip.h
77 6f97dba0 aliguori
#include <netinet/udp.h>
78 6f97dba0 aliguori
#include <netinet/tcp.h>
79 6f97dba0 aliguori
#include <net/if.h>
80 6f97dba0 aliguori
#include <syslog.h>
81 6f97dba0 aliguori
#endif
82 6f97dba0 aliguori
#endif
83 6f97dba0 aliguori
#endif
84 6f97dba0 aliguori
85 1de7afc9 Paolo Bonzini
#include "qemu/sockets.h"
86 cbcc6336 Alon Levy
#include "ui/qemu-spice.h"
87 6f97dba0 aliguori
88 9bd7854e Amit Shah
#define READ_BUF_LEN 4096
89 9bd7854e Amit Shah
90 6f97dba0 aliguori
/***********************************************************/
91 6f97dba0 aliguori
/* character device */
92 6f97dba0 aliguori
93 72cf2d4f Blue Swirl
static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
94 72cf2d4f Blue Swirl
    QTAILQ_HEAD_INITIALIZER(chardevs);
95 2970a6c9 aliguori
96 a425d23f Hans de Goede
void qemu_chr_be_event(CharDriverState *s, int event)
97 6f97dba0 aliguori
{
98 73cdf3f2 Alexander Graf
    /* Keep track if the char device is open */
99 73cdf3f2 Alexander Graf
    switch (event) {
100 73cdf3f2 Alexander Graf
        case CHR_EVENT_OPENED:
101 16665b94 Hans de Goede
            s->be_open = 1;
102 73cdf3f2 Alexander Graf
            break;
103 73cdf3f2 Alexander Graf
        case CHR_EVENT_CLOSED:
104 16665b94 Hans de Goede
            s->be_open = 0;
105 73cdf3f2 Alexander Graf
            break;
106 73cdf3f2 Alexander Graf
    }
107 73cdf3f2 Alexander Graf
108 6f97dba0 aliguori
    if (!s->chr_event)
109 6f97dba0 aliguori
        return;
110 6f97dba0 aliguori
    s->chr_event(s->handler_opaque, event);
111 6f97dba0 aliguori
}
112 6f97dba0 aliguori
113 fee204fd Hans de Goede
static gboolean qemu_chr_be_generic_open_bh(gpointer opaque)
114 6f97dba0 aliguori
{
115 6f97dba0 aliguori
    CharDriverState *s = opaque;
116 a425d23f Hans de Goede
    qemu_chr_be_event(s, CHR_EVENT_OPENED);
117 9f939df9 Anthony Liguori
    s->idle_tag = 0;
118 9f939df9 Anthony Liguori
    return FALSE;
119 6f97dba0 aliguori
}
120 6f97dba0 aliguori
121 fee204fd Hans de Goede
void qemu_chr_be_generic_open(CharDriverState *s)
122 6f97dba0 aliguori
{
123 9f939df9 Anthony Liguori
    if (s->idle_tag == 0) {
124 fee204fd Hans de Goede
        s->idle_tag = g_idle_add(qemu_chr_be_generic_open_bh, s);
125 6f97dba0 aliguori
    }
126 6f97dba0 aliguori
}
127 6f97dba0 aliguori
128 2cc6e0a1 Anthony Liguori
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
129 6f97dba0 aliguori
{
130 6f97dba0 aliguori
    return s->chr_write(s, buf, len);
131 6f97dba0 aliguori
}
132 6f97dba0 aliguori
133 cd18720a Anthony Liguori
int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len)
134 cd18720a Anthony Liguori
{
135 cd18720a Anthony Liguori
    int offset = 0;
136 cd18720a Anthony Liguori
    int res;
137 cd18720a Anthony Liguori
138 cd18720a Anthony Liguori
    while (offset < len) {
139 cd18720a Anthony Liguori
        do {
140 cd18720a Anthony Liguori
            res = s->chr_write(s, buf + offset, len - offset);
141 cd18720a Anthony Liguori
            if (res == -1 && errno == EAGAIN) {
142 cd18720a Anthony Liguori
                g_usleep(100);
143 cd18720a Anthony Liguori
            }
144 cd18720a Anthony Liguori
        } while (res == -1 && errno == EAGAIN);
145 cd18720a Anthony Liguori
146 cd18720a Anthony Liguori
        if (res == 0) {
147 cd18720a Anthony Liguori
            break;
148 cd18720a Anthony Liguori
        }
149 cd18720a Anthony Liguori
150 cd18720a Anthony Liguori
        if (res < 0) {
151 cd18720a Anthony Liguori
            return res;
152 cd18720a Anthony Liguori
        }
153 cd18720a Anthony Liguori
154 cd18720a Anthony Liguori
        offset += res;
155 cd18720a Anthony Liguori
    }
156 cd18720a Anthony Liguori
157 cd18720a Anthony Liguori
    return offset;
158 cd18720a Anthony Liguori
}
159 cd18720a Anthony Liguori
160 41084f1b Anthony Liguori
int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
161 6f97dba0 aliguori
{
162 6f97dba0 aliguori
    if (!s->chr_ioctl)
163 6f97dba0 aliguori
        return -ENOTSUP;
164 6f97dba0 aliguori
    return s->chr_ioctl(s, cmd, arg);
165 6f97dba0 aliguori
}
166 6f97dba0 aliguori
167 909cda12 Anthony Liguori
int qemu_chr_be_can_write(CharDriverState *s)
168 6f97dba0 aliguori
{
169 6f97dba0 aliguori
    if (!s->chr_can_read)
170 6f97dba0 aliguori
        return 0;
171 6f97dba0 aliguori
    return s->chr_can_read(s->handler_opaque);
172 6f97dba0 aliguori
}
173 6f97dba0 aliguori
174 fa5efccb Anthony Liguori
void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
175 6f97dba0 aliguori
{
176 ac310734 Stefan Weil
    if (s->chr_read) {
177 ac310734 Stefan Weil
        s->chr_read(s->handler_opaque, buf, len);
178 ac310734 Stefan Weil
    }
179 6f97dba0 aliguori
}
180 6f97dba0 aliguori
181 74c0d6f0 Anthony Liguori
int qemu_chr_fe_get_msgfd(CharDriverState *s)
182 7d174059 Mark McLoughlin
{
183 7d174059 Mark McLoughlin
    return s->get_msgfd ? s->get_msgfd(s) : -1;
184 7d174059 Mark McLoughlin
}
185 7d174059 Mark McLoughlin
186 13661089 Daniel P. Berrange
int qemu_chr_add_client(CharDriverState *s, int fd)
187 13661089 Daniel P. Berrange
{
188 13661089 Daniel P. Berrange
    return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
189 13661089 Daniel P. Berrange
}
190 13661089 Daniel P. Berrange
191 6f97dba0 aliguori
void qemu_chr_accept_input(CharDriverState *s)
192 6f97dba0 aliguori
{
193 6f97dba0 aliguori
    if (s->chr_accept_input)
194 6f97dba0 aliguori
        s->chr_accept_input(s);
195 98c8ee1d Jan Kiszka
    qemu_notify_event();
196 6f97dba0 aliguori
}
197 6f97dba0 aliguori
198 e7e71b0e Anthony Liguori
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
199 6f97dba0 aliguori
{
200 9bd7854e Amit Shah
    char buf[READ_BUF_LEN];
201 6f97dba0 aliguori
    va_list ap;
202 6f97dba0 aliguori
    va_start(ap, fmt);
203 6f97dba0 aliguori
    vsnprintf(buf, sizeof(buf), fmt, ap);
204 2cc6e0a1 Anthony Liguori
    qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
205 6f97dba0 aliguori
    va_end(ap);
206 6f97dba0 aliguori
}
207 6f97dba0 aliguori
208 6f97dba0 aliguori
void qemu_chr_add_handlers(CharDriverState *s,
209 7b27a769 Juan Quintela
                           IOCanReadHandler *fd_can_read,
210 6f97dba0 aliguori
                           IOReadHandler *fd_read,
211 6f97dba0 aliguori
                           IOEventHandler *fd_event,
212 6f97dba0 aliguori
                           void *opaque)
213 6f97dba0 aliguori
{
214 19083228 Hans de Goede
    int fe_open;
215 19083228 Hans de Goede
216 da7d998b Amit Shah
    if (!opaque && !fd_can_read && !fd_read && !fd_event) {
217 19083228 Hans de Goede
        fe_open = 0;
218 19083228 Hans de Goede
    } else {
219 19083228 Hans de Goede
        fe_open = 1;
220 2d6c1ef4 Amit Shah
    }
221 6f97dba0 aliguori
    s->chr_can_read = fd_can_read;
222 6f97dba0 aliguori
    s->chr_read = fd_read;
223 6f97dba0 aliguori
    s->chr_event = fd_event;
224 6f97dba0 aliguori
    s->handler_opaque = opaque;
225 6f97dba0 aliguori
    if (s->chr_update_read_handler)
226 6f97dba0 aliguori
        s->chr_update_read_handler(s);
227 73cdf3f2 Alexander Graf
228 19083228 Hans de Goede
    if (!s->explicit_fe_open) {
229 8e25daa8 Hans de Goede
        qemu_chr_fe_set_open(s, fe_open);
230 19083228 Hans de Goede
    }
231 19083228 Hans de Goede
232 73cdf3f2 Alexander Graf
    /* We're connecting to an already opened device, so let's make sure we
233 73cdf3f2 Alexander Graf
       also get the open event */
234 a59bcd31 Hans de Goede
    if (fe_open && s->be_open) {
235 fee204fd Hans de Goede
        qemu_chr_be_generic_open(s);
236 73cdf3f2 Alexander Graf
    }
237 6f97dba0 aliguori
}
238 6f97dba0 aliguori
239 6f97dba0 aliguori
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
240 6f97dba0 aliguori
{
241 6f97dba0 aliguori
    return len;
242 6f97dba0 aliguori
}
243 6f97dba0 aliguori
244 80dca9e6 Gerd Hoffmann
static CharDriverState *qemu_chr_open_null(void)
245 6f97dba0 aliguori
{
246 6f97dba0 aliguori
    CharDriverState *chr;
247 6f97dba0 aliguori
248 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
249 6f97dba0 aliguori
    chr->chr_write = null_chr_write;
250 1f51470d Markus Armbruster
    return chr;
251 6f97dba0 aliguori
}
252 6f97dba0 aliguori
253 6f97dba0 aliguori
/* MUX driver for serial I/O splitting */
254 6f97dba0 aliguori
#define MAX_MUX 4
255 6f97dba0 aliguori
#define MUX_BUFFER_SIZE 32        /* Must be a power of 2.  */
256 6f97dba0 aliguori
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
257 6f97dba0 aliguori
typedef struct {
258 7b27a769 Juan Quintela
    IOCanReadHandler *chr_can_read[MAX_MUX];
259 6f97dba0 aliguori
    IOReadHandler *chr_read[MAX_MUX];
260 6f97dba0 aliguori
    IOEventHandler *chr_event[MAX_MUX];
261 6f97dba0 aliguori
    void *ext_opaque[MAX_MUX];
262 6f97dba0 aliguori
    CharDriverState *drv;
263 799f1f23 Gerd Hoffmann
    int focus;
264 6f97dba0 aliguori
    int mux_cnt;
265 6f97dba0 aliguori
    int term_got_escape;
266 6f97dba0 aliguori
    int max_size;
267 a80bf99f aliguori
    /* Intermediate input buffer allows to catch escape sequences even if the
268 a80bf99f aliguori
       currently active device is not accepting any input - but only until it
269 a80bf99f aliguori
       is full as well. */
270 a80bf99f aliguori
    unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
271 a80bf99f aliguori
    int prod[MAX_MUX];
272 a80bf99f aliguori
    int cons[MAX_MUX];
273 2d22959d Jan Kiszka
    int timestamps;
274 4ab312f7 Jan Kiszka
    int linestart;
275 2d22959d Jan Kiszka
    int64_t timestamps_start;
276 6f97dba0 aliguori
} MuxDriver;
277 6f97dba0 aliguori
278 6f97dba0 aliguori
279 6f97dba0 aliguori
static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
280 6f97dba0 aliguori
{
281 6f97dba0 aliguori
    MuxDriver *d = chr->opaque;
282 6f97dba0 aliguori
    int ret;
283 2d22959d Jan Kiszka
    if (!d->timestamps) {
284 6f97dba0 aliguori
        ret = d->drv->chr_write(d->drv, buf, len);
285 6f97dba0 aliguori
    } else {
286 6f97dba0 aliguori
        int i;
287 6f97dba0 aliguori
288 6f97dba0 aliguori
        ret = 0;
289 4ab312f7 Jan Kiszka
        for (i = 0; i < len; i++) {
290 4ab312f7 Jan Kiszka
            if (d->linestart) {
291 6f97dba0 aliguori
                char buf1[64];
292 6f97dba0 aliguori
                int64_t ti;
293 6f97dba0 aliguori
                int secs;
294 6f97dba0 aliguori
295 7bd427d8 Paolo Bonzini
                ti = qemu_get_clock_ms(rt_clock);
296 2d22959d Jan Kiszka
                if (d->timestamps_start == -1)
297 2d22959d Jan Kiszka
                    d->timestamps_start = ti;
298 2d22959d Jan Kiszka
                ti -= d->timestamps_start;
299 a4bb1db8 aliguori
                secs = ti / 1000;
300 6f97dba0 aliguori
                snprintf(buf1, sizeof(buf1),
301 6f97dba0 aliguori
                         "[%02d:%02d:%02d.%03d] ",
302 6f97dba0 aliguori
                         secs / 3600,
303 6f97dba0 aliguori
                         (secs / 60) % 60,
304 6f97dba0 aliguori
                         secs % 60,
305 a4bb1db8 aliguori
                         (int)(ti % 1000));
306 6f97dba0 aliguori
                d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
307 4ab312f7 Jan Kiszka
                d->linestart = 0;
308 4ab312f7 Jan Kiszka
            }
309 4ab312f7 Jan Kiszka
            ret += d->drv->chr_write(d->drv, buf+i, 1);
310 4ab312f7 Jan Kiszka
            if (buf[i] == '\n') {
311 4ab312f7 Jan Kiszka
                d->linestart = 1;
312 6f97dba0 aliguori
            }
313 6f97dba0 aliguori
        }
314 6f97dba0 aliguori
    }
315 6f97dba0 aliguori
    return ret;
316 6f97dba0 aliguori
}
317 6f97dba0 aliguori
318 6f97dba0 aliguori
static const char * const mux_help[] = {
319 6f97dba0 aliguori
    "% h    print this help\n\r",
320 6f97dba0 aliguori
    "% x    exit emulator\n\r",
321 6f97dba0 aliguori
    "% s    save disk data back to file (if -snapshot)\n\r",
322 6f97dba0 aliguori
    "% t    toggle console timestamps\n\r"
323 6f97dba0 aliguori
    "% b    send break (magic sysrq)\n\r",
324 6f97dba0 aliguori
    "% c    switch between console and monitor\n\r",
325 6f97dba0 aliguori
    "% %  sends %\n\r",
326 6f97dba0 aliguori
    NULL
327 6f97dba0 aliguori
};
328 6f97dba0 aliguori
329 6f97dba0 aliguori
int term_escape_char = 0x01; /* ctrl-a is used for escape */
330 6f97dba0 aliguori
static void mux_print_help(CharDriverState *chr)
331 6f97dba0 aliguori
{
332 6f97dba0 aliguori
    int i, j;
333 6f97dba0 aliguori
    char ebuf[15] = "Escape-Char";
334 6f97dba0 aliguori
    char cbuf[50] = "\n\r";
335 6f97dba0 aliguori
336 6f97dba0 aliguori
    if (term_escape_char > 0 && term_escape_char < 26) {
337 6f97dba0 aliguori
        snprintf(cbuf, sizeof(cbuf), "\n\r");
338 6f97dba0 aliguori
        snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
339 6f97dba0 aliguori
    } else {
340 6f97dba0 aliguori
        snprintf(cbuf, sizeof(cbuf),
341 6f97dba0 aliguori
                 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
342 6f97dba0 aliguori
                 term_escape_char);
343 6f97dba0 aliguori
    }
344 6f97dba0 aliguori
    chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
345 6f97dba0 aliguori
    for (i = 0; mux_help[i] != NULL; i++) {
346 6f97dba0 aliguori
        for (j=0; mux_help[i][j] != '\0'; j++) {
347 6f97dba0 aliguori
            if (mux_help[i][j] == '%')
348 6f97dba0 aliguori
                chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
349 6f97dba0 aliguori
            else
350 6f97dba0 aliguori
                chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
351 6f97dba0 aliguori
        }
352 6f97dba0 aliguori
    }
353 6f97dba0 aliguori
}
354 6f97dba0 aliguori
355 2724b180 aliguori
static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event)
356 2724b180 aliguori
{
357 2724b180 aliguori
    if (d->chr_event[mux_nr])
358 2724b180 aliguori
        d->chr_event[mux_nr](d->ext_opaque[mux_nr], event);
359 2724b180 aliguori
}
360 2724b180 aliguori
361 6f97dba0 aliguori
static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
362 6f97dba0 aliguori
{
363 6f97dba0 aliguori
    if (d->term_got_escape) {
364 6f97dba0 aliguori
        d->term_got_escape = 0;
365 6f97dba0 aliguori
        if (ch == term_escape_char)
366 6f97dba0 aliguori
            goto send_char;
367 6f97dba0 aliguori
        switch(ch) {
368 6f97dba0 aliguori
        case '?':
369 6f97dba0 aliguori
        case 'h':
370 6f97dba0 aliguori
            mux_print_help(chr);
371 6f97dba0 aliguori
            break;
372 6f97dba0 aliguori
        case 'x':
373 6f97dba0 aliguori
            {
374 6f97dba0 aliguori
                 const char *term =  "QEMU: Terminated\n\r";
375 6f97dba0 aliguori
                 chr->chr_write(chr,(uint8_t *)term,strlen(term));
376 6f97dba0 aliguori
                 exit(0);
377 6f97dba0 aliguori
                 break;
378 6f97dba0 aliguori
            }
379 6f97dba0 aliguori
        case 's':
380 6ab4b5ab Markus Armbruster
            bdrv_commit_all();
381 6f97dba0 aliguori
            break;
382 6f97dba0 aliguori
        case 'b':
383 a425d23f Hans de Goede
            qemu_chr_be_event(chr, CHR_EVENT_BREAK);
384 6f97dba0 aliguori
            break;
385 6f97dba0 aliguori
        case 'c':
386 6f97dba0 aliguori
            /* Switch to the next registered device */
387 799f1f23 Gerd Hoffmann
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
388 799f1f23 Gerd Hoffmann
            d->focus++;
389 799f1f23 Gerd Hoffmann
            if (d->focus >= d->mux_cnt)
390 799f1f23 Gerd Hoffmann
                d->focus = 0;
391 799f1f23 Gerd Hoffmann
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
392 6f97dba0 aliguori
            break;
393 2d22959d Jan Kiszka
        case 't':
394 2d22959d Jan Kiszka
            d->timestamps = !d->timestamps;
395 2d22959d Jan Kiszka
            d->timestamps_start = -1;
396 4ab312f7 Jan Kiszka
            d->linestart = 0;
397 2d22959d Jan Kiszka
            break;
398 6f97dba0 aliguori
        }
399 6f97dba0 aliguori
    } else if (ch == term_escape_char) {
400 6f97dba0 aliguori
        d->term_got_escape = 1;
401 6f97dba0 aliguori
    } else {
402 6f97dba0 aliguori
    send_char:
403 6f97dba0 aliguori
        return 1;
404 6f97dba0 aliguori
    }
405 6f97dba0 aliguori
    return 0;
406 6f97dba0 aliguori
}
407 6f97dba0 aliguori
408 6f97dba0 aliguori
static void mux_chr_accept_input(CharDriverState *chr)
409 6f97dba0 aliguori
{
410 6f97dba0 aliguori
    MuxDriver *d = chr->opaque;
411 799f1f23 Gerd Hoffmann
    int m = d->focus;
412 6f97dba0 aliguori
413 a80bf99f aliguori
    while (d->prod[m] != d->cons[m] &&
414 6f97dba0 aliguori
           d->chr_can_read[m] &&
415 6f97dba0 aliguori
           d->chr_can_read[m](d->ext_opaque[m])) {
416 6f97dba0 aliguori
        d->chr_read[m](d->ext_opaque[m],
417 a80bf99f aliguori
                       &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
418 6f97dba0 aliguori
    }
419 6f97dba0 aliguori
}
420 6f97dba0 aliguori
421 6f97dba0 aliguori
static int mux_chr_can_read(void *opaque)
422 6f97dba0 aliguori
{
423 6f97dba0 aliguori
    CharDriverState *chr = opaque;
424 6f97dba0 aliguori
    MuxDriver *d = chr->opaque;
425 799f1f23 Gerd Hoffmann
    int m = d->focus;
426 6f97dba0 aliguori
427 a80bf99f aliguori
    if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
428 6f97dba0 aliguori
        return 1;
429 a80bf99f aliguori
    if (d->chr_can_read[m])
430 a80bf99f aliguori
        return d->chr_can_read[m](d->ext_opaque[m]);
431 6f97dba0 aliguori
    return 0;
432 6f97dba0 aliguori
}
433 6f97dba0 aliguori
434 6f97dba0 aliguori
static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
435 6f97dba0 aliguori
{
436 6f97dba0 aliguori
    CharDriverState *chr = opaque;
437 6f97dba0 aliguori
    MuxDriver *d = chr->opaque;
438 799f1f23 Gerd Hoffmann
    int m = d->focus;
439 6f97dba0 aliguori
    int i;
440 6f97dba0 aliguori
441 6f97dba0 aliguori
    mux_chr_accept_input (opaque);
442 6f97dba0 aliguori
443 6f97dba0 aliguori
    for(i = 0; i < size; i++)
444 6f97dba0 aliguori
        if (mux_proc_byte(chr, d, buf[i])) {
445 a80bf99f aliguori
            if (d->prod[m] == d->cons[m] &&
446 6f97dba0 aliguori
                d->chr_can_read[m] &&
447 6f97dba0 aliguori
                d->chr_can_read[m](d->ext_opaque[m]))
448 6f97dba0 aliguori
                d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
449 6f97dba0 aliguori
            else
450 a80bf99f aliguori
                d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
451 6f97dba0 aliguori
        }
452 6f97dba0 aliguori
}
453 6f97dba0 aliguori
454 6f97dba0 aliguori
static void mux_chr_event(void *opaque, int event)
455 6f97dba0 aliguori
{
456 6f97dba0 aliguori
    CharDriverState *chr = opaque;
457 6f97dba0 aliguori
    MuxDriver *d = chr->opaque;
458 6f97dba0 aliguori
    int i;
459 6f97dba0 aliguori
460 6f97dba0 aliguori
    /* Send the event to all registered listeners */
461 6f97dba0 aliguori
    for (i = 0; i < d->mux_cnt; i++)
462 2724b180 aliguori
        mux_chr_send_event(d, i, event);
463 6f97dba0 aliguori
}
464 6f97dba0 aliguori
465 6f97dba0 aliguori
static void mux_chr_update_read_handler(CharDriverState *chr)
466 6f97dba0 aliguori
{
467 6f97dba0 aliguori
    MuxDriver *d = chr->opaque;
468 6f97dba0 aliguori
469 6f97dba0 aliguori
    if (d->mux_cnt >= MAX_MUX) {
470 6f97dba0 aliguori
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
471 6f97dba0 aliguori
        return;
472 6f97dba0 aliguori
    }
473 6f97dba0 aliguori
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
474 6f97dba0 aliguori
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
475 6f97dba0 aliguori
    d->chr_read[d->mux_cnt] = chr->chr_read;
476 6f97dba0 aliguori
    d->chr_event[d->mux_cnt] = chr->chr_event;
477 6f97dba0 aliguori
    /* Fix up the real driver with mux routines */
478 6f97dba0 aliguori
    if (d->mux_cnt == 0) {
479 6f97dba0 aliguori
        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
480 6f97dba0 aliguori
                              mux_chr_event, chr);
481 6f97dba0 aliguori
    }
482 799f1f23 Gerd Hoffmann
    if (d->focus != -1) {
483 799f1f23 Gerd Hoffmann
        mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
484 a7aec5da Gerd Hoffmann
    }
485 799f1f23 Gerd Hoffmann
    d->focus = d->mux_cnt;
486 6f97dba0 aliguori
    d->mux_cnt++;
487 799f1f23 Gerd Hoffmann
    mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
488 6f97dba0 aliguori
}
489 6f97dba0 aliguori
490 6f97dba0 aliguori
static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
491 6f97dba0 aliguori
{
492 6f97dba0 aliguori
    CharDriverState *chr;
493 6f97dba0 aliguori
    MuxDriver *d;
494 6f97dba0 aliguori
495 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
496 7267c094 Anthony Liguori
    d = g_malloc0(sizeof(MuxDriver));
497 6f97dba0 aliguori
498 6f97dba0 aliguori
    chr->opaque = d;
499 6f97dba0 aliguori
    d->drv = drv;
500 799f1f23 Gerd Hoffmann
    d->focus = -1;
501 6f97dba0 aliguori
    chr->chr_write = mux_chr_write;
502 6f97dba0 aliguori
    chr->chr_update_read_handler = mux_chr_update_read_handler;
503 6f97dba0 aliguori
    chr->chr_accept_input = mux_chr_accept_input;
504 7c32c4fe Hans de Goede
    /* Frontend guest-open / -close notification is not support with muxes */
505 574b711a Hans de Goede
    chr->chr_set_fe_open = NULL;
506 73cdf3f2 Alexander Graf
507 73cdf3f2 Alexander Graf
    /* Muxes are always open on creation */
508 fee204fd Hans de Goede
    qemu_chr_be_generic_open(chr);
509 73cdf3f2 Alexander Graf
510 6f97dba0 aliguori
    return chr;
511 6f97dba0 aliguori
}
512 6f97dba0 aliguori
513 6f97dba0 aliguori
514 6f97dba0 aliguori
#ifdef _WIN32
515 d247d25f aliguori
int send_all(int fd, const void *buf, int len1)
516 6f97dba0 aliguori
{
517 6f97dba0 aliguori
    int ret, len;
518 6f97dba0 aliguori
519 6f97dba0 aliguori
    len = len1;
520 6f97dba0 aliguori
    while (len > 0) {
521 6f97dba0 aliguori
        ret = send(fd, buf, len, 0);
522 6f97dba0 aliguori
        if (ret < 0) {
523 6f97dba0 aliguori
            errno = WSAGetLastError();
524 6f97dba0 aliguori
            if (errno != WSAEWOULDBLOCK) {
525 6f97dba0 aliguori
                return -1;
526 6f97dba0 aliguori
            }
527 6f97dba0 aliguori
        } else if (ret == 0) {
528 6f97dba0 aliguori
            break;
529 6f97dba0 aliguori
        } else {
530 6f97dba0 aliguori
            buf += ret;
531 6f97dba0 aliguori
            len -= ret;
532 6f97dba0 aliguori
        }
533 6f97dba0 aliguori
    }
534 6f97dba0 aliguori
    return len1 - len;
535 6f97dba0 aliguori
}
536 6f97dba0 aliguori
537 6f97dba0 aliguori
#else
538 6f97dba0 aliguori
539 5fc9cfed Jes Sorensen
int send_all(int fd, const void *_buf, int len1)
540 6f97dba0 aliguori
{
541 6f97dba0 aliguori
    int ret, len;
542 5fc9cfed Jes Sorensen
    const uint8_t *buf = _buf;
543 6f97dba0 aliguori
544 6f97dba0 aliguori
    len = len1;
545 6f97dba0 aliguori
    while (len > 0) {
546 6f97dba0 aliguori
        ret = write(fd, buf, len);
547 6f97dba0 aliguori
        if (ret < 0) {
548 6f97dba0 aliguori
            if (errno != EINTR && errno != EAGAIN)
549 6f97dba0 aliguori
                return -1;
550 6f97dba0 aliguori
        } else if (ret == 0) {
551 6f97dba0 aliguori
            break;
552 6f97dba0 aliguori
        } else {
553 6f97dba0 aliguori
            buf += ret;
554 6f97dba0 aliguori
            len -= ret;
555 6f97dba0 aliguori
        }
556 6f97dba0 aliguori
    }
557 6f97dba0 aliguori
    return len1 - len;
558 6f97dba0 aliguori
}
559 4549a8b7 Stefan Berger
560 4549a8b7 Stefan Berger
int recv_all(int fd, void *_buf, int len1, bool single_read)
561 4549a8b7 Stefan Berger
{
562 4549a8b7 Stefan Berger
    int ret, len;
563 4549a8b7 Stefan Berger
    uint8_t *buf = _buf;
564 4549a8b7 Stefan Berger
565 4549a8b7 Stefan Berger
    len = len1;
566 4549a8b7 Stefan Berger
    while ((len > 0) && (ret = read(fd, buf, len)) != 0) {
567 4549a8b7 Stefan Berger
        if (ret < 0) {
568 4549a8b7 Stefan Berger
            if (errno != EINTR && errno != EAGAIN) {
569 4549a8b7 Stefan Berger
                return -1;
570 4549a8b7 Stefan Berger
            }
571 4549a8b7 Stefan Berger
            continue;
572 4549a8b7 Stefan Berger
        } else {
573 4549a8b7 Stefan Berger
            if (single_read) {
574 4549a8b7 Stefan Berger
                return ret;
575 4549a8b7 Stefan Berger
            }
576 4549a8b7 Stefan Berger
            buf += ret;
577 4549a8b7 Stefan Berger
            len -= ret;
578 4549a8b7 Stefan Berger
        }
579 4549a8b7 Stefan Berger
    }
580 4549a8b7 Stefan Berger
    return len1 - len;
581 4549a8b7 Stefan Berger
}
582 4549a8b7 Stefan Berger
583 6f97dba0 aliguori
#endif /* !_WIN32 */
584 6f97dba0 aliguori
585 96c63847 Anthony Liguori
typedef struct IOWatchPoll
586 96c63847 Anthony Liguori
{
587 d185c094 Paolo Bonzini
    GSource parent;
588 d185c094 Paolo Bonzini
589 1e885b25 Paolo Bonzini
    GIOChannel *channel;
590 96c63847 Anthony Liguori
    GSource *src;
591 96c63847 Anthony Liguori
592 96c63847 Anthony Liguori
    IOCanReadHandler *fd_can_read;
593 1e885b25 Paolo Bonzini
    GSourceFunc fd_read;
594 96c63847 Anthony Liguori
    void *opaque;
595 96c63847 Anthony Liguori
} IOWatchPoll;
596 96c63847 Anthony Liguori
597 96c63847 Anthony Liguori
static IOWatchPoll *io_watch_poll_from_source(GSource *source)
598 96c63847 Anthony Liguori
{
599 d185c094 Paolo Bonzini
    return container_of(source, IOWatchPoll, parent);
600 96c63847 Anthony Liguori
}
601 96c63847 Anthony Liguori
602 96c63847 Anthony Liguori
static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
603 96c63847 Anthony Liguori
{
604 96c63847 Anthony Liguori
    IOWatchPoll *iwp = io_watch_poll_from_source(source);
605 d185c094 Paolo Bonzini
    bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
606 1e885b25 Paolo Bonzini
    bool was_active = iwp->src != NULL;
607 d185c094 Paolo Bonzini
    if (was_active == now_active) {
608 96c63847 Anthony Liguori
        return FALSE;
609 96c63847 Anthony Liguori
    }
610 96c63847 Anthony Liguori
611 d185c094 Paolo Bonzini
    if (now_active) {
612 1e885b25 Paolo Bonzini
        iwp->src = g_io_create_watch(iwp->channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
613 1e885b25 Paolo Bonzini
        g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
614 d185c094 Paolo Bonzini
        g_source_attach(iwp->src, NULL);
615 d185c094 Paolo Bonzini
    } else {
616 1e885b25 Paolo Bonzini
        g_source_destroy(iwp->src);
617 1e885b25 Paolo Bonzini
        g_source_unref(iwp->src);
618 1e885b25 Paolo Bonzini
        iwp->src = NULL;
619 d185c094 Paolo Bonzini
    }
620 d185c094 Paolo Bonzini
    return FALSE;
621 96c63847 Anthony Liguori
}
622 96c63847 Anthony Liguori
623 96c63847 Anthony Liguori
static gboolean io_watch_poll_check(GSource *source)
624 96c63847 Anthony Liguori
{
625 d185c094 Paolo Bonzini
    return FALSE;
626 96c63847 Anthony Liguori
}
627 96c63847 Anthony Liguori
628 96c63847 Anthony Liguori
static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
629 96c63847 Anthony Liguori
                                       gpointer user_data)
630 96c63847 Anthony Liguori
{
631 d185c094 Paolo Bonzini
    abort();
632 96c63847 Anthony Liguori
}
633 96c63847 Anthony Liguori
634 96c63847 Anthony Liguori
static void io_watch_poll_finalize(GSource *source)
635 96c63847 Anthony Liguori
{
636 2b316774 Paolo Bonzini
    /* Due to a glib bug, removing the last reference to a source
637 2b316774 Paolo Bonzini
     * inside a finalize callback causes recursive locking (and a
638 2b316774 Paolo Bonzini
     * deadlock).  This is not a problem inside other callbacks,
639 2b316774 Paolo Bonzini
     * including dispatch callbacks, so we call io_remove_watch_poll
640 2b316774 Paolo Bonzini
     * to remove this source.  At this point, iwp->src must
641 2b316774 Paolo Bonzini
     * be NULL, or we would leak it.
642 2b316774 Paolo Bonzini
     *
643 2b316774 Paolo Bonzini
     * This would be solved much more elegantly by child sources,
644 2b316774 Paolo Bonzini
     * but we support older glib versions that do not have them.
645 2b316774 Paolo Bonzini
     */
646 96c63847 Anthony Liguori
    IOWatchPoll *iwp = io_watch_poll_from_source(source);
647 2b316774 Paolo Bonzini
    assert(iwp->src == NULL);
648 96c63847 Anthony Liguori
}
649 96c63847 Anthony Liguori
650 96c63847 Anthony Liguori
static GSourceFuncs io_watch_poll_funcs = {
651 96c63847 Anthony Liguori
    .prepare = io_watch_poll_prepare,
652 96c63847 Anthony Liguori
    .check = io_watch_poll_check,
653 96c63847 Anthony Liguori
    .dispatch = io_watch_poll_dispatch,
654 96c63847 Anthony Liguori
    .finalize = io_watch_poll_finalize,
655 96c63847 Anthony Liguori
};
656 96c63847 Anthony Liguori
657 96c63847 Anthony Liguori
/* Can only be used for read */
658 96c63847 Anthony Liguori
static guint io_add_watch_poll(GIOChannel *channel,
659 96c63847 Anthony Liguori
                               IOCanReadHandler *fd_can_read,
660 96c63847 Anthony Liguori
                               GIOFunc fd_read,
661 96c63847 Anthony Liguori
                               gpointer user_data)
662 96c63847 Anthony Liguori
{
663 96c63847 Anthony Liguori
    IOWatchPoll *iwp;
664 0ca5aa4f Paolo Bonzini
    int tag;
665 96c63847 Anthony Liguori
666 d185c094 Paolo Bonzini
    iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs, sizeof(IOWatchPoll));
667 96c63847 Anthony Liguori
    iwp->fd_can_read = fd_can_read;
668 96c63847 Anthony Liguori
    iwp->opaque = user_data;
669 1e885b25 Paolo Bonzini
    iwp->channel = channel;
670 1e885b25 Paolo Bonzini
    iwp->fd_read = (GSourceFunc) fd_read;
671 1e885b25 Paolo Bonzini
    iwp->src = NULL;
672 96c63847 Anthony Liguori
673 0ca5aa4f Paolo Bonzini
    tag = g_source_attach(&iwp->parent, NULL);
674 0ca5aa4f Paolo Bonzini
    g_source_unref(&iwp->parent);
675 0ca5aa4f Paolo Bonzini
    return tag;
676 96c63847 Anthony Liguori
}
677 96c63847 Anthony Liguori
678 2b316774 Paolo Bonzini
static void io_remove_watch_poll(guint tag)
679 2b316774 Paolo Bonzini
{
680 2b316774 Paolo Bonzini
    GSource *source;
681 2b316774 Paolo Bonzini
    IOWatchPoll *iwp;
682 2b316774 Paolo Bonzini
683 2b316774 Paolo Bonzini
    g_return_if_fail (tag > 0);
684 2b316774 Paolo Bonzini
685 2b316774 Paolo Bonzini
    source = g_main_context_find_source_by_id(NULL, tag);
686 2b316774 Paolo Bonzini
    g_return_if_fail (source != NULL);
687 2b316774 Paolo Bonzini
688 2b316774 Paolo Bonzini
    iwp = io_watch_poll_from_source(source);
689 2b316774 Paolo Bonzini
    if (iwp->src) {
690 2b316774 Paolo Bonzini
        g_source_destroy(iwp->src);
691 2b316774 Paolo Bonzini
        g_source_unref(iwp->src);
692 2b316774 Paolo Bonzini
        iwp->src = NULL;
693 2b316774 Paolo Bonzini
    }
694 2b316774 Paolo Bonzini
    g_source_destroy(&iwp->parent);
695 2b316774 Paolo Bonzini
}
696 2b316774 Paolo Bonzini
697 44ab9ed4 Blue Swirl
#ifndef _WIN32
698 96c63847 Anthony Liguori
static GIOChannel *io_channel_from_fd(int fd)
699 96c63847 Anthony Liguori
{
700 96c63847 Anthony Liguori
    GIOChannel *chan;
701 96c63847 Anthony Liguori
702 96c63847 Anthony Liguori
    if (fd == -1) {
703 96c63847 Anthony Liguori
        return NULL;
704 96c63847 Anthony Liguori
    }
705 96c63847 Anthony Liguori
706 96c63847 Anthony Liguori
    chan = g_io_channel_unix_new(fd);
707 96c63847 Anthony Liguori
708 96c63847 Anthony Liguori
    g_io_channel_set_encoding(chan, NULL, NULL);
709 96c63847 Anthony Liguori
    g_io_channel_set_buffered(chan, FALSE);
710 96c63847 Anthony Liguori
711 96c63847 Anthony Liguori
    return chan;
712 96c63847 Anthony Liguori
}
713 44ab9ed4 Blue Swirl
#endif
714 96c63847 Anthony Liguori
715 76a9644b Anthony Liguori
static GIOChannel *io_channel_from_socket(int fd)
716 76a9644b Anthony Liguori
{
717 76a9644b Anthony Liguori
    GIOChannel *chan;
718 76a9644b Anthony Liguori
719 76a9644b Anthony Liguori
    if (fd == -1) {
720 76a9644b Anthony Liguori
        return NULL;
721 76a9644b Anthony Liguori
    }
722 76a9644b Anthony Liguori
723 76a9644b Anthony Liguori
#ifdef _WIN32
724 76a9644b Anthony Liguori
    chan = g_io_channel_win32_new_socket(fd);
725 76a9644b Anthony Liguori
#else
726 76a9644b Anthony Liguori
    chan = g_io_channel_unix_new(fd);
727 76a9644b Anthony Liguori
#endif
728 76a9644b Anthony Liguori
729 76a9644b Anthony Liguori
    g_io_channel_set_encoding(chan, NULL, NULL);
730 76a9644b Anthony Liguori
    g_io_channel_set_buffered(chan, FALSE);
731 76a9644b Anthony Liguori
732 76a9644b Anthony Liguori
    return chan;
733 76a9644b Anthony Liguori
}
734 76a9644b Anthony Liguori
735 684a096e Anthony Liguori
static int io_channel_send(GIOChannel *fd, const void *buf, size_t len)
736 96c63847 Anthony Liguori
{
737 96c63847 Anthony Liguori
    GIOStatus status;
738 684a096e Anthony Liguori
    size_t offset;
739 96c63847 Anthony Liguori
740 684a096e Anthony Liguori
    offset = 0;
741 684a096e Anthony Liguori
    while (offset < len) {
742 684a096e Anthony Liguori
        gsize bytes_written;
743 684a096e Anthony Liguori
744 684a096e Anthony Liguori
        status = g_io_channel_write_chars(fd, buf + offset, len - offset,
745 96c63847 Anthony Liguori
                                          &bytes_written, NULL);
746 96c63847 Anthony Liguori
        if (status != G_IO_STATUS_NORMAL) {
747 23673ca7 Anthony Liguori
            if (status == G_IO_STATUS_AGAIN) {
748 684a096e Anthony Liguori
                /* If we've written any data, return a partial write. */
749 684a096e Anthony Liguori
                if (offset) {
750 684a096e Anthony Liguori
                    break;
751 684a096e Anthony Liguori
                }
752 23673ca7 Anthony Liguori
                errno = EAGAIN;
753 23673ca7 Anthony Liguori
            } else {
754 23673ca7 Anthony Liguori
                errno = EINVAL;
755 96c63847 Anthony Liguori
            }
756 684a096e Anthony Liguori
757 684a096e Anthony Liguori
            return -1;
758 96c63847 Anthony Liguori
        } else if (status == G_IO_STATUS_EOF) {
759 96c63847 Anthony Liguori
            break;
760 96c63847 Anthony Liguori
        }
761 684a096e Anthony Liguori
762 684a096e Anthony Liguori
        offset += bytes_written;
763 96c63847 Anthony Liguori
    }
764 684a096e Anthony Liguori
765 684a096e Anthony Liguori
    return offset;
766 96c63847 Anthony Liguori
}
767 96c63847 Anthony Liguori
768 44ab9ed4 Blue Swirl
#ifndef _WIN32
769 44ab9ed4 Blue Swirl
770 a29753f8 Anthony Liguori
typedef struct FDCharDriver {
771 a29753f8 Anthony Liguori
    CharDriverState *chr;
772 a29753f8 Anthony Liguori
    GIOChannel *fd_in, *fd_out;
773 a29753f8 Anthony Liguori
    guint fd_in_tag;
774 6f97dba0 aliguori
    int max_size;
775 a29753f8 Anthony Liguori
    QTAILQ_ENTRY(FDCharDriver) node;
776 6f97dba0 aliguori
} FDCharDriver;
777 6f97dba0 aliguori
778 6f97dba0 aliguori
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
779 6f97dba0 aliguori
{
780 6f97dba0 aliguori
    FDCharDriver *s = chr->opaque;
781 a29753f8 Anthony Liguori
    
782 684a096e Anthony Liguori
    return io_channel_send(s->fd_out, buf, len);
783 6f97dba0 aliguori
}
784 6f97dba0 aliguori
785 a29753f8 Anthony Liguori
static gboolean fd_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
786 6f97dba0 aliguori
{
787 6f97dba0 aliguori
    CharDriverState *chr = opaque;
788 6f97dba0 aliguori
    FDCharDriver *s = chr->opaque;
789 a29753f8 Anthony Liguori
    int len;
790 9bd7854e Amit Shah
    uint8_t buf[READ_BUF_LEN];
791 a29753f8 Anthony Liguori
    GIOStatus status;
792 a29753f8 Anthony Liguori
    gsize bytes_read;
793 6f97dba0 aliguori
794 6f97dba0 aliguori
    len = sizeof(buf);
795 a29753f8 Anthony Liguori
    if (len > s->max_size) {
796 6f97dba0 aliguori
        len = s->max_size;
797 a29753f8 Anthony Liguori
    }
798 a29753f8 Anthony Liguori
    if (len == 0) {
799 cdbf6e16 Paolo Bonzini
        return TRUE;
800 a29753f8 Anthony Liguori
    }
801 a29753f8 Anthony Liguori
802 a29753f8 Anthony Liguori
    status = g_io_channel_read_chars(chan, (gchar *)buf,
803 a29753f8 Anthony Liguori
                                     len, &bytes_read, NULL);
804 a29753f8 Anthony Liguori
    if (status == G_IO_STATUS_EOF) {
805 cdbf6e16 Paolo Bonzini
        if (s->fd_in_tag) {
806 2b316774 Paolo Bonzini
            io_remove_watch_poll(s->fd_in_tag);
807 cdbf6e16 Paolo Bonzini
            s->fd_in_tag = 0;
808 cdbf6e16 Paolo Bonzini
        }
809 a425d23f Hans de Goede
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
810 a29753f8 Anthony Liguori
        return FALSE;
811 6f97dba0 aliguori
    }
812 a29753f8 Anthony Liguori
    if (status == G_IO_STATUS_NORMAL) {
813 a29753f8 Anthony Liguori
        qemu_chr_be_write(chr, buf, bytes_read);
814 6f97dba0 aliguori
    }
815 a29753f8 Anthony Liguori
816 a29753f8 Anthony Liguori
    return TRUE;
817 a29753f8 Anthony Liguori
}
818 a29753f8 Anthony Liguori
819 a29753f8 Anthony Liguori
static int fd_chr_read_poll(void *opaque)
820 a29753f8 Anthony Liguori
{
821 a29753f8 Anthony Liguori
    CharDriverState *chr = opaque;
822 a29753f8 Anthony Liguori
    FDCharDriver *s = chr->opaque;
823 a29753f8 Anthony Liguori
824 a29753f8 Anthony Liguori
    s->max_size = qemu_chr_be_can_write(chr);
825 a29753f8 Anthony Liguori
    return s->max_size;
826 6f97dba0 aliguori
}
827 6f97dba0 aliguori
828 23673ca7 Anthony Liguori
static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
829 23673ca7 Anthony Liguori
{
830 23673ca7 Anthony Liguori
    FDCharDriver *s = chr->opaque;
831 23673ca7 Anthony Liguori
    return g_io_create_watch(s->fd_out, cond);
832 23673ca7 Anthony Liguori
}
833 23673ca7 Anthony Liguori
834 6f97dba0 aliguori
static void fd_chr_update_read_handler(CharDriverState *chr)
835 6f97dba0 aliguori
{
836 6f97dba0 aliguori
    FDCharDriver *s = chr->opaque;
837 6f97dba0 aliguori
838 a29753f8 Anthony Liguori
    if (s->fd_in_tag) {
839 2b316774 Paolo Bonzini
        io_remove_watch_poll(s->fd_in_tag);
840 910b6368 Paolo Bonzini
        s->fd_in_tag = 0;
841 a29753f8 Anthony Liguori
    }
842 a29753f8 Anthony Liguori
843 a29753f8 Anthony Liguori
    if (s->fd_in) {
844 a29753f8 Anthony Liguori
        s->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll, fd_chr_read, chr);
845 6f97dba0 aliguori
    }
846 6f97dba0 aliguori
}
847 6f97dba0 aliguori
848 6f97dba0 aliguori
static void fd_chr_close(struct CharDriverState *chr)
849 6f97dba0 aliguori
{
850 6f97dba0 aliguori
    FDCharDriver *s = chr->opaque;
851 6f97dba0 aliguori
852 a29753f8 Anthony Liguori
    if (s->fd_in_tag) {
853 2b316774 Paolo Bonzini
        io_remove_watch_poll(s->fd_in_tag);
854 a29753f8 Anthony Liguori
        s->fd_in_tag = 0;
855 a29753f8 Anthony Liguori
    }
856 a29753f8 Anthony Liguori
857 a29753f8 Anthony Liguori
    if (s->fd_in) {
858 a29753f8 Anthony Liguori
        g_io_channel_unref(s->fd_in);
859 a29753f8 Anthony Liguori
    }
860 a29753f8 Anthony Liguori
    if (s->fd_out) {
861 a29753f8 Anthony Liguori
        g_io_channel_unref(s->fd_out);
862 6f97dba0 aliguori
    }
863 6f97dba0 aliguori
864 7267c094 Anthony Liguori
    g_free(s);
865 a425d23f Hans de Goede
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
866 6f97dba0 aliguori
}
867 6f97dba0 aliguori
868 6f97dba0 aliguori
/* open a character device to a unix fd */
869 6f97dba0 aliguori
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
870 6f97dba0 aliguori
{
871 6f97dba0 aliguori
    CharDriverState *chr;
872 6f97dba0 aliguori
    FDCharDriver *s;
873 6f97dba0 aliguori
874 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
875 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(FDCharDriver));
876 a29753f8 Anthony Liguori
    s->fd_in = io_channel_from_fd(fd_in);
877 a29753f8 Anthony Liguori
    s->fd_out = io_channel_from_fd(fd_out);
878 23673ca7 Anthony Liguori
    fcntl(fd_out, F_SETFL, O_NONBLOCK);
879 a29753f8 Anthony Liguori
    s->chr = chr;
880 6f97dba0 aliguori
    chr->opaque = s;
881 23673ca7 Anthony Liguori
    chr->chr_add_watch = fd_chr_add_watch;
882 6f97dba0 aliguori
    chr->chr_write = fd_chr_write;
883 6f97dba0 aliguori
    chr->chr_update_read_handler = fd_chr_update_read_handler;
884 6f97dba0 aliguori
    chr->chr_close = fd_chr_close;
885 6f97dba0 aliguori
886 fee204fd Hans de Goede
    qemu_chr_be_generic_open(chr);
887 6f97dba0 aliguori
888 6f97dba0 aliguori
    return chr;
889 6f97dba0 aliguori
}
890 6f97dba0 aliguori
891 548cbb36 Gerd Hoffmann
static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
892 6f97dba0 aliguori
{
893 6f97dba0 aliguori
    int fd_in, fd_out;
894 6f97dba0 aliguori
    char filename_in[256], filename_out[256];
895 548cbb36 Gerd Hoffmann
    const char *filename = opts->device;
896 7d31544f Gerd Hoffmann
897 7d31544f Gerd Hoffmann
    if (filename == NULL) {
898 7d31544f Gerd Hoffmann
        fprintf(stderr, "chardev: pipe: no filename given\n");
899 1f51470d Markus Armbruster
        return NULL;
900 7d31544f Gerd Hoffmann
    }
901 6f97dba0 aliguori
902 6f97dba0 aliguori
    snprintf(filename_in, 256, "%s.in", filename);
903 6f97dba0 aliguori
    snprintf(filename_out, 256, "%s.out", filename);
904 40ff6d7e Kevin Wolf
    TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
905 40ff6d7e Kevin Wolf
    TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
906 6f97dba0 aliguori
    if (fd_in < 0 || fd_out < 0) {
907 6f97dba0 aliguori
        if (fd_in >= 0)
908 6f97dba0 aliguori
            close(fd_in);
909 6f97dba0 aliguori
        if (fd_out >= 0)
910 6f97dba0 aliguori
            close(fd_out);
911 b181e047 Markus Armbruster
        TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
912 a89dd6c3 Markus Armbruster
        if (fd_in < 0) {
913 1f51470d Markus Armbruster
            return NULL;
914 a89dd6c3 Markus Armbruster
        }
915 6f97dba0 aliguori
    }
916 1f51470d Markus Armbruster
    return qemu_chr_open_fd(fd_in, fd_out);
917 6f97dba0 aliguori
}
918 6f97dba0 aliguori
919 6f97dba0 aliguori
/* init terminal so that we can grab keys */
920 6f97dba0 aliguori
static struct termios oldtty;
921 6f97dba0 aliguori
static int old_fd0_flags;
922 bb002513 Paolo Bonzini
static bool stdio_allow_signal;
923 6f97dba0 aliguori
924 6f97dba0 aliguori
static void term_exit(void)
925 6f97dba0 aliguori
{
926 6f97dba0 aliguori
    tcsetattr (0, TCSANOW, &oldtty);
927 6f97dba0 aliguori
    fcntl(0, F_SETFL, old_fd0_flags);
928 6f97dba0 aliguori
}
929 6f97dba0 aliguori
930 bb002513 Paolo Bonzini
static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
931 6f97dba0 aliguori
{
932 6f97dba0 aliguori
    struct termios tty;
933 6f97dba0 aliguori
934 0369364b Paolo Bonzini
    tty = oldtty;
935 bb002513 Paolo Bonzini
    if (!echo) {
936 bb002513 Paolo Bonzini
        tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
937 6f97dba0 aliguori
                          |INLCR|IGNCR|ICRNL|IXON);
938 bb002513 Paolo Bonzini
        tty.c_oflag |= OPOST;
939 bb002513 Paolo Bonzini
        tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
940 bb002513 Paolo Bonzini
        tty.c_cflag &= ~(CSIZE|PARENB);
941 bb002513 Paolo Bonzini
        tty.c_cflag |= CS8;
942 bb002513 Paolo Bonzini
        tty.c_cc[VMIN] = 1;
943 bb002513 Paolo Bonzini
        tty.c_cc[VTIME] = 0;
944 bb002513 Paolo Bonzini
    }
945 6f97dba0 aliguori
    /* if graphical mode, we allow Ctrl-C handling */
946 bb002513 Paolo Bonzini
    if (!stdio_allow_signal)
947 6f97dba0 aliguori
        tty.c_lflag &= ~ISIG;
948 6f97dba0 aliguori
949 6f97dba0 aliguori
    tcsetattr (0, TCSANOW, &tty);
950 6f97dba0 aliguori
}
951 6f97dba0 aliguori
952 6f97dba0 aliguori
static void qemu_chr_close_stdio(struct CharDriverState *chr)
953 6f97dba0 aliguori
{
954 6f97dba0 aliguori
    term_exit();
955 6f97dba0 aliguori
    fd_chr_close(chr);
956 6f97dba0 aliguori
}
957 6f97dba0 aliguori
958 7c358031 Gerd Hoffmann
static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
959 6f97dba0 aliguori
{
960 6f97dba0 aliguori
    CharDriverState *chr;
961 6f97dba0 aliguori
962 ab51b1d5 Michael Tokarev
    if (is_daemonized()) {
963 ab51b1d5 Michael Tokarev
        error_report("cannot use stdio with -daemonize");
964 ab51b1d5 Michael Tokarev
        return NULL;
965 ab51b1d5 Michael Tokarev
    }
966 ed7a1540 Anthony Liguori
    old_fd0_flags = fcntl(0, F_GETFL);
967 ed7a1540 Anthony Liguori
    tcgetattr (0, &oldtty);
968 ed7a1540 Anthony Liguori
    fcntl(0, F_SETFL, O_NONBLOCK);
969 ed7a1540 Anthony Liguori
    atexit(term_exit);
970 0369364b Paolo Bonzini
971 6f97dba0 aliguori
    chr = qemu_chr_open_fd(0, 1);
972 6f97dba0 aliguori
    chr->chr_close = qemu_chr_close_stdio;
973 bb002513 Paolo Bonzini
    chr->chr_set_echo = qemu_chr_set_echo_stdio;
974 7c358031 Gerd Hoffmann
    stdio_allow_signal = display_type != DT_NOGRAPHIC;
975 7c358031 Gerd Hoffmann
    if (opts->has_signal) {
976 7c358031 Gerd Hoffmann
        stdio_allow_signal = opts->signal;
977 7c358031 Gerd Hoffmann
    }
978 15f31519 Anthony Liguori
    qemu_chr_fe_set_echo(chr, false);
979 6f97dba0 aliguori
980 1f51470d Markus Armbruster
    return chr;
981 6f97dba0 aliguori
}
982 6f97dba0 aliguori
983 6f97dba0 aliguori
#ifdef __sun__
984 6f97dba0 aliguori
/* Once Solaris has openpty(), this is going to be removed. */
985 3f4cb3d3 blueswir1
static int openpty(int *amaster, int *aslave, char *name,
986 3f4cb3d3 blueswir1
                   struct termios *termp, struct winsize *winp)
987 6f97dba0 aliguori
{
988 6f97dba0 aliguori
        const char *slave;
989 6f97dba0 aliguori
        int mfd = -1, sfd = -1;
990 6f97dba0 aliguori
991 6f97dba0 aliguori
        *amaster = *aslave = -1;
992 6f97dba0 aliguori
993 6f97dba0 aliguori
        mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
994 6f97dba0 aliguori
        if (mfd < 0)
995 6f97dba0 aliguori
                goto err;
996 6f97dba0 aliguori
997 6f97dba0 aliguori
        if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
998 6f97dba0 aliguori
                goto err;
999 6f97dba0 aliguori
1000 6f97dba0 aliguori
        if ((slave = ptsname(mfd)) == NULL)
1001 6f97dba0 aliguori
                goto err;
1002 6f97dba0 aliguori
1003 6f97dba0 aliguori
        if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
1004 6f97dba0 aliguori
                goto err;
1005 6f97dba0 aliguori
1006 6f97dba0 aliguori
        if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
1007 6f97dba0 aliguori
            (termp != NULL && tcgetattr(sfd, termp) < 0))
1008 6f97dba0 aliguori
                goto err;
1009 6f97dba0 aliguori
1010 6f97dba0 aliguori
        if (amaster)
1011 6f97dba0 aliguori
                *amaster = mfd;
1012 6f97dba0 aliguori
        if (aslave)
1013 6f97dba0 aliguori
                *aslave = sfd;
1014 6f97dba0 aliguori
        if (winp)
1015 6f97dba0 aliguori
                ioctl(sfd, TIOCSWINSZ, winp);
1016 6f97dba0 aliguori
1017 6f97dba0 aliguori
        return 0;
1018 6f97dba0 aliguori
1019 6f97dba0 aliguori
err:
1020 6f97dba0 aliguori
        if (sfd != -1)
1021 6f97dba0 aliguori
                close(sfd);
1022 6f97dba0 aliguori
        close(mfd);
1023 6f97dba0 aliguori
        return -1;
1024 6f97dba0 aliguori
}
1025 6f97dba0 aliguori
1026 3f4cb3d3 blueswir1
static void cfmakeraw (struct termios *termios_p)
1027 6f97dba0 aliguori
{
1028 6f97dba0 aliguori
        termios_p->c_iflag &=
1029 6f97dba0 aliguori
                ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
1030 6f97dba0 aliguori
        termios_p->c_oflag &= ~OPOST;
1031 6f97dba0 aliguori
        termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
1032 6f97dba0 aliguori
        termios_p->c_cflag &= ~(CSIZE|PARENB);
1033 6f97dba0 aliguori
        termios_p->c_cflag |= CS8;
1034 6f97dba0 aliguori
1035 6f97dba0 aliguori
        termios_p->c_cc[VMIN] = 0;
1036 6f97dba0 aliguori
        termios_p->c_cc[VTIME] = 0;
1037 6f97dba0 aliguori
}
1038 6f97dba0 aliguori
#endif
1039 6f97dba0 aliguori
1040 6f97dba0 aliguori
#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
1041 a167ba50 Aurelien Jarno
    || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
1042 a167ba50 Aurelien Jarno
    || defined(__GLIBC__)
1043 6f97dba0 aliguori
1044 e551498e Gerd Hoffmann
#define HAVE_CHARDEV_TTY 1
1045 e551498e Gerd Hoffmann
1046 6f97dba0 aliguori
typedef struct {
1047 093d3a20 Anthony Liguori
    GIOChannel *fd;
1048 093d3a20 Anthony Liguori
    guint fd_tag;
1049 6f97dba0 aliguori
    int connected;
1050 6f97dba0 aliguori
    int read_bytes;
1051 8aa33caf Anthony Liguori
    guint timer_tag;
1052 6f97dba0 aliguori
} PtyCharDriver;
1053 6f97dba0 aliguori
1054 6f97dba0 aliguori
static void pty_chr_update_read_handler(CharDriverState *chr);
1055 6f97dba0 aliguori
static void pty_chr_state(CharDriverState *chr, int connected);
1056 6f97dba0 aliguori
1057 8aa33caf Anthony Liguori
static gboolean pty_chr_timer(gpointer opaque)
1058 8aa33caf Anthony Liguori
{
1059 8aa33caf Anthony Liguori
    struct CharDriverState *chr = opaque;
1060 8aa33caf Anthony Liguori
    PtyCharDriver *s = chr->opaque;
1061 8aa33caf Anthony Liguori
1062 8aa33caf Anthony Liguori
    if (s->connected) {
1063 8aa33caf Anthony Liguori
        goto out;
1064 8aa33caf Anthony Liguori
    }
1065 8aa33caf Anthony Liguori
1066 8aa33caf Anthony Liguori
    /* Next poll ... */
1067 8aa33caf Anthony Liguori
    pty_chr_update_read_handler(chr);
1068 8aa33caf Anthony Liguori
1069 8aa33caf Anthony Liguori
out:
1070 79f20075 Hans de Goede
    s->timer_tag = 0;
1071 8aa33caf Anthony Liguori
    return FALSE;
1072 8aa33caf Anthony Liguori
}
1073 8aa33caf Anthony Liguori
1074 8aa33caf Anthony Liguori
static void pty_chr_rearm_timer(CharDriverState *chr, int ms)
1075 8aa33caf Anthony Liguori
{
1076 8aa33caf Anthony Liguori
    PtyCharDriver *s = chr->opaque;
1077 8aa33caf Anthony Liguori
1078 8aa33caf Anthony Liguori
    if (s->timer_tag) {
1079 8aa33caf Anthony Liguori
        g_source_remove(s->timer_tag);
1080 8aa33caf Anthony Liguori
        s->timer_tag = 0;
1081 8aa33caf Anthony Liguori
    }
1082 8aa33caf Anthony Liguori
1083 8aa33caf Anthony Liguori
    if (ms == 1000) {
1084 8aa33caf Anthony Liguori
        s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
1085 8aa33caf Anthony Liguori
    } else {
1086 8aa33caf Anthony Liguori
        s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
1087 8aa33caf Anthony Liguori
    }
1088 8aa33caf Anthony Liguori
}
1089 8aa33caf Anthony Liguori
1090 6f97dba0 aliguori
static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1091 6f97dba0 aliguori
{
1092 6f97dba0 aliguori
    PtyCharDriver *s = chr->opaque;
1093 6f97dba0 aliguori
1094 6f97dba0 aliguori
    if (!s->connected) {
1095 6f97dba0 aliguori
        /* guest sends data, check for (re-)connect */
1096 6f97dba0 aliguori
        pty_chr_update_read_handler(chr);
1097 6f97dba0 aliguori
        return 0;
1098 6f97dba0 aliguori
    }
1099 684a096e Anthony Liguori
    return io_channel_send(s->fd, buf, len);
1100 6f97dba0 aliguori
}
1101 6f97dba0 aliguori
1102 e6a87ed8 Anthony Liguori
static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond)
1103 e6a87ed8 Anthony Liguori
{
1104 e6a87ed8 Anthony Liguori
    PtyCharDriver *s = chr->opaque;
1105 e6a87ed8 Anthony Liguori
    return g_io_create_watch(s->fd, cond);
1106 e6a87ed8 Anthony Liguori
}
1107 e6a87ed8 Anthony Liguori
1108 6f97dba0 aliguori
static int pty_chr_read_poll(void *opaque)
1109 6f97dba0 aliguori
{
1110 6f97dba0 aliguori
    CharDriverState *chr = opaque;
1111 6f97dba0 aliguori
    PtyCharDriver *s = chr->opaque;
1112 6f97dba0 aliguori
1113 909cda12 Anthony Liguori
    s->read_bytes = qemu_chr_be_can_write(chr);
1114 6f97dba0 aliguori
    return s->read_bytes;
1115 6f97dba0 aliguori
}
1116 6f97dba0 aliguori
1117 093d3a20 Anthony Liguori
static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
1118 6f97dba0 aliguori
{
1119 6f97dba0 aliguori
    CharDriverState *chr = opaque;
1120 6f97dba0 aliguori
    PtyCharDriver *s = chr->opaque;
1121 093d3a20 Anthony Liguori
    gsize size, len;
1122 9bd7854e Amit Shah
    uint8_t buf[READ_BUF_LEN];
1123 093d3a20 Anthony Liguori
    GIOStatus status;
1124 6f97dba0 aliguori
1125 6f97dba0 aliguori
    len = sizeof(buf);
1126 6f97dba0 aliguori
    if (len > s->read_bytes)
1127 6f97dba0 aliguori
        len = s->read_bytes;
1128 cdbf6e16 Paolo Bonzini
    if (len == 0) {
1129 cdbf6e16 Paolo Bonzini
        return TRUE;
1130 cdbf6e16 Paolo Bonzini
    }
1131 093d3a20 Anthony Liguori
    status = g_io_channel_read_chars(s->fd, (gchar *)buf, len, &size, NULL);
1132 093d3a20 Anthony Liguori
    if (status != G_IO_STATUS_NORMAL) {
1133 6f97dba0 aliguori
        pty_chr_state(chr, 0);
1134 093d3a20 Anthony Liguori
        return FALSE;
1135 093d3a20 Anthony Liguori
    } else {
1136 6f97dba0 aliguori
        pty_chr_state(chr, 1);
1137 fa5efccb Anthony Liguori
        qemu_chr_be_write(chr, buf, size);
1138 6f97dba0 aliguori
    }
1139 093d3a20 Anthony Liguori
    return TRUE;
1140 6f97dba0 aliguori
}
1141 6f97dba0 aliguori
1142 6f97dba0 aliguori
static void pty_chr_update_read_handler(CharDriverState *chr)
1143 6f97dba0 aliguori
{
1144 6f97dba0 aliguori
    PtyCharDriver *s = chr->opaque;
1145 85a67692 Paolo Bonzini
    GPollFD pfd;
1146 6f97dba0 aliguori
1147 85a67692 Paolo Bonzini
    pfd.fd = g_io_channel_unix_get_fd(s->fd);
1148 85a67692 Paolo Bonzini
    pfd.events = G_IO_OUT;
1149 85a67692 Paolo Bonzini
    pfd.revents = 0;
1150 85a67692 Paolo Bonzini
    g_poll(&pfd, 1, 0);
1151 85a67692 Paolo Bonzini
    if (pfd.revents & G_IO_HUP) {
1152 85a67692 Paolo Bonzini
        pty_chr_state(chr, 0);
1153 85a67692 Paolo Bonzini
    } else {
1154 85a67692 Paolo Bonzini
        pty_chr_state(chr, 1);
1155 093d3a20 Anthony Liguori
    }
1156 6f97dba0 aliguori
}
1157 6f97dba0 aliguori
1158 6f97dba0 aliguori
static void pty_chr_state(CharDriverState *chr, int connected)
1159 6f97dba0 aliguori
{
1160 6f97dba0 aliguori
    PtyCharDriver *s = chr->opaque;
1161 6f97dba0 aliguori
1162 6f97dba0 aliguori
    if (!connected) {
1163 910b6368 Paolo Bonzini
        if (s->fd_tag) {
1164 2b316774 Paolo Bonzini
            io_remove_watch_poll(s->fd_tag);
1165 910b6368 Paolo Bonzini
            s->fd_tag = 0;
1166 910b6368 Paolo Bonzini
        }
1167 6f97dba0 aliguori
        s->connected = 0;
1168 6f97dba0 aliguori
        /* (re-)connect poll interval for idle guests: once per second.
1169 6f97dba0 aliguori
         * We check more frequently in case the guests sends data to
1170 6f97dba0 aliguori
         * the virtual device linked to our pty. */
1171 8aa33caf Anthony Liguori
        pty_chr_rearm_timer(chr, 1000);
1172 6f97dba0 aliguori
    } else {
1173 85a67692 Paolo Bonzini
        if (s->timer_tag) {
1174 85a67692 Paolo Bonzini
            g_source_remove(s->timer_tag);
1175 85a67692 Paolo Bonzini
            s->timer_tag = 0;
1176 85a67692 Paolo Bonzini
        }
1177 85a67692 Paolo Bonzini
        if (!s->connected) {
1178 fee204fd Hans de Goede
            qemu_chr_be_generic_open(chr);
1179 85a67692 Paolo Bonzini
            s->connected = 1;
1180 85a67692 Paolo Bonzini
            s->fd_tag = io_add_watch_poll(s->fd, pty_chr_read_poll, pty_chr_read, chr);
1181 85a67692 Paolo Bonzini
        }
1182 6f97dba0 aliguori
    }
1183 6f97dba0 aliguori
}
1184 6f97dba0 aliguori
1185 6f97dba0 aliguori
1186 6f97dba0 aliguori
static void pty_chr_close(struct CharDriverState *chr)
1187 6f97dba0 aliguori
{
1188 6f97dba0 aliguori
    PtyCharDriver *s = chr->opaque;
1189 093d3a20 Anthony Liguori
    int fd;
1190 6f97dba0 aliguori
1191 093d3a20 Anthony Liguori
    if (s->fd_tag) {
1192 2b316774 Paolo Bonzini
        io_remove_watch_poll(s->fd_tag);
1193 910b6368 Paolo Bonzini
        s->fd_tag = 0;
1194 093d3a20 Anthony Liguori
    }
1195 093d3a20 Anthony Liguori
    fd = g_io_channel_unix_get_fd(s->fd);
1196 093d3a20 Anthony Liguori
    g_io_channel_unref(s->fd);
1197 093d3a20 Anthony Liguori
    close(fd);
1198 8aa33caf Anthony Liguori
    if (s->timer_tag) {
1199 8aa33caf Anthony Liguori
        g_source_remove(s->timer_tag);
1200 910b6368 Paolo Bonzini
        s->timer_tag = 0;
1201 8aa33caf Anthony Liguori
    }
1202 7267c094 Anthony Liguori
    g_free(s);
1203 a425d23f Hans de Goede
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1204 6f97dba0 aliguori
}
1205 6f97dba0 aliguori
1206 e68c5958 Gerd Hoffmann
static CharDriverState *qemu_chr_open_pty(const char *id,
1207 e68c5958 Gerd Hoffmann
                                          ChardevReturn *ret)
1208 6f97dba0 aliguori
{
1209 6f97dba0 aliguori
    CharDriverState *chr;
1210 6f97dba0 aliguori
    PtyCharDriver *s;
1211 6f97dba0 aliguori
    struct termios tty;
1212 e68c5958 Gerd Hoffmann
    int master_fd, slave_fd;
1213 c5e97233 blueswir1
#if defined(__OpenBSD__) || defined(__DragonFly__)
1214 6f97dba0 aliguori
    char pty_name[PATH_MAX];
1215 6f97dba0 aliguori
#define q_ptsname(x) pty_name
1216 6f97dba0 aliguori
#else
1217 6f97dba0 aliguori
    char *pty_name = NULL;
1218 6f97dba0 aliguori
#define q_ptsname(x) ptsname(x)
1219 6f97dba0 aliguori
#endif
1220 6f97dba0 aliguori
1221 a4e26048 Markus Armbruster
    if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) {
1222 1f51470d Markus Armbruster
        return NULL;
1223 6f97dba0 aliguori
    }
1224 6f97dba0 aliguori
1225 6f97dba0 aliguori
    /* Set raw attributes on the pty. */
1226 c3b972c3 aliguori
    tcgetattr(slave_fd, &tty);
1227 6f97dba0 aliguori
    cfmakeraw(&tty);
1228 6f97dba0 aliguori
    tcsetattr(slave_fd, TCSAFLUSH, &tty);
1229 6f97dba0 aliguori
    close(slave_fd);
1230 6f97dba0 aliguori
1231 a4e26048 Markus Armbruster
    chr = g_malloc0(sizeof(CharDriverState));
1232 a4e26048 Markus Armbruster
1233 e68c5958 Gerd Hoffmann
    chr->filename = g_strdup_printf("pty:%s", q_ptsname(master_fd));
1234 e68c5958 Gerd Hoffmann
    ret->pty = g_strdup(q_ptsname(master_fd));
1235 e68c5958 Gerd Hoffmann
    ret->has_pty = true;
1236 58650218 Lei Li
1237 e68c5958 Gerd Hoffmann
    fprintf(stderr, "char device redirected to %s (label %s)\n",
1238 e68c5958 Gerd Hoffmann
            q_ptsname(master_fd), id);
1239 6f97dba0 aliguori
1240 a4e26048 Markus Armbruster
    s = g_malloc0(sizeof(PtyCharDriver));
1241 6f97dba0 aliguori
    chr->opaque = s;
1242 6f97dba0 aliguori
    chr->chr_write = pty_chr_write;
1243 6f97dba0 aliguori
    chr->chr_update_read_handler = pty_chr_update_read_handler;
1244 6f97dba0 aliguori
    chr->chr_close = pty_chr_close;
1245 e6a87ed8 Anthony Liguori
    chr->chr_add_watch = pty_chr_add_watch;
1246 6f97dba0 aliguori
1247 093d3a20 Anthony Liguori
    s->fd = io_channel_from_fd(master_fd);
1248 8aa33caf Anthony Liguori
    s->timer_tag = 0;
1249 6f97dba0 aliguori
1250 1f51470d Markus Armbruster
    return chr;
1251 6f97dba0 aliguori
}
1252 6f97dba0 aliguori
1253 6f97dba0 aliguori
static void tty_serial_init(int fd, int speed,
1254 6f97dba0 aliguori
                            int parity, int data_bits, int stop_bits)
1255 6f97dba0 aliguori
{
1256 6f97dba0 aliguori
    struct termios tty;
1257 6f97dba0 aliguori
    speed_t spd;
1258 6f97dba0 aliguori
1259 6f97dba0 aliguori
#if 0
1260 6f97dba0 aliguori
    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
1261 6f97dba0 aliguori
           speed, parity, data_bits, stop_bits);
1262 6f97dba0 aliguori
#endif
1263 6f97dba0 aliguori
    tcgetattr (fd, &tty);
1264 6f97dba0 aliguori
1265 45eea13b Stefan Weil
#define check_speed(val) if (speed <= val) { spd = B##val; break; }
1266 45eea13b Stefan Weil
    speed = speed * 10 / 11;
1267 45eea13b Stefan Weil
    do {
1268 45eea13b Stefan Weil
        check_speed(50);
1269 45eea13b Stefan Weil
        check_speed(75);
1270 45eea13b Stefan Weil
        check_speed(110);
1271 45eea13b Stefan Weil
        check_speed(134);
1272 45eea13b Stefan Weil
        check_speed(150);
1273 45eea13b Stefan Weil
        check_speed(200);
1274 45eea13b Stefan Weil
        check_speed(300);
1275 45eea13b Stefan Weil
        check_speed(600);
1276 45eea13b Stefan Weil
        check_speed(1200);
1277 45eea13b Stefan Weil
        check_speed(1800);
1278 45eea13b Stefan Weil
        check_speed(2400);
1279 45eea13b Stefan Weil
        check_speed(4800);
1280 45eea13b Stefan Weil
        check_speed(9600);
1281 45eea13b Stefan Weil
        check_speed(19200);
1282 45eea13b Stefan Weil
        check_speed(38400);
1283 45eea13b Stefan Weil
        /* Non-Posix values follow. They may be unsupported on some systems. */
1284 45eea13b Stefan Weil
        check_speed(57600);
1285 45eea13b Stefan Weil
        check_speed(115200);
1286 45eea13b Stefan Weil
#ifdef B230400
1287 45eea13b Stefan Weil
        check_speed(230400);
1288 45eea13b Stefan Weil
#endif
1289 45eea13b Stefan Weil
#ifdef B460800
1290 45eea13b Stefan Weil
        check_speed(460800);
1291 45eea13b Stefan Weil
#endif
1292 45eea13b Stefan Weil
#ifdef B500000
1293 45eea13b Stefan Weil
        check_speed(500000);
1294 45eea13b Stefan Weil
#endif
1295 45eea13b Stefan Weil
#ifdef B576000
1296 45eea13b Stefan Weil
        check_speed(576000);
1297 45eea13b Stefan Weil
#endif
1298 45eea13b Stefan Weil
#ifdef B921600
1299 45eea13b Stefan Weil
        check_speed(921600);
1300 45eea13b Stefan Weil
#endif
1301 45eea13b Stefan Weil
#ifdef B1000000
1302 45eea13b Stefan Weil
        check_speed(1000000);
1303 45eea13b Stefan Weil
#endif
1304 45eea13b Stefan Weil
#ifdef B1152000
1305 45eea13b Stefan Weil
        check_speed(1152000);
1306 45eea13b Stefan Weil
#endif
1307 45eea13b Stefan Weil
#ifdef B1500000
1308 45eea13b Stefan Weil
        check_speed(1500000);
1309 45eea13b Stefan Weil
#endif
1310 45eea13b Stefan Weil
#ifdef B2000000
1311 45eea13b Stefan Weil
        check_speed(2000000);
1312 45eea13b Stefan Weil
#endif
1313 45eea13b Stefan Weil
#ifdef B2500000
1314 45eea13b Stefan Weil
        check_speed(2500000);
1315 45eea13b Stefan Weil
#endif
1316 45eea13b Stefan Weil
#ifdef B3000000
1317 45eea13b Stefan Weil
        check_speed(3000000);
1318 45eea13b Stefan Weil
#endif
1319 45eea13b Stefan Weil
#ifdef B3500000
1320 45eea13b Stefan Weil
        check_speed(3500000);
1321 45eea13b Stefan Weil
#endif
1322 45eea13b Stefan Weil
#ifdef B4000000
1323 45eea13b Stefan Weil
        check_speed(4000000);
1324 45eea13b Stefan Weil
#endif
1325 6f97dba0 aliguori
        spd = B115200;
1326 45eea13b Stefan Weil
    } while (0);
1327 6f97dba0 aliguori
1328 6f97dba0 aliguori
    cfsetispeed(&tty, spd);
1329 6f97dba0 aliguori
    cfsetospeed(&tty, spd);
1330 6f97dba0 aliguori
1331 6f97dba0 aliguori
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1332 6f97dba0 aliguori
                          |INLCR|IGNCR|ICRNL|IXON);
1333 6f97dba0 aliguori
    tty.c_oflag |= OPOST;
1334 6f97dba0 aliguori
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
1335 6f97dba0 aliguori
    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
1336 6f97dba0 aliguori
    switch(data_bits) {
1337 6f97dba0 aliguori
    default:
1338 6f97dba0 aliguori
    case 8:
1339 6f97dba0 aliguori
        tty.c_cflag |= CS8;
1340 6f97dba0 aliguori
        break;
1341 6f97dba0 aliguori
    case 7:
1342 6f97dba0 aliguori
        tty.c_cflag |= CS7;
1343 6f97dba0 aliguori
        break;
1344 6f97dba0 aliguori
    case 6:
1345 6f97dba0 aliguori
        tty.c_cflag |= CS6;
1346 6f97dba0 aliguori
        break;
1347 6f97dba0 aliguori
    case 5:
1348 6f97dba0 aliguori
        tty.c_cflag |= CS5;
1349 6f97dba0 aliguori
        break;
1350 6f97dba0 aliguori
    }
1351 6f97dba0 aliguori
    switch(parity) {
1352 6f97dba0 aliguori
    default:
1353 6f97dba0 aliguori
    case 'N':
1354 6f97dba0 aliguori
        break;
1355 6f97dba0 aliguori
    case 'E':
1356 6f97dba0 aliguori
        tty.c_cflag |= PARENB;
1357 6f97dba0 aliguori
        break;
1358 6f97dba0 aliguori
    case 'O':
1359 6f97dba0 aliguori
        tty.c_cflag |= PARENB | PARODD;
1360 6f97dba0 aliguori
        break;
1361 6f97dba0 aliguori
    }
1362 6f97dba0 aliguori
    if (stop_bits == 2)
1363 6f97dba0 aliguori
        tty.c_cflag |= CSTOPB;
1364 6f97dba0 aliguori
1365 6f97dba0 aliguori
    tcsetattr (fd, TCSANOW, &tty);
1366 6f97dba0 aliguori
}
1367 6f97dba0 aliguori
1368 6f97dba0 aliguori
static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
1369 6f97dba0 aliguori
{
1370 6f97dba0 aliguori
    FDCharDriver *s = chr->opaque;
1371 6f97dba0 aliguori
1372 6f97dba0 aliguori
    switch(cmd) {
1373 6f97dba0 aliguori
    case CHR_IOCTL_SERIAL_SET_PARAMS:
1374 6f97dba0 aliguori
        {
1375 6f97dba0 aliguori
            QEMUSerialSetParams *ssp = arg;
1376 a29753f8 Anthony Liguori
            tty_serial_init(g_io_channel_unix_get_fd(s->fd_in),
1377 a29753f8 Anthony Liguori
                            ssp->speed, ssp->parity,
1378 6f97dba0 aliguori
                            ssp->data_bits, ssp->stop_bits);
1379 6f97dba0 aliguori
        }
1380 6f97dba0 aliguori
        break;
1381 6f97dba0 aliguori
    case CHR_IOCTL_SERIAL_SET_BREAK:
1382 6f97dba0 aliguori
        {
1383 6f97dba0 aliguori
            int enable = *(int *)arg;
1384 a29753f8 Anthony Liguori
            if (enable) {
1385 a29753f8 Anthony Liguori
                tcsendbreak(g_io_channel_unix_get_fd(s->fd_in), 1);
1386 a29753f8 Anthony Liguori
            }
1387 6f97dba0 aliguori
        }
1388 6f97dba0 aliguori
        break;
1389 6f97dba0 aliguori
    case CHR_IOCTL_SERIAL_GET_TIOCM:
1390 6f97dba0 aliguori
        {
1391 6f97dba0 aliguori
            int sarg = 0;
1392 6f97dba0 aliguori
            int *targ = (int *)arg;
1393 a29753f8 Anthony Liguori
            ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &sarg);
1394 6f97dba0 aliguori
            *targ = 0;
1395 b4abdfa4 aurel32
            if (sarg & TIOCM_CTS)
1396 6f97dba0 aliguori
                *targ |= CHR_TIOCM_CTS;
1397 b4abdfa4 aurel32
            if (sarg & TIOCM_CAR)
1398 6f97dba0 aliguori
                *targ |= CHR_TIOCM_CAR;
1399 b4abdfa4 aurel32
            if (sarg & TIOCM_DSR)
1400 6f97dba0 aliguori
                *targ |= CHR_TIOCM_DSR;
1401 b4abdfa4 aurel32
            if (sarg & TIOCM_RI)
1402 6f97dba0 aliguori
                *targ |= CHR_TIOCM_RI;
1403 b4abdfa4 aurel32
            if (sarg & TIOCM_DTR)
1404 6f97dba0 aliguori
                *targ |= CHR_TIOCM_DTR;
1405 b4abdfa4 aurel32
            if (sarg & TIOCM_RTS)
1406 6f97dba0 aliguori
                *targ |= CHR_TIOCM_RTS;
1407 6f97dba0 aliguori
        }
1408 6f97dba0 aliguori
        break;
1409 6f97dba0 aliguori
    case CHR_IOCTL_SERIAL_SET_TIOCM:
1410 6f97dba0 aliguori
        {
1411 6f97dba0 aliguori
            int sarg = *(int *)arg;
1412 6f97dba0 aliguori
            int targ = 0;
1413 a29753f8 Anthony Liguori
            ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &targ);
1414 b4abdfa4 aurel32
            targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
1415 b4abdfa4 aurel32
                     | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
1416 b4abdfa4 aurel32
            if (sarg & CHR_TIOCM_CTS)
1417 b4abdfa4 aurel32
                targ |= TIOCM_CTS;
1418 b4abdfa4 aurel32
            if (sarg & CHR_TIOCM_CAR)
1419 b4abdfa4 aurel32
                targ |= TIOCM_CAR;
1420 b4abdfa4 aurel32
            if (sarg & CHR_TIOCM_DSR)
1421 b4abdfa4 aurel32
                targ |= TIOCM_DSR;
1422 b4abdfa4 aurel32
            if (sarg & CHR_TIOCM_RI)
1423 b4abdfa4 aurel32
                targ |= TIOCM_RI;
1424 b4abdfa4 aurel32
            if (sarg & CHR_TIOCM_DTR)
1425 6f97dba0 aliguori
                targ |= TIOCM_DTR;
1426 b4abdfa4 aurel32
            if (sarg & CHR_TIOCM_RTS)
1427 6f97dba0 aliguori
                targ |= TIOCM_RTS;
1428 a29753f8 Anthony Liguori
            ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ);
1429 6f97dba0 aliguori
        }
1430 6f97dba0 aliguori
        break;
1431 6f97dba0 aliguori
    default:
1432 6f97dba0 aliguori
        return -ENOTSUP;
1433 6f97dba0 aliguori
    }
1434 6f97dba0 aliguori
    return 0;
1435 6f97dba0 aliguori
}
1436 6f97dba0 aliguori
1437 4266a134 David Ahern
static void qemu_chr_close_tty(CharDriverState *chr)
1438 4266a134 David Ahern
{
1439 4266a134 David Ahern
    FDCharDriver *s = chr->opaque;
1440 4266a134 David Ahern
    int fd = -1;
1441 4266a134 David Ahern
1442 4266a134 David Ahern
    if (s) {
1443 a29753f8 Anthony Liguori
        fd = g_io_channel_unix_get_fd(s->fd_in);
1444 4266a134 David Ahern
    }
1445 4266a134 David Ahern
1446 4266a134 David Ahern
    fd_chr_close(chr);
1447 4266a134 David Ahern
1448 4266a134 David Ahern
    if (fd >= 0) {
1449 4266a134 David Ahern
        close(fd);
1450 4266a134 David Ahern
    }
1451 4266a134 David Ahern
}
1452 4266a134 David Ahern
1453 d59044ef Gerd Hoffmann
static CharDriverState *qemu_chr_open_tty_fd(int fd)
1454 d59044ef Gerd Hoffmann
{
1455 d59044ef Gerd Hoffmann
    CharDriverState *chr;
1456 d59044ef Gerd Hoffmann
1457 d59044ef Gerd Hoffmann
    tty_serial_init(fd, 115200, 'N', 8, 1);
1458 d59044ef Gerd Hoffmann
    chr = qemu_chr_open_fd(fd, fd);
1459 d59044ef Gerd Hoffmann
    chr->chr_ioctl = tty_serial_ioctl;
1460 d59044ef Gerd Hoffmann
    chr->chr_close = qemu_chr_close_tty;
1461 d59044ef Gerd Hoffmann
    return chr;
1462 d59044ef Gerd Hoffmann
}
1463 6f97dba0 aliguori
#endif /* __linux__ || __sun__ */
1464 6f97dba0 aliguori
1465 6f97dba0 aliguori
#if defined(__linux__)
1466 e551498e Gerd Hoffmann
1467 e551498e Gerd Hoffmann
#define HAVE_CHARDEV_PARPORT 1
1468 e551498e Gerd Hoffmann
1469 6f97dba0 aliguori
typedef struct {
1470 6f97dba0 aliguori
    int fd;
1471 6f97dba0 aliguori
    int mode;
1472 6f97dba0 aliguori
} ParallelCharDriver;
1473 6f97dba0 aliguori
1474 6f97dba0 aliguori
static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
1475 6f97dba0 aliguori
{
1476 6f97dba0 aliguori
    if (s->mode != mode) {
1477 6f97dba0 aliguori
        int m = mode;
1478 6f97dba0 aliguori
        if (ioctl(s->fd, PPSETMODE, &m) < 0)
1479 6f97dba0 aliguori
            return 0;
1480 6f97dba0 aliguori
        s->mode = mode;
1481 6f97dba0 aliguori
    }
1482 6f97dba0 aliguori
    return 1;
1483 6f97dba0 aliguori
}
1484 6f97dba0 aliguori
1485 6f97dba0 aliguori
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1486 6f97dba0 aliguori
{
1487 6f97dba0 aliguori
    ParallelCharDriver *drv = chr->opaque;
1488 6f97dba0 aliguori
    int fd = drv->fd;
1489 6f97dba0 aliguori
    uint8_t b;
1490 6f97dba0 aliguori
1491 6f97dba0 aliguori
    switch(cmd) {
1492 6f97dba0 aliguori
    case CHR_IOCTL_PP_READ_DATA:
1493 6f97dba0 aliguori
        if (ioctl(fd, PPRDATA, &b) < 0)
1494 6f97dba0 aliguori
            return -ENOTSUP;
1495 6f97dba0 aliguori
        *(uint8_t *)arg = b;
1496 6f97dba0 aliguori
        break;
1497 6f97dba0 aliguori
    case CHR_IOCTL_PP_WRITE_DATA:
1498 6f97dba0 aliguori
        b = *(uint8_t *)arg;
1499 6f97dba0 aliguori
        if (ioctl(fd, PPWDATA, &b) < 0)
1500 6f97dba0 aliguori
            return -ENOTSUP;
1501 6f97dba0 aliguori
        break;
1502 6f97dba0 aliguori
    case CHR_IOCTL_PP_READ_CONTROL:
1503 6f97dba0 aliguori
        if (ioctl(fd, PPRCONTROL, &b) < 0)
1504 6f97dba0 aliguori
            return -ENOTSUP;
1505 6f97dba0 aliguori
        /* Linux gives only the lowest bits, and no way to know data
1506 6f97dba0 aliguori
           direction! For better compatibility set the fixed upper
1507 6f97dba0 aliguori
           bits. */
1508 6f97dba0 aliguori
        *(uint8_t *)arg = b | 0xc0;
1509 6f97dba0 aliguori
        break;
1510 6f97dba0 aliguori
    case CHR_IOCTL_PP_WRITE_CONTROL:
1511 6f97dba0 aliguori
        b = *(uint8_t *)arg;
1512 6f97dba0 aliguori
        if (ioctl(fd, PPWCONTROL, &b) < 0)
1513 6f97dba0 aliguori
            return -ENOTSUP;
1514 6f97dba0 aliguori
        break;
1515 6f97dba0 aliguori
    case CHR_IOCTL_PP_READ_STATUS:
1516 6f97dba0 aliguori
        if (ioctl(fd, PPRSTATUS, &b) < 0)
1517 6f97dba0 aliguori
            return -ENOTSUP;
1518 6f97dba0 aliguori
        *(uint8_t *)arg = b;
1519 6f97dba0 aliguori
        break;
1520 6f97dba0 aliguori
    case CHR_IOCTL_PP_DATA_DIR:
1521 6f97dba0 aliguori
        if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
1522 6f97dba0 aliguori
            return -ENOTSUP;
1523 6f97dba0 aliguori
        break;
1524 6f97dba0 aliguori
    case CHR_IOCTL_PP_EPP_READ_ADDR:
1525 6f97dba0 aliguori
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1526 6f97dba0 aliguori
            struct ParallelIOArg *parg = arg;
1527 6f97dba0 aliguori
            int n = read(fd, parg->buffer, parg->count);
1528 6f97dba0 aliguori
            if (n != parg->count) {
1529 6f97dba0 aliguori
                return -EIO;
1530 6f97dba0 aliguori
            }
1531 6f97dba0 aliguori
        }
1532 6f97dba0 aliguori
        break;
1533 6f97dba0 aliguori
    case CHR_IOCTL_PP_EPP_READ:
1534 6f97dba0 aliguori
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1535 6f97dba0 aliguori
            struct ParallelIOArg *parg = arg;
1536 6f97dba0 aliguori
            int n = read(fd, parg->buffer, parg->count);
1537 6f97dba0 aliguori
            if (n != parg->count) {
1538 6f97dba0 aliguori
                return -EIO;
1539 6f97dba0 aliguori
            }
1540 6f97dba0 aliguori
        }
1541 6f97dba0 aliguori
        break;
1542 6f97dba0 aliguori
    case CHR_IOCTL_PP_EPP_WRITE_ADDR:
1543 6f97dba0 aliguori
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1544 6f97dba0 aliguori
            struct ParallelIOArg *parg = arg;
1545 6f97dba0 aliguori
            int n = write(fd, parg->buffer, parg->count);
1546 6f97dba0 aliguori
            if (n != parg->count) {
1547 6f97dba0 aliguori
                return -EIO;
1548 6f97dba0 aliguori
            }
1549 6f97dba0 aliguori
        }
1550 6f97dba0 aliguori
        break;
1551 6f97dba0 aliguori
    case CHR_IOCTL_PP_EPP_WRITE:
1552 6f97dba0 aliguori
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1553 6f97dba0 aliguori
            struct ParallelIOArg *parg = arg;
1554 6f97dba0 aliguori
            int n = write(fd, parg->buffer, parg->count);
1555 6f97dba0 aliguori
            if (n != parg->count) {
1556 6f97dba0 aliguori
                return -EIO;
1557 6f97dba0 aliguori
            }
1558 6f97dba0 aliguori
        }
1559 6f97dba0 aliguori
        break;
1560 6f97dba0 aliguori
    default:
1561 6f97dba0 aliguori
        return -ENOTSUP;
1562 6f97dba0 aliguori
    }
1563 6f97dba0 aliguori
    return 0;
1564 6f97dba0 aliguori
}
1565 6f97dba0 aliguori
1566 6f97dba0 aliguori
static void pp_close(CharDriverState *chr)
1567 6f97dba0 aliguori
{
1568 6f97dba0 aliguori
    ParallelCharDriver *drv = chr->opaque;
1569 6f97dba0 aliguori
    int fd = drv->fd;
1570 6f97dba0 aliguori
1571 6f97dba0 aliguori
    pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
1572 6f97dba0 aliguori
    ioctl(fd, PPRELEASE);
1573 6f97dba0 aliguori
    close(fd);
1574 7267c094 Anthony Liguori
    g_free(drv);
1575 a425d23f Hans de Goede
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1576 6f97dba0 aliguori
}
1577 6f97dba0 aliguori
1578 88a946d3 Gerd Hoffmann
static CharDriverState *qemu_chr_open_pp_fd(int fd)
1579 6f97dba0 aliguori
{
1580 6f97dba0 aliguori
    CharDriverState *chr;
1581 6f97dba0 aliguori
    ParallelCharDriver *drv;
1582 6f97dba0 aliguori
1583 6f97dba0 aliguori
    if (ioctl(fd, PPCLAIM) < 0) {
1584 6f97dba0 aliguori
        close(fd);
1585 1f51470d Markus Armbruster
        return NULL;
1586 6f97dba0 aliguori
    }
1587 6f97dba0 aliguori
1588 7267c094 Anthony Liguori
    drv = g_malloc0(sizeof(ParallelCharDriver));
1589 6f97dba0 aliguori
    drv->fd = fd;
1590 6f97dba0 aliguori
    drv->mode = IEEE1284_MODE_COMPAT;
1591 6f97dba0 aliguori
1592 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
1593 6f97dba0 aliguori
    chr->chr_write = null_chr_write;
1594 6f97dba0 aliguori
    chr->chr_ioctl = pp_ioctl;
1595 6f97dba0 aliguori
    chr->chr_close = pp_close;
1596 6f97dba0 aliguori
    chr->opaque = drv;
1597 6f97dba0 aliguori
1598 fee204fd Hans de Goede
    qemu_chr_be_generic_open(chr);
1599 6f97dba0 aliguori
1600 1f51470d Markus Armbruster
    return chr;
1601 6f97dba0 aliguori
}
1602 6f97dba0 aliguori
#endif /* __linux__ */
1603 6f97dba0 aliguori
1604 a167ba50 Aurelien Jarno
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1605 e551498e Gerd Hoffmann
1606 e551498e Gerd Hoffmann
#define HAVE_CHARDEV_PARPORT 1
1607 e551498e Gerd Hoffmann
1608 6972f935 blueswir1
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1609 6972f935 blueswir1
{
1610 e0efb993 Stefan Weil
    int fd = (int)(intptr_t)chr->opaque;
1611 6972f935 blueswir1
    uint8_t b;
1612 6972f935 blueswir1
1613 6972f935 blueswir1
    switch(cmd) {
1614 6972f935 blueswir1
    case CHR_IOCTL_PP_READ_DATA:
1615 6972f935 blueswir1
        if (ioctl(fd, PPIGDATA, &b) < 0)
1616 6972f935 blueswir1
            return -ENOTSUP;
1617 6972f935 blueswir1
        *(uint8_t *)arg = b;
1618 6972f935 blueswir1
        break;
1619 6972f935 blueswir1
    case CHR_IOCTL_PP_WRITE_DATA:
1620 6972f935 blueswir1
        b = *(uint8_t *)arg;
1621 6972f935 blueswir1
        if (ioctl(fd, PPISDATA, &b) < 0)
1622 6972f935 blueswir1
            return -ENOTSUP;
1623 6972f935 blueswir1
        break;
1624 6972f935 blueswir1
    case CHR_IOCTL_PP_READ_CONTROL:
1625 6972f935 blueswir1
        if (ioctl(fd, PPIGCTRL, &b) < 0)
1626 6972f935 blueswir1
            return -ENOTSUP;
1627 6972f935 blueswir1
        *(uint8_t *)arg = b;
1628 6972f935 blueswir1
        break;
1629 6972f935 blueswir1
    case CHR_IOCTL_PP_WRITE_CONTROL:
1630 6972f935 blueswir1
        b = *(uint8_t *)arg;
1631 6972f935 blueswir1
        if (ioctl(fd, PPISCTRL, &b) < 0)
1632 6972f935 blueswir1
            return -ENOTSUP;
1633 6972f935 blueswir1
        break;
1634 6972f935 blueswir1
    case CHR_IOCTL_PP_READ_STATUS:
1635 6972f935 blueswir1
        if (ioctl(fd, PPIGSTATUS, &b) < 0)
1636 6972f935 blueswir1
            return -ENOTSUP;
1637 6972f935 blueswir1
        *(uint8_t *)arg = b;
1638 6972f935 blueswir1
        break;
1639 6972f935 blueswir1
    default:
1640 6972f935 blueswir1
        return -ENOTSUP;
1641 6972f935 blueswir1
    }
1642 6972f935 blueswir1
    return 0;
1643 6972f935 blueswir1
}
1644 6972f935 blueswir1
1645 88a946d3 Gerd Hoffmann
static CharDriverState *qemu_chr_open_pp_fd(int fd)
1646 6972f935 blueswir1
{
1647 6972f935 blueswir1
    CharDriverState *chr;
1648 6972f935 blueswir1
1649 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
1650 e0efb993 Stefan Weil
    chr->opaque = (void *)(intptr_t)fd;
1651 6972f935 blueswir1
    chr->chr_write = null_chr_write;
1652 6972f935 blueswir1
    chr->chr_ioctl = pp_ioctl;
1653 1f51470d Markus Armbruster
    return chr;
1654 6972f935 blueswir1
}
1655 6972f935 blueswir1
#endif
1656 6972f935 blueswir1
1657 6f97dba0 aliguori
#else /* _WIN32 */
1658 6f97dba0 aliguori
1659 6f97dba0 aliguori
typedef struct {
1660 6f97dba0 aliguori
    int max_size;
1661 6f97dba0 aliguori
    HANDLE hcom, hrecv, hsend;
1662 6f97dba0 aliguori
    OVERLAPPED orecv, osend;
1663 6f97dba0 aliguori
    BOOL fpipe;
1664 6f97dba0 aliguori
    DWORD len;
1665 6f97dba0 aliguori
} WinCharState;
1666 6f97dba0 aliguori
1667 db418a0a Fabien Chouteau
typedef struct {
1668 db418a0a Fabien Chouteau
    HANDLE  hStdIn;
1669 db418a0a Fabien Chouteau
    HANDLE  hInputReadyEvent;
1670 db418a0a Fabien Chouteau
    HANDLE  hInputDoneEvent;
1671 db418a0a Fabien Chouteau
    HANDLE  hInputThread;
1672 db418a0a Fabien Chouteau
    uint8_t win_stdio_buf;
1673 db418a0a Fabien Chouteau
} WinStdioCharState;
1674 db418a0a Fabien Chouteau
1675 6f97dba0 aliguori
#define NSENDBUF 2048
1676 6f97dba0 aliguori
#define NRECVBUF 2048
1677 6f97dba0 aliguori
#define MAXCONNECT 1
1678 6f97dba0 aliguori
#define NTIMEOUT 5000
1679 6f97dba0 aliguori
1680 6f97dba0 aliguori
static int win_chr_poll(void *opaque);
1681 6f97dba0 aliguori
static int win_chr_pipe_poll(void *opaque);
1682 6f97dba0 aliguori
1683 6f97dba0 aliguori
static void win_chr_close(CharDriverState *chr)
1684 6f97dba0 aliguori
{
1685 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1686 6f97dba0 aliguori
1687 6f97dba0 aliguori
    if (s->hsend) {
1688 6f97dba0 aliguori
        CloseHandle(s->hsend);
1689 6f97dba0 aliguori
        s->hsend = NULL;
1690 6f97dba0 aliguori
    }
1691 6f97dba0 aliguori
    if (s->hrecv) {
1692 6f97dba0 aliguori
        CloseHandle(s->hrecv);
1693 6f97dba0 aliguori
        s->hrecv = NULL;
1694 6f97dba0 aliguori
    }
1695 6f97dba0 aliguori
    if (s->hcom) {
1696 6f97dba0 aliguori
        CloseHandle(s->hcom);
1697 6f97dba0 aliguori
        s->hcom = NULL;
1698 6f97dba0 aliguori
    }
1699 6f97dba0 aliguori
    if (s->fpipe)
1700 6f97dba0 aliguori
        qemu_del_polling_cb(win_chr_pipe_poll, chr);
1701 6f97dba0 aliguori
    else
1702 6f97dba0 aliguori
        qemu_del_polling_cb(win_chr_poll, chr);
1703 793cbfb5 Amit Shah
1704 a425d23f Hans de Goede
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1705 6f97dba0 aliguori
}
1706 6f97dba0 aliguori
1707 6f97dba0 aliguori
static int win_chr_init(CharDriverState *chr, const char *filename)
1708 6f97dba0 aliguori
{
1709 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1710 6f97dba0 aliguori
    COMMCONFIG comcfg;
1711 6f97dba0 aliguori
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
1712 6f97dba0 aliguori
    COMSTAT comstat;
1713 6f97dba0 aliguori
    DWORD size;
1714 6f97dba0 aliguori
    DWORD err;
1715 6f97dba0 aliguori
1716 6f97dba0 aliguori
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1717 6f97dba0 aliguori
    if (!s->hsend) {
1718 6f97dba0 aliguori
        fprintf(stderr, "Failed CreateEvent\n");
1719 6f97dba0 aliguori
        goto fail;
1720 6f97dba0 aliguori
    }
1721 6f97dba0 aliguori
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1722 6f97dba0 aliguori
    if (!s->hrecv) {
1723 6f97dba0 aliguori
        fprintf(stderr, "Failed CreateEvent\n");
1724 6f97dba0 aliguori
        goto fail;
1725 6f97dba0 aliguori
    }
1726 6f97dba0 aliguori
1727 6f97dba0 aliguori
    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1728 6f97dba0 aliguori
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
1729 6f97dba0 aliguori
    if (s->hcom == INVALID_HANDLE_VALUE) {
1730 6f97dba0 aliguori
        fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
1731 6f97dba0 aliguori
        s->hcom = NULL;
1732 6f97dba0 aliguori
        goto fail;
1733 6f97dba0 aliguori
    }
1734 6f97dba0 aliguori
1735 6f97dba0 aliguori
    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
1736 6f97dba0 aliguori
        fprintf(stderr, "Failed SetupComm\n");
1737 6f97dba0 aliguori
        goto fail;
1738 6f97dba0 aliguori
    }
1739 6f97dba0 aliguori
1740 6f97dba0 aliguori
    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
1741 6f97dba0 aliguori
    size = sizeof(COMMCONFIG);
1742 6f97dba0 aliguori
    GetDefaultCommConfig(filename, &comcfg, &size);
1743 6f97dba0 aliguori
    comcfg.dcb.DCBlength = sizeof(DCB);
1744 6f97dba0 aliguori
    CommConfigDialog(filename, NULL, &comcfg);
1745 6f97dba0 aliguori
1746 6f97dba0 aliguori
    if (!SetCommState(s->hcom, &comcfg.dcb)) {
1747 6f97dba0 aliguori
        fprintf(stderr, "Failed SetCommState\n");
1748 6f97dba0 aliguori
        goto fail;
1749 6f97dba0 aliguori
    }
1750 6f97dba0 aliguori
1751 6f97dba0 aliguori
    if (!SetCommMask(s->hcom, EV_ERR)) {
1752 6f97dba0 aliguori
        fprintf(stderr, "Failed SetCommMask\n");
1753 6f97dba0 aliguori
        goto fail;
1754 6f97dba0 aliguori
    }
1755 6f97dba0 aliguori
1756 6f97dba0 aliguori
    cto.ReadIntervalTimeout = MAXDWORD;
1757 6f97dba0 aliguori
    if (!SetCommTimeouts(s->hcom, &cto)) {
1758 6f97dba0 aliguori
        fprintf(stderr, "Failed SetCommTimeouts\n");
1759 6f97dba0 aliguori
        goto fail;
1760 6f97dba0 aliguori
    }
1761 6f97dba0 aliguori
1762 6f97dba0 aliguori
    if (!ClearCommError(s->hcom, &err, &comstat)) {
1763 6f97dba0 aliguori
        fprintf(stderr, "Failed ClearCommError\n");
1764 6f97dba0 aliguori
        goto fail;
1765 6f97dba0 aliguori
    }
1766 6f97dba0 aliguori
    qemu_add_polling_cb(win_chr_poll, chr);
1767 6f97dba0 aliguori
    return 0;
1768 6f97dba0 aliguori
1769 6f97dba0 aliguori
 fail:
1770 6f97dba0 aliguori
    win_chr_close(chr);
1771 6f97dba0 aliguori
    return -1;
1772 6f97dba0 aliguori
}
1773 6f97dba0 aliguori
1774 6f97dba0 aliguori
static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
1775 6f97dba0 aliguori
{
1776 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1777 6f97dba0 aliguori
    DWORD len, ret, size, err;
1778 6f97dba0 aliguori
1779 6f97dba0 aliguori
    len = len1;
1780 6f97dba0 aliguori
    ZeroMemory(&s->osend, sizeof(s->osend));
1781 6f97dba0 aliguori
    s->osend.hEvent = s->hsend;
1782 6f97dba0 aliguori
    while (len > 0) {
1783 6f97dba0 aliguori
        if (s->hsend)
1784 6f97dba0 aliguori
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
1785 6f97dba0 aliguori
        else
1786 6f97dba0 aliguori
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
1787 6f97dba0 aliguori
        if (!ret) {
1788 6f97dba0 aliguori
            err = GetLastError();
1789 6f97dba0 aliguori
            if (err == ERROR_IO_PENDING) {
1790 6f97dba0 aliguori
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
1791 6f97dba0 aliguori
                if (ret) {
1792 6f97dba0 aliguori
                    buf += size;
1793 6f97dba0 aliguori
                    len -= size;
1794 6f97dba0 aliguori
                } else {
1795 6f97dba0 aliguori
                    break;
1796 6f97dba0 aliguori
                }
1797 6f97dba0 aliguori
            } else {
1798 6f97dba0 aliguori
                break;
1799 6f97dba0 aliguori
            }
1800 6f97dba0 aliguori
        } else {
1801 6f97dba0 aliguori
            buf += size;
1802 6f97dba0 aliguori
            len -= size;
1803 6f97dba0 aliguori
        }
1804 6f97dba0 aliguori
    }
1805 6f97dba0 aliguori
    return len1 - len;
1806 6f97dba0 aliguori
}
1807 6f97dba0 aliguori
1808 6f97dba0 aliguori
static int win_chr_read_poll(CharDriverState *chr)
1809 6f97dba0 aliguori
{
1810 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1811 6f97dba0 aliguori
1812 909cda12 Anthony Liguori
    s->max_size = qemu_chr_be_can_write(chr);
1813 6f97dba0 aliguori
    return s->max_size;
1814 6f97dba0 aliguori
}
1815 6f97dba0 aliguori
1816 6f97dba0 aliguori
static void win_chr_readfile(CharDriverState *chr)
1817 6f97dba0 aliguori
{
1818 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1819 6f97dba0 aliguori
    int ret, err;
1820 9bd7854e Amit Shah
    uint8_t buf[READ_BUF_LEN];
1821 6f97dba0 aliguori
    DWORD size;
1822 6f97dba0 aliguori
1823 6f97dba0 aliguori
    ZeroMemory(&s->orecv, sizeof(s->orecv));
1824 6f97dba0 aliguori
    s->orecv.hEvent = s->hrecv;
1825 6f97dba0 aliguori
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
1826 6f97dba0 aliguori
    if (!ret) {
1827 6f97dba0 aliguori
        err = GetLastError();
1828 6f97dba0 aliguori
        if (err == ERROR_IO_PENDING) {
1829 6f97dba0 aliguori
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
1830 6f97dba0 aliguori
        }
1831 6f97dba0 aliguori
    }
1832 6f97dba0 aliguori
1833 6f97dba0 aliguori
    if (size > 0) {
1834 fa5efccb Anthony Liguori
        qemu_chr_be_write(chr, buf, size);
1835 6f97dba0 aliguori
    }
1836 6f97dba0 aliguori
}
1837 6f97dba0 aliguori
1838 6f97dba0 aliguori
static void win_chr_read(CharDriverState *chr)
1839 6f97dba0 aliguori
{
1840 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1841 6f97dba0 aliguori
1842 6f97dba0 aliguori
    if (s->len > s->max_size)
1843 6f97dba0 aliguori
        s->len = s->max_size;
1844 6f97dba0 aliguori
    if (s->len == 0)
1845 6f97dba0 aliguori
        return;
1846 6f97dba0 aliguori
1847 6f97dba0 aliguori
    win_chr_readfile(chr);
1848 6f97dba0 aliguori
}
1849 6f97dba0 aliguori
1850 6f97dba0 aliguori
static int win_chr_poll(void *opaque)
1851 6f97dba0 aliguori
{
1852 6f97dba0 aliguori
    CharDriverState *chr = opaque;
1853 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1854 6f97dba0 aliguori
    COMSTAT status;
1855 6f97dba0 aliguori
    DWORD comerr;
1856 6f97dba0 aliguori
1857 6f97dba0 aliguori
    ClearCommError(s->hcom, &comerr, &status);
1858 6f97dba0 aliguori
    if (status.cbInQue > 0) {
1859 6f97dba0 aliguori
        s->len = status.cbInQue;
1860 6f97dba0 aliguori
        win_chr_read_poll(chr);
1861 6f97dba0 aliguori
        win_chr_read(chr);
1862 6f97dba0 aliguori
        return 1;
1863 6f97dba0 aliguori
    }
1864 6f97dba0 aliguori
    return 0;
1865 6f97dba0 aliguori
}
1866 6f97dba0 aliguori
1867 d59044ef Gerd Hoffmann
static CharDriverState *qemu_chr_open_win_path(const char *filename)
1868 6f97dba0 aliguori
{
1869 6f97dba0 aliguori
    CharDriverState *chr;
1870 6f97dba0 aliguori
    WinCharState *s;
1871 6f97dba0 aliguori
1872 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
1873 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(WinCharState));
1874 6f97dba0 aliguori
    chr->opaque = s;
1875 6f97dba0 aliguori
    chr->chr_write = win_chr_write;
1876 6f97dba0 aliguori
    chr->chr_close = win_chr_close;
1877 6f97dba0 aliguori
1878 6f97dba0 aliguori
    if (win_chr_init(chr, filename) < 0) {
1879 2e02e18b Stefan Weil
        g_free(s);
1880 2e02e18b Stefan Weil
        g_free(chr);
1881 1f51470d Markus Armbruster
        return NULL;
1882 6f97dba0 aliguori
    }
1883 fee204fd Hans de Goede
    qemu_chr_be_generic_open(chr);
1884 1f51470d Markus Armbruster
    return chr;
1885 6f97dba0 aliguori
}
1886 6f97dba0 aliguori
1887 6f97dba0 aliguori
static int win_chr_pipe_poll(void *opaque)
1888 6f97dba0 aliguori
{
1889 6f97dba0 aliguori
    CharDriverState *chr = opaque;
1890 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1891 6f97dba0 aliguori
    DWORD size;
1892 6f97dba0 aliguori
1893 6f97dba0 aliguori
    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
1894 6f97dba0 aliguori
    if (size > 0) {
1895 6f97dba0 aliguori
        s->len = size;
1896 6f97dba0 aliguori
        win_chr_read_poll(chr);
1897 6f97dba0 aliguori
        win_chr_read(chr);
1898 6f97dba0 aliguori
        return 1;
1899 6f97dba0 aliguori
    }
1900 6f97dba0 aliguori
    return 0;
1901 6f97dba0 aliguori
}
1902 6f97dba0 aliguori
1903 6f97dba0 aliguori
static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
1904 6f97dba0 aliguori
{
1905 6f97dba0 aliguori
    WinCharState *s = chr->opaque;
1906 6f97dba0 aliguori
    OVERLAPPED ov;
1907 6f97dba0 aliguori
    int ret;
1908 6f97dba0 aliguori
    DWORD size;
1909 6f97dba0 aliguori
    char openname[256];
1910 6f97dba0 aliguori
1911 6f97dba0 aliguori
    s->fpipe = TRUE;
1912 6f97dba0 aliguori
1913 6f97dba0 aliguori
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1914 6f97dba0 aliguori
    if (!s->hsend) {
1915 6f97dba0 aliguori
        fprintf(stderr, "Failed CreateEvent\n");
1916 6f97dba0 aliguori
        goto fail;
1917 6f97dba0 aliguori
    }
1918 6f97dba0 aliguori
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1919 6f97dba0 aliguori
    if (!s->hrecv) {
1920 6f97dba0 aliguori
        fprintf(stderr, "Failed CreateEvent\n");
1921 6f97dba0 aliguori
        goto fail;
1922 6f97dba0 aliguori
    }
1923 6f97dba0 aliguori
1924 6f97dba0 aliguori
    snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
1925 6f97dba0 aliguori
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1926 6f97dba0 aliguori
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
1927 6f97dba0 aliguori
                              PIPE_WAIT,
1928 6f97dba0 aliguori
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
1929 6f97dba0 aliguori
    if (s->hcom == INVALID_HANDLE_VALUE) {
1930 6f97dba0 aliguori
        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
1931 6f97dba0 aliguori
        s->hcom = NULL;
1932 6f97dba0 aliguori
        goto fail;
1933 6f97dba0 aliguori
    }
1934 6f97dba0 aliguori
1935 6f97dba0 aliguori
    ZeroMemory(&ov, sizeof(ov));
1936 6f97dba0 aliguori
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1937 6f97dba0 aliguori
    ret = ConnectNamedPipe(s->hcom, &ov);
1938 6f97dba0 aliguori
    if (ret) {
1939 6f97dba0 aliguori
        fprintf(stderr, "Failed ConnectNamedPipe\n");
1940 6f97dba0 aliguori
        goto fail;
1941 6f97dba0 aliguori
    }
1942 6f97dba0 aliguori
1943 6f97dba0 aliguori
    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
1944 6f97dba0 aliguori
    if (!ret) {
1945 6f97dba0 aliguori
        fprintf(stderr, "Failed GetOverlappedResult\n");
1946 6f97dba0 aliguori
        if (ov.hEvent) {
1947 6f97dba0 aliguori
            CloseHandle(ov.hEvent);
1948 6f97dba0 aliguori
            ov.hEvent = NULL;
1949 6f97dba0 aliguori
        }
1950 6f97dba0 aliguori
        goto fail;
1951 6f97dba0 aliguori
    }
1952 6f97dba0 aliguori
1953 6f97dba0 aliguori
    if (ov.hEvent) {
1954 6f97dba0 aliguori
        CloseHandle(ov.hEvent);
1955 6f97dba0 aliguori
        ov.hEvent = NULL;
1956 6f97dba0 aliguori
    }
1957 6f97dba0 aliguori
    qemu_add_polling_cb(win_chr_pipe_poll, chr);
1958 6f97dba0 aliguori
    return 0;
1959 6f97dba0 aliguori
1960 6f97dba0 aliguori
 fail:
1961 6f97dba0 aliguori
    win_chr_close(chr);
1962 6f97dba0 aliguori
    return -1;
1963 6f97dba0 aliguori
}
1964 6f97dba0 aliguori
1965 6f97dba0 aliguori
1966 548cbb36 Gerd Hoffmann
static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
1967 6f97dba0 aliguori
{
1968 548cbb36 Gerd Hoffmann
    const char *filename = opts->device;
1969 6f97dba0 aliguori
    CharDriverState *chr;
1970 6f97dba0 aliguori
    WinCharState *s;
1971 6f97dba0 aliguori
1972 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
1973 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(WinCharState));
1974 6f97dba0 aliguori
    chr->opaque = s;
1975 6f97dba0 aliguori
    chr->chr_write = win_chr_write;
1976 6f97dba0 aliguori
    chr->chr_close = win_chr_close;
1977 6f97dba0 aliguori
1978 6f97dba0 aliguori
    if (win_chr_pipe_init(chr, filename) < 0) {
1979 2e02e18b Stefan Weil
        g_free(s);
1980 2e02e18b Stefan Weil
        g_free(chr);
1981 1f51470d Markus Armbruster
        return NULL;
1982 6f97dba0 aliguori
    }
1983 fee204fd Hans de Goede
    qemu_chr_be_generic_open(chr);
1984 1f51470d Markus Armbruster
    return chr;
1985 6f97dba0 aliguori
}
1986 6f97dba0 aliguori
1987 1f51470d Markus Armbruster
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
1988 6f97dba0 aliguori
{
1989 6f97dba0 aliguori
    CharDriverState *chr;
1990 6f97dba0 aliguori
    WinCharState *s;
1991 6f97dba0 aliguori
1992 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
1993 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(WinCharState));
1994 6f97dba0 aliguori
    s->hcom = fd_out;
1995 6f97dba0 aliguori
    chr->opaque = s;
1996 6f97dba0 aliguori
    chr->chr_write = win_chr_write;
1997 fee204fd Hans de Goede
    qemu_chr_be_generic_open(chr);
1998 1f51470d Markus Armbruster
    return chr;
1999 6f97dba0 aliguori
}
2000 6f97dba0 aliguori
2001 d9ac374f Gerd Hoffmann
static CharDriverState *qemu_chr_open_win_con(void)
2002 6f97dba0 aliguori
{
2003 1f51470d Markus Armbruster
    return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
2004 6f97dba0 aliguori
}
2005 6f97dba0 aliguori
2006 db418a0a Fabien Chouteau
static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
2007 db418a0a Fabien Chouteau
{
2008 db418a0a Fabien Chouteau
    HANDLE  hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
2009 db418a0a Fabien Chouteau
    DWORD   dwSize;
2010 db418a0a Fabien Chouteau
    int     len1;
2011 db418a0a Fabien Chouteau
2012 db418a0a Fabien Chouteau
    len1 = len;
2013 db418a0a Fabien Chouteau
2014 db418a0a Fabien Chouteau
    while (len1 > 0) {
2015 db418a0a Fabien Chouteau
        if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
2016 db418a0a Fabien Chouteau
            break;
2017 db418a0a Fabien Chouteau
        }
2018 db418a0a Fabien Chouteau
        buf  += dwSize;
2019 db418a0a Fabien Chouteau
        len1 -= dwSize;
2020 db418a0a Fabien Chouteau
    }
2021 db418a0a Fabien Chouteau
2022 db418a0a Fabien Chouteau
    return len - len1;
2023 db418a0a Fabien Chouteau
}
2024 db418a0a Fabien Chouteau
2025 db418a0a Fabien Chouteau
static void win_stdio_wait_func(void *opaque)
2026 db418a0a Fabien Chouteau
{
2027 db418a0a Fabien Chouteau
    CharDriverState   *chr   = opaque;
2028 db418a0a Fabien Chouteau
    WinStdioCharState *stdio = chr->opaque;
2029 db418a0a Fabien Chouteau
    INPUT_RECORD       buf[4];
2030 db418a0a Fabien Chouteau
    int                ret;
2031 db418a0a Fabien Chouteau
    DWORD              dwSize;
2032 db418a0a Fabien Chouteau
    int                i;
2033 db418a0a Fabien Chouteau
2034 db418a0a Fabien Chouteau
    ret = ReadConsoleInput(stdio->hStdIn, buf, sizeof(buf) / sizeof(*buf),
2035 db418a0a Fabien Chouteau
                           &dwSize);
2036 db418a0a Fabien Chouteau
2037 db418a0a Fabien Chouteau
    if (!ret) {
2038 db418a0a Fabien Chouteau
        /* Avoid error storm */
2039 db418a0a Fabien Chouteau
        qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
2040 db418a0a Fabien Chouteau
        return;
2041 db418a0a Fabien Chouteau
    }
2042 db418a0a Fabien Chouteau
2043 db418a0a Fabien Chouteau
    for (i = 0; i < dwSize; i++) {
2044 db418a0a Fabien Chouteau
        KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;
2045 db418a0a Fabien Chouteau
2046 db418a0a Fabien Chouteau
        if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
2047 db418a0a Fabien Chouteau
            int j;
2048 db418a0a Fabien Chouteau
            if (kev->uChar.AsciiChar != 0) {
2049 db418a0a Fabien Chouteau
                for (j = 0; j < kev->wRepeatCount; j++) {
2050 db418a0a Fabien Chouteau
                    if (qemu_chr_be_can_write(chr)) {
2051 db418a0a Fabien Chouteau
                        uint8_t c = kev->uChar.AsciiChar;
2052 db418a0a Fabien Chouteau
                        qemu_chr_be_write(chr, &c, 1);
2053 db418a0a Fabien Chouteau
                    }
2054 db418a0a Fabien Chouteau
                }
2055 db418a0a Fabien Chouteau
            }
2056 db418a0a Fabien Chouteau
        }
2057 db418a0a Fabien Chouteau
    }
2058 db418a0a Fabien Chouteau
}
2059 db418a0a Fabien Chouteau
2060 db418a0a Fabien Chouteau
static DWORD WINAPI win_stdio_thread(LPVOID param)
2061 db418a0a Fabien Chouteau
{
2062 db418a0a Fabien Chouteau
    CharDriverState   *chr   = param;
2063 db418a0a Fabien Chouteau
    WinStdioCharState *stdio = chr->opaque;
2064 db418a0a Fabien Chouteau
    int                ret;
2065 db418a0a Fabien Chouteau
    DWORD              dwSize;
2066 db418a0a Fabien Chouteau
2067 db418a0a Fabien Chouteau
    while (1) {
2068 db418a0a Fabien Chouteau
2069 db418a0a Fabien Chouteau
        /* Wait for one byte */
2070 db418a0a Fabien Chouteau
        ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);
2071 db418a0a Fabien Chouteau
2072 db418a0a Fabien Chouteau
        /* Exit in case of error, continue if nothing read */
2073 db418a0a Fabien Chouteau
        if (!ret) {
2074 db418a0a Fabien Chouteau
            break;
2075 db418a0a Fabien Chouteau
        }
2076 db418a0a Fabien Chouteau
        if (!dwSize) {
2077 db418a0a Fabien Chouteau
            continue;
2078 db418a0a Fabien Chouteau
        }
2079 db418a0a Fabien Chouteau
2080 db418a0a Fabien Chouteau
        /* Some terminal emulator returns \r\n for Enter, just pass \n */
2081 db418a0a Fabien Chouteau
        if (stdio->win_stdio_buf == '\r') {
2082 db418a0a Fabien Chouteau
            continue;
2083 db418a0a Fabien Chouteau
        }
2084 db418a0a Fabien Chouteau
2085 db418a0a Fabien Chouteau
        /* Signal the main thread and wait until the byte was eaten */
2086 db418a0a Fabien Chouteau
        if (!SetEvent(stdio->hInputReadyEvent)) {
2087 db418a0a Fabien Chouteau
            break;
2088 db418a0a Fabien Chouteau
        }
2089 db418a0a Fabien Chouteau
        if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
2090 db418a0a Fabien Chouteau
            != WAIT_OBJECT_0) {
2091 db418a0a Fabien Chouteau
            break;
2092 db418a0a Fabien Chouteau
        }
2093 db418a0a Fabien Chouteau
    }
2094 db418a0a Fabien Chouteau
2095 db418a0a Fabien Chouteau
    qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
2096 db418a0a Fabien Chouteau
    return 0;
2097 db418a0a Fabien Chouteau
}
2098 db418a0a Fabien Chouteau
2099 db418a0a Fabien Chouteau
static void win_stdio_thread_wait_func(void *opaque)
2100 db418a0a Fabien Chouteau
{
2101 db418a0a Fabien Chouteau
    CharDriverState   *chr   = opaque;
2102 db418a0a Fabien Chouteau
    WinStdioCharState *stdio = chr->opaque;
2103 db418a0a Fabien Chouteau
2104 db418a0a Fabien Chouteau
    if (qemu_chr_be_can_write(chr)) {
2105 db418a0a Fabien Chouteau
        qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
2106 db418a0a Fabien Chouteau
    }
2107 db418a0a Fabien Chouteau
2108 db418a0a Fabien Chouteau
    SetEvent(stdio->hInputDoneEvent);
2109 db418a0a Fabien Chouteau
}
2110 db418a0a Fabien Chouteau
2111 db418a0a Fabien Chouteau
static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo)
2112 db418a0a Fabien Chouteau
{
2113 db418a0a Fabien Chouteau
    WinStdioCharState *stdio  = chr->opaque;
2114 db418a0a Fabien Chouteau
    DWORD              dwMode = 0;
2115 db418a0a Fabien Chouteau
2116 db418a0a Fabien Chouteau
    GetConsoleMode(stdio->hStdIn, &dwMode);
2117 db418a0a Fabien Chouteau
2118 db418a0a Fabien Chouteau
    if (echo) {
2119 db418a0a Fabien Chouteau
        SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
2120 db418a0a Fabien Chouteau
    } else {
2121 db418a0a Fabien Chouteau
        SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
2122 db418a0a Fabien Chouteau
    }
2123 db418a0a Fabien Chouteau
}
2124 db418a0a Fabien Chouteau
2125 db418a0a Fabien Chouteau
static void win_stdio_close(CharDriverState *chr)
2126 db418a0a Fabien Chouteau
{
2127 db418a0a Fabien Chouteau
    WinStdioCharState *stdio = chr->opaque;
2128 db418a0a Fabien Chouteau
2129 db418a0a Fabien Chouteau
    if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
2130 db418a0a Fabien Chouteau
        CloseHandle(stdio->hInputReadyEvent);
2131 db418a0a Fabien Chouteau
    }
2132 db418a0a Fabien Chouteau
    if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
2133 db418a0a Fabien Chouteau
        CloseHandle(stdio->hInputDoneEvent);
2134 db418a0a Fabien Chouteau
    }
2135 db418a0a Fabien Chouteau
    if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
2136 db418a0a Fabien Chouteau
        TerminateThread(stdio->hInputThread, 0);
2137 db418a0a Fabien Chouteau
    }
2138 db418a0a Fabien Chouteau
2139 db418a0a Fabien Chouteau
    g_free(chr->opaque);
2140 db418a0a Fabien Chouteau
    g_free(chr);
2141 db418a0a Fabien Chouteau
}
2142 db418a0a Fabien Chouteau
2143 7c358031 Gerd Hoffmann
static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
2144 db418a0a Fabien Chouteau
{
2145 db418a0a Fabien Chouteau
    CharDriverState   *chr;
2146 db418a0a Fabien Chouteau
    WinStdioCharState *stdio;
2147 db418a0a Fabien Chouteau
    DWORD              dwMode;
2148 db418a0a Fabien Chouteau
    int                is_console = 0;
2149 db418a0a Fabien Chouteau
2150 db418a0a Fabien Chouteau
    chr   = g_malloc0(sizeof(CharDriverState));
2151 db418a0a Fabien Chouteau
    stdio = g_malloc0(sizeof(WinStdioCharState));
2152 db418a0a Fabien Chouteau
2153 db418a0a Fabien Chouteau
    stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
2154 db418a0a Fabien Chouteau
    if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
2155 db418a0a Fabien Chouteau
        fprintf(stderr, "cannot open stdio: invalid handle\n");
2156 db418a0a Fabien Chouteau
        exit(1);
2157 db418a0a Fabien Chouteau
    }
2158 db418a0a Fabien Chouteau
2159 db418a0a Fabien Chouteau
    is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
2160 db418a0a Fabien Chouteau
2161 db418a0a Fabien Chouteau
    chr->opaque    = stdio;
2162 db418a0a Fabien Chouteau
    chr->chr_write = win_stdio_write;
2163 db418a0a Fabien Chouteau
    chr->chr_close = win_stdio_close;
2164 db418a0a Fabien Chouteau
2165 ed7a1540 Anthony Liguori
    if (is_console) {
2166 ed7a1540 Anthony Liguori
        if (qemu_add_wait_object(stdio->hStdIn,
2167 ed7a1540 Anthony Liguori
                                 win_stdio_wait_func, chr)) {
2168 ed7a1540 Anthony Liguori
            fprintf(stderr, "qemu_add_wait_object: failed\n");
2169 ed7a1540 Anthony Liguori
        }
2170 ed7a1540 Anthony Liguori
    } else {
2171 ed7a1540 Anthony Liguori
        DWORD   dwId;
2172 ed7a1540 Anthony Liguori
            
2173 ed7a1540 Anthony Liguori
        stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2174 ed7a1540 Anthony Liguori
        stdio->hInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
2175 ed7a1540 Anthony Liguori
        stdio->hInputThread     = CreateThread(NULL, 0, win_stdio_thread,
2176 ed7a1540 Anthony Liguori
                                               chr, 0, &dwId);
2177 ed7a1540 Anthony Liguori
2178 ed7a1540 Anthony Liguori
        if (stdio->hInputThread == INVALID_HANDLE_VALUE
2179 ed7a1540 Anthony Liguori
            || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
2180 ed7a1540 Anthony Liguori
            || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
2181 ed7a1540 Anthony Liguori
            fprintf(stderr, "cannot create stdio thread or event\n");
2182 ed7a1540 Anthony Liguori
            exit(1);
2183 ed7a1540 Anthony Liguori
        }
2184 ed7a1540 Anthony Liguori
        if (qemu_add_wait_object(stdio->hInputReadyEvent,
2185 ed7a1540 Anthony Liguori
                                 win_stdio_thread_wait_func, chr)) {
2186 ed7a1540 Anthony Liguori
            fprintf(stderr, "qemu_add_wait_object: failed\n");
2187 db418a0a Fabien Chouteau
        }
2188 db418a0a Fabien Chouteau
    }
2189 db418a0a Fabien Chouteau
2190 db418a0a Fabien Chouteau
    dwMode |= ENABLE_LINE_INPUT;
2191 db418a0a Fabien Chouteau
2192 ed7a1540 Anthony Liguori
    if (is_console) {
2193 db418a0a Fabien Chouteau
        /* set the terminal in raw mode */
2194 db418a0a Fabien Chouteau
        /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
2195 db418a0a Fabien Chouteau
        dwMode |= ENABLE_PROCESSED_INPUT;
2196 db418a0a Fabien Chouteau
    }
2197 db418a0a Fabien Chouteau
2198 db418a0a Fabien Chouteau
    SetConsoleMode(stdio->hStdIn, dwMode);
2199 db418a0a Fabien Chouteau
2200 db418a0a Fabien Chouteau
    chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
2201 db418a0a Fabien Chouteau
    qemu_chr_fe_set_echo(chr, false);
2202 db418a0a Fabien Chouteau
2203 1f51470d Markus Armbruster
    return chr;
2204 db418a0a Fabien Chouteau
}
2205 6f97dba0 aliguori
#endif /* !_WIN32 */
2206 6f97dba0 aliguori
2207 5ab8211b Anthony Liguori
2208 6f97dba0 aliguori
/***********************************************************/
2209 6f97dba0 aliguori
/* UDP Net console */
2210 6f97dba0 aliguori
2211 6f97dba0 aliguori
typedef struct {
2212 6f97dba0 aliguori
    int fd;
2213 76a9644b Anthony Liguori
    GIOChannel *chan;
2214 76a9644b Anthony Liguori
    guint tag;
2215 9bd7854e Amit Shah
    uint8_t buf[READ_BUF_LEN];
2216 6f97dba0 aliguori
    int bufcnt;
2217 6f97dba0 aliguori
    int bufptr;
2218 6f97dba0 aliguori
    int max_size;
2219 6f97dba0 aliguori
} NetCharDriver;
2220 6f97dba0 aliguori
2221 6f97dba0 aliguori
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2222 6f97dba0 aliguori
{
2223 6f97dba0 aliguori
    NetCharDriver *s = chr->opaque;
2224 76a9644b Anthony Liguori
    gsize bytes_written;
2225 76a9644b Anthony Liguori
    GIOStatus status;
2226 76a9644b Anthony Liguori
2227 76a9644b Anthony Liguori
    status = g_io_channel_write_chars(s->chan, (const gchar *)buf, len, &bytes_written, NULL);
2228 76a9644b Anthony Liguori
    if (status == G_IO_STATUS_EOF) {
2229 76a9644b Anthony Liguori
        return 0;
2230 76a9644b Anthony Liguori
    } else if (status != G_IO_STATUS_NORMAL) {
2231 76a9644b Anthony Liguori
        return -1;
2232 76a9644b Anthony Liguori
    }
2233 6f97dba0 aliguori
2234 76a9644b Anthony Liguori
    return bytes_written;
2235 6f97dba0 aliguori
}
2236 6f97dba0 aliguori
2237 6f97dba0 aliguori
static int udp_chr_read_poll(void *opaque)
2238 6f97dba0 aliguori
{
2239 6f97dba0 aliguori
    CharDriverState *chr = opaque;
2240 6f97dba0 aliguori
    NetCharDriver *s = chr->opaque;
2241 6f97dba0 aliguori
2242 909cda12 Anthony Liguori
    s->max_size = qemu_chr_be_can_write(chr);
2243 6f97dba0 aliguori
2244 6f97dba0 aliguori
    /* If there were any stray characters in the queue process them
2245 6f97dba0 aliguori
     * first
2246 6f97dba0 aliguori
     */
2247 6f97dba0 aliguori
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2248 fa5efccb Anthony Liguori
        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
2249 6f97dba0 aliguori
        s->bufptr++;
2250 909cda12 Anthony Liguori
        s->max_size = qemu_chr_be_can_write(chr);
2251 6f97dba0 aliguori
    }
2252 6f97dba0 aliguori
    return s->max_size;
2253 6f97dba0 aliguori
}
2254 6f97dba0 aliguori
2255 76a9644b Anthony Liguori
static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
2256 6f97dba0 aliguori
{
2257 6f97dba0 aliguori
    CharDriverState *chr = opaque;
2258 6f97dba0 aliguori
    NetCharDriver *s = chr->opaque;
2259 76a9644b Anthony Liguori
    gsize bytes_read = 0;
2260 76a9644b Anthony Liguori
    GIOStatus status;
2261 6f97dba0 aliguori
2262 cdbf6e16 Paolo Bonzini
    if (s->max_size == 0) {
2263 cdbf6e16 Paolo Bonzini
        return TRUE;
2264 cdbf6e16 Paolo Bonzini
    }
2265 76a9644b Anthony Liguori
    status = g_io_channel_read_chars(s->chan, (gchar *)s->buf, sizeof(s->buf),
2266 76a9644b Anthony Liguori
                                     &bytes_read, NULL);
2267 76a9644b Anthony Liguori
    s->bufcnt = bytes_read;
2268 6f97dba0 aliguori
    s->bufptr = s->bufcnt;
2269 76a9644b Anthony Liguori
    if (status != G_IO_STATUS_NORMAL) {
2270 cdbf6e16 Paolo Bonzini
        if (s->tag) {
2271 2b316774 Paolo Bonzini
            io_remove_watch_poll(s->tag);
2272 cdbf6e16 Paolo Bonzini
            s->tag = 0;
2273 cdbf6e16 Paolo Bonzini
        }
2274 76a9644b Anthony Liguori
        return FALSE;
2275 76a9644b Anthony Liguori
    }
2276 6f97dba0 aliguori
2277 6f97dba0 aliguori
    s->bufptr = 0;
2278 6f97dba0 aliguori
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2279 fa5efccb Anthony Liguori
        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
2280 6f97dba0 aliguori
        s->bufptr++;
2281 909cda12 Anthony Liguori
        s->max_size = qemu_chr_be_can_write(chr);
2282 6f97dba0 aliguori
    }
2283 76a9644b Anthony Liguori
2284 76a9644b Anthony Liguori
    return TRUE;
2285 6f97dba0 aliguori
}
2286 6f97dba0 aliguori
2287 6f97dba0 aliguori
static void udp_chr_update_read_handler(CharDriverState *chr)
2288 6f97dba0 aliguori
{
2289 6f97dba0 aliguori
    NetCharDriver *s = chr->opaque;
2290 6f97dba0 aliguori
2291 76a9644b Anthony Liguori
    if (s->tag) {
2292 2b316774 Paolo Bonzini
        io_remove_watch_poll(s->tag);
2293 76a9644b Anthony Liguori
        s->tag = 0;
2294 76a9644b Anthony Liguori
    }
2295 76a9644b Anthony Liguori
2296 76a9644b Anthony Liguori
    if (s->chan) {
2297 76a9644b Anthony Liguori
        s->tag = io_add_watch_poll(s->chan, udp_chr_read_poll, udp_chr_read, chr);
2298 6f97dba0 aliguori
    }
2299 6f97dba0 aliguori
}
2300 6f97dba0 aliguori
2301 819f56b7 aliguori
static void udp_chr_close(CharDriverState *chr)
2302 819f56b7 aliguori
{
2303 819f56b7 aliguori
    NetCharDriver *s = chr->opaque;
2304 76a9644b Anthony Liguori
    if (s->tag) {
2305 2b316774 Paolo Bonzini
        io_remove_watch_poll(s->tag);
2306 910b6368 Paolo Bonzini
        s->tag = 0;
2307 76a9644b Anthony Liguori
    }
2308 76a9644b Anthony Liguori
    if (s->chan) {
2309 76a9644b Anthony Liguori
        g_io_channel_unref(s->chan);
2310 819f56b7 aliguori
        closesocket(s->fd);
2311 819f56b7 aliguori
    }
2312 7267c094 Anthony Liguori
    g_free(s);
2313 a425d23f Hans de Goede
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
2314 819f56b7 aliguori
}
2315 819f56b7 aliguori
2316 3ecc059d Gerd Hoffmann
static CharDriverState *qemu_chr_open_udp_fd(int fd)
2317 6f97dba0 aliguori
{
2318 6f97dba0 aliguori
    CharDriverState *chr = NULL;
2319 6f97dba0 aliguori
    NetCharDriver *s = NULL;
2320 6f97dba0 aliguori
2321 7267c094 Anthony Liguori
    chr = g_malloc0(sizeof(CharDriverState));
2322 7267c094 Anthony Liguori
    s = g_malloc0(sizeof(NetCharDriver));
2323 6f97dba0 aliguori
2324 6f97dba0 aliguori
    s->fd = fd;
2325 76a9644b Anthony Liguori
    s->chan = io_channel_from_socket(s->fd);
2326 6f97dba0 aliguori
    s->bufcnt = 0;
2327 6f97dba0 aliguori
    s->bufptr = 0;
2328 6f97dba0 aliguori
    chr->opaque = s;
2329 6f97dba0 aliguori
    chr->chr_write = udp_chr_write;
2330 6f97dba0 aliguori
    chr->chr_update_read_handler = udp_chr_update_read_handler;
2331 819f56b7 aliguori
    chr->chr_close = udp_chr_close;
2332 1f51470d Markus Armbruster
    return chr;
2333 3ecc059d Gerd Hoffmann
}
2334 6f97dba0 aliguori
2335 3ecc059d Gerd Hoffmann
static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
2336 3ecc059d Gerd Hoffmann
{
2337 3ecc059d Gerd Hoffmann
    Error *local_err = NULL;
2338 3ecc059d Gerd Hoffmann
    int fd = -1;
2339 3ecc059d Gerd Hoffmann
2340 3ecc059d Gerd Hoffmann
    fd = inet_dgram_opts(opts, &local_err);
2341 3ecc059d Gerd Hoffmann
    if (fd < 0) {
2342 3ecc059d Gerd Hoffmann
        return NULL;
2343 6e1db57b Kevin Wolf
    }
2344 3ecc059d Gerd Hoffmann
    return qemu_chr_open_udp_fd(fd);
2345 6f97dba0 aliguori
}
2346 6f97dba0 aliguori
2347 6f97dba0 aliguori
/***********************************************************/
2348 6f97dba0 aliguori
/* TCP Net console */
2349 6f97dba0 aliguori
2350 6f97dba0 aliguori
typedef struct {
2351 2ea5a7af Anthony Liguori
2352 2ea5a7af Anthony Liguori
    GIOChannel *chan, *listen_chan;
2353 2ea5a7af Anthony Liguori
    guint tag, listen_tag;
2354 6f97dba0 aliguori
    int fd, listen_fd;
2355 6f97dba0 aliguori
    int connected;
2356 6f97dba0 aliguori
    int max_size;
2357 6f97dba0 aliguori
    int do_telnetopt;
2358 6f97dba0 aliguori
    int do_nodelay;
2359 6f97dba0 aliguori
    int is_unix;
2360 7d174059 Mark McLoughlin
    int msgfd;
2361 6f97dba0 aliguori
} TCPCharDriver;
2362 6f97dba0 aliguori
2363 2ea5a7af Anthony Liguori
static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
2364 6f97dba0 aliguori
2365 6f97dba0 aliguori
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2366 6f97dba0 aliguori
{
2367 6f97dba0 aliguori
    TCPCharDriver *s = chr->opaque;
2368 6f97dba0 aliguori
    if (s->connected) {
2369 684a096e Anthony Liguori
        return io_channel_send(s->chan, buf, len);
2370 455aa1e0 Anthony Liguori
    } else {
2371 6db0fdce Anthony Liguori
        /* XXX: indicate an error ? */
2372 455aa1e0 Anthony Liguori
        return len;
2373 6f97dba0 aliguori
    }
2374 6f97dba0 aliguori
}
2375 6f97dba0 aliguori
2376 6f97dba0 aliguori
static int tcp_chr_read_poll(void *opaque)
2377 6f97dba0 aliguori
{
2378 6f97dba0 aliguori
    CharDriverState *chr = opaque;
2379 6f97dba0 aliguori
    TCPCharDriver *s = chr->opaque;
2380 6f97dba0 aliguori
    if (!s->connected)
2381 6f97dba0 aliguori
        return 0;
2382 909cda12 Anthony Liguori
    s->max_size = qemu_chr_be_can_write(chr);
2383 6f97dba0 aliguori
    return s->max_size;
2384 6f97dba0 aliguori
}
2385 6f97dba0 aliguori
2386 6f97dba0 aliguori
#define IAC 255
2387 6f97dba0 aliguori
#define IAC_BREAK 243
2388 6f97dba0 aliguori
static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
2389 6f97dba0 aliguori
                                      TCPCharDriver *s,
2390 6f97dba0 aliguori
                                      uint8_t *buf, int *size)
2391 6f97dba0 aliguori
{
2392 6f97dba0 aliguori
    /* Handle any telnet client's basic IAC options to satisfy char by
2393 6f97dba0 aliguori
     * char mode with no echo.  All IAC options will be removed from
2394 6f97dba0 aliguori
     * the buf and the do_telnetopt variable will be used to track the
2395 6f97dba0 aliguori
     * state of the width of the IAC information.
2396 6f97dba0 aliguori
     *
2397 6f97dba0 aliguori
     * IAC commands come in sets of 3 bytes with the exception of the
2398 6f97dba0 aliguori
     * "IAC BREAK" command and the double IAC.
2399 6f97dba0 aliguori
     */
2400 6f97dba0 aliguori
2401 6f97dba0 aliguori
    int i;
2402 6f97dba0 aliguori
    int j = 0;
2403 6f97dba0 aliguori
2404 6f97dba0 aliguori
    for (i = 0; i < *size; i++) {
2405 6f97dba0 aliguori
        if (s->do_telnetopt > 1) {
2406 6f97dba0 aliguori
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
2407 6f97dba0 aliguori
                /* Double IAC means send an IAC */
2408 6f97dba0 aliguori
                if (j != i)
2409 6f97dba0 aliguori
                    buf[j] = buf[i];
2410 6f97dba0 aliguori
                j++;
2411 6f97dba0 aliguori
                s->do_telnetopt = 1;
2412 6f97dba0 aliguori
            } else {
2413 6f97dba0 aliguori
                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
2414 6f97dba0 aliguori
                    /* Handle IAC break commands by sending a serial break */
2415 a425d23f Hans de Goede
                    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
2416 6f97dba0 aliguori
                    s->do_telnetopt++;
2417 6f97dba0 aliguori
                }
2418 6f97dba0 aliguori
                s->do_telnetopt++;
2419 6f97dba0 aliguori
            }
2420 6f97dba0 aliguori
            if (s->do_telnetopt >= 4) {
2421 6f97dba0 aliguori
                s->do_telnetopt = 1;
2422 6f97dba0 aliguori
            }
2423 6f97dba0 aliguori
        } else {
2424 6f97dba0 aliguori
            if ((unsigned char)buf[i] == IAC) {
2425 6f97dba0 aliguori
                s->do_telnetopt = 2;
2426 6f97dba0 aliguori
            } else {
2427 6f97dba0 aliguori
                if (j != i)
2428 6f97dba0 aliguori
                    buf[j] = buf[i];
2429 6f97dba0 aliguori
                j++;
2430 6f97dba0 aliguori
            }
2431 6f97dba0 aliguori
        }
2432 6f97dba0 aliguori
    }
2433 6f97dba0 aliguori
    *size = j;
2434 6f97dba0 aliguori
}
2435 6f97dba0 aliguori
2436 7d174059 Mark McLoughlin
static int tcp_get_msgfd(CharDriverState *chr)
2437 7d174059 Mark McLoughlin
{
2438 7d174059 Mark McLoughlin
    TCPCharDriver *s = chr->opaque;
2439 e53f27b9 Paolo Bonzini
    int fd = s->msgfd;
2440 e53f27b9 Paolo Bonzini
    s->msgfd = -1;
2441 e53f27b9 Paolo Bonzini
    return fd;
2442 7d174059 Mark McLoughlin
}
2443 7d174059 Mark McLoughlin
2444 73bcc2ac Anthony Liguori
#ifndef _WIN32
2445 7d174059 Mark McLoughlin
static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
2446 7d174059 Mark McLoughlin
{
2447 7d174059 Mark McLoughlin
    TCPCharDriver *s = chr->opaque;
2448 7d174059 Mark McLoughlin
    struct cmsghdr *cmsg;
2449 7d174059 Mark McLoughlin
2450 7d174059 Mark McLoughlin
    for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
2451 7d174059 Mark McLoughlin
        int fd;
2452 7d174059 Mark McLoughlin
2453 7d174059 Mark McLoughlin
        if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
2454 7d174059 Mark McLoughlin
            cmsg->cmsg_level != SOL_SOCKET ||
2455 7d174059 Mark McLoughlin
            cmsg->cmsg_type != SCM_RIGHTS)
2456 7d174059 Mark McLoughlin
            continue;
2457 7d174059 Mark McLoughlin
2458 7d174059 Mark McLoughlin
        fd = *((int *)CMSG_DATA(cmsg));
2459 7d174059 Mark McLoughlin
        if (fd < 0)
2460 7d174059 Mark McLoughlin
            continue;
2461 7d174059 Mark McLoughlin
2462 9b938c72 Stefan Hajnoczi
        /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
2463 9b938c72 Stefan Hajnoczi
        qemu_set_block(fd);
2464 9b938c72 Stefan Hajnoczi
2465 06138651 Corey Bryant
#ifndef MSG_CMSG_CLOEXEC
2466 06138651 Corey Bryant
        qemu_set_cloexec(fd);
2467 06138651 Corey Bryant
#endif
2468 7d174059 Mark McLoughlin
        if (s->msgfd != -1)
2469 7d174059 Mark McLoughlin
            close(s->msgfd);
2470 7d174059 Mark McLoughlin
        s->msgfd = fd;
2471 7d174059 Mark McLoughlin
    }
2472 7d174059 Mark McLoughlin
}
2473 7d174059 Mark McLoughlin
2474 9977c894 Mark McLoughlin
static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2475 9977c894 Mark McLoughlin
{
2476 9977c894 Mark McLoughlin
    TCPCharDriver *s = chr->opaque;
2477 7cba04f6 Blue Swirl
    struct msghdr msg = { NULL, };
2478 9977c894 Mark McLoughlin
    struct iovec iov[1];
2479 7d174059 Mark McLoughlin
    union {
2480 7d174059 Mark McLoughlin
        struct cmsghdr cmsg;
2481 7d174059 Mark McLoughlin
        char control[CMSG_SPACE(sizeof(int))];
2482 7d174059 Mark McLoughlin
    } msg_control;
2483 06138651 Corey Bryant
    int flags = 0;
2484 7d174059 Mark McLoughlin
    ssize_t ret;
2485 9977c894 Mark McLoughlin
2486 9977c894 Mark McLoughlin
    iov[0].iov_base = buf;
2487 9977c894 Mark McLoughlin
    iov[0].iov_len = len;
2488 9977c894 Mark McLoughlin
2489 9977c894 Mark McLoughlin
    msg.msg_iov = iov;
2490 9977c894 Mark McLoughlin
    msg.msg_iovlen = 1;
2491 7d174059 Mark McLoughlin
    msg.msg_control = &msg_control;
2492 7d174059 Mark McLoughlin
    msg.msg_controllen = sizeof(msg_control);
2493 7d174059 Mark McLoughlin
2494 06138651 Corey Bryant
#ifdef MSG_CMSG_CLOEXEC
2495 06138651 Corey Bryant
    flags |= MSG_CMSG_CLOEXEC;
2496 06138651 Corey Bryant
#endif
2497 06138651 Corey Bryant
    ret = recvmsg(s->fd, &msg, flags);
2498 06138651 Corey Bryant
    if (ret > 0 && s->is_unix) {
2499 7d174059 Mark McLoughlin
        unix_process_msgfd(chr, &msg);
2500 06138651 Corey Bryant
    }
2501 9977c894 Mark McLoughlin
2502 7d174059 Mark McLoughlin
    return ret;
2503 9977c894 Mark McLoughlin
}
2504 9977c894 Mark McLoughlin
#else
2505 9977c894 Mark McLoughlin
static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
2506 9977c894 Mark McLoughlin
{
2507 9977c894 Mark McLoughlin
    TCPCharDriver *s = chr->opaque;
2508 00aa0040 Blue Swirl
    return qemu_recv(s->fd, buf, len, 0);
2509 9977c894 Mark McLoughlin
}
2510 9977c894 Mark McLoughlin
#endif
2511 9977c894 Mark McLoughlin
2512 d3cc5bc4 Amit Shah
static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond)
2513 d3cc5bc4 Amit Shah
{
2514 d3cc5bc4 Amit Shah
    TCPCharDriver *s = chr->opaque;
2515 d3cc5bc4 Amit Shah
    return g_io_create_watch(s->chan, cond);
2516 d3cc5bc4 Amit Shah
}
2517 d3cc5bc4 Amit Shah
2518 2ea5a7af Anthony Liguori
static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
2519 6f97dba0 aliguori
{
2520 6f97dba0 aliguori
    CharDriverState *chr = opaque;
2521 6f97dba0 aliguori
    TCPCharDriver *s = chr->opaque;
2522 9bd7854e Amit Shah
    uint8_t buf[READ_BUF_LEN];
2523 6f97dba0 aliguori
    int len, size;
2524 6f97dba0 aliguori
2525 2ea5a7af Anthony Liguori
    if (!s->connected || s->max_size <= 0) {
2526 cdbf6e16 Paolo Bonzini
        return TRUE;
2527 2ea5a7af Anthony Liguori
    }
2528 6f97dba0 aliguori
    len = sizeof(buf);
2529 6f97dba0 aliguori
    if (len > s->max_size)
2530 6f97dba0 aliguori
        len = s->max_size;
2531 9977c894 Mark McLoughlin
    size = tcp_chr_recv(chr, (void *)buf, len);
2532 6f97dba0 aliguori
    if (size == 0) {
2533 6f97dba0 aliguori
        /* connection closed */
2534 6f97dba0 aliguori
        s->connected = 0;
2535 2ea5a7af Anthony Liguori
        if (s->listen_chan) {
2536 2ea5a7af Anthony Liguori
            s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
2537 6f97dba0 aliguori
        }
2538 910b6368 Paolo Bonzini
        if (s->tag) {
2539 2b316774 Paolo Bonzini
            io_remove_watch_poll(s->tag);
2540 910b6368 Paolo Bonzini
            s->tag = 0;
2541 910b6368 Paolo Bonzini
        }
2542 2ea5a7af Anthony Liguori
        g_io_channel_unref(s->chan);
2543 2ea5a7af Anthony Liguori
        s->chan = NULL;
2544 6f97dba0 aliguori
        closesocket(s->fd);
2545 6f97dba0 aliguori
        s->fd = -1;
2546 a425d23f Hans de Goede
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
2547 6f97dba0 aliguori
    } else if (size > 0) {
2548 6f97dba0 aliguori
        if (s->do_telnetopt)
2549 6f97dba0 aliguori
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
2550 6f97dba0 aliguori
        if (size > 0)
2551 fa5efccb Anthony Liguori
            qemu_chr_be_write(chr, buf, size);
2552 6f97dba0 aliguori
    }
2553 2ea5a7af Anthony Liguori
2554 2ea5a7af Anthony Liguori
    return TRUE;
2555 6f97dba0 aliguori
}
2556 6f97dba0 aliguori
2557 68c18d1c Blue Swirl
#ifndef _WIN32
2558 68c18d1c Blue Swirl
CharDriverState *qemu_chr_open_eventfd(int eventfd)
2559 68c18d1c Blue Swirl
{
2560 6cbf4c8c Cam Macdonell
    return qemu_chr_open_fd(eventfd, eventfd);
2561 6cbf4c8c Cam Macdonell
}
2562 68c18d1c Blue Swirl
#endif
2563 6cbf4c8c Cam Macdonell
2564 6f97dba0 aliguori
static void tcp_chr_connect(void *opaque)
2565 6f97dba0 aliguori
{
2566 6f97dba0 aliguori
    CharDriverState *chr = opaque;
2567 6f97dba0 aliguori
    TCPCharDriver *s = chr->opaque;
2568 6f97dba0 aliguori
2569 6f97dba0 aliguori
    s->connected = 1;
2570 2ea5a7af Anthony Liguori
    if (s->chan) {
2571 2ea5a7af Anthony Liguori
        s->tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, tcp_chr_read, chr);
2572 bbdd2ad0 David Gibson
    }
2573 fee204fd Hans de Goede
    qemu_chr_be_generic_open(chr);
2574 6f97dba0 aliguori
}
2575 6f97dba0 aliguori
2576 6f97dba0 aliguori
#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
2577 6f97dba0 aliguori
static void tcp_chr_telnet_init(int fd)
2578 6f97dba0 aliguori
{
2579 6f97dba0 aliguori
    char buf[3];
2580 6f97dba0 aliguori
    /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
2581 6f97dba0 aliguori
    IACSET(buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
2582 6f97dba0 aliguori
    send(fd, (char *)buf, 3, 0);
2583 6f97dba0 aliguori
    IACSET(buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
2584 6f97dba0 aliguori
    send(fd, (char *)buf, 3, 0);
2585 6f97dba0 aliguori
    IACSET(buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
2586 6f97dba0 aliguori
    send(fd, (char *)buf, 3, 0);
2587 6f97dba0 aliguori
    IACSET(buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
2588 6f97dba0 aliguori
    send(fd, (char *)buf, 3, 0);
2589 6f97dba0 aliguori
}
2590 6f97dba0 aliguori
2591 13661089 Daniel P. Berrange
static int tcp_chr_add_client(CharDriverState *chr, int fd)
2592 13661089 Daniel P. Berrange
{
2593 13661089 Daniel P. Berrange
    TCPCharDriver *s = chr->opaque;
2594 13661089 Daniel P. Berrange
    if (s->fd != -1)
2595 13661089 Daniel P. Berrange
        return -1;
2596 13661089 Daniel P. Berrange
2597 f9e8cacc Stefan Hajnoczi
    qemu_set_nonblock(fd);
2598 13661089 Daniel P. Berrange
    if (s->do_nodelay)
2599 13661089 Daniel P. Berrange
        socket_set_nodelay(fd);
2600 13661089 Daniel P. Berrange
    s->fd = fd;
2601 2ea5a7af Anthony Liguori
    s->chan = io_channel_from_socket(fd);
2602 910b6368 Paolo Bonzini
    if (s->listen_tag) {
2603 910b6368 Paolo Bonzini
        g_source_remove(s->listen_tag);
2604 910b6368 Paolo Bonzini
        s->listen_tag = 0;
2605 910b6368 Paolo Bonzini
    }
2606 13661089 Daniel P. Berrange
    tcp_chr_connect(chr);
2607 13661089 Daniel P. Berrange
2608 13661089 Daniel P. Berrange
    return 0;
2609 13661089 Daniel P. Berrange
}
2610 13661089 Daniel P. Berrange
2611 2ea5a7af Anthony Liguori
static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque)
2612 6f97dba0 aliguori
{
2613 6f97dba0 aliguori
    CharDriverState *chr = opaque;
2614 6f97dba0 aliguori
    TCPCharDriver *s = chr->opaque;
2615 6f97dba0 aliguori
    struct sockaddr_in saddr;
2616 6f97dba0 aliguori
#ifndef _WIN32
2617 6f97dba0 aliguori
    struct sockaddr_un uaddr;
2618 6f97dba0 aliguori
#endif
2619 6f97dba0 aliguori
    struct sockaddr *addr;
2620 6f97dba0 aliguori
    socklen_t len;
2621 6f97dba0 aliguori
    int fd;
2622 6f97dba0 aliguori
2623 6f97dba0 aliguori
    for(;;) {
2624 6f97dba0 aliguori
#ifndef _WIN32
2625 6f97dba0 aliguori
        if (s->is_unix) {
2626 6f97dba0 aliguori
            len = sizeof(uaddr);
2627 6f97dba0 aliguori
            addr = (struct sockaddr *)&uaddr;
2628 6f97dba0 aliguori
        } else
2629 6f97dba0 aliguori
#endif
2630 6f97dba0 aliguori
        {
2631 6f97dba0 aliguori
            len = sizeof(saddr);
2632 6f97dba0 aliguori
            addr = (struct sockaddr *)&saddr;
2633 6f97dba0 aliguori
        }
2634 40ff6d7e Kevin Wolf
        fd = qemu_accept(s->listen_fd, addr, &len);
2635 6f97dba0 aliguori
        if (fd < 0 && errno != EINTR) {
2636 79f20075 Hans de Goede
            s->listen_tag = 0;
2637 2ea5a7af Anthony Liguori
            return FALSE;
2638 6f97dba0 aliguori
        } else if (fd >= 0) {
2639 6f97dba0 aliguori
            if (s->do_telnetopt)
2640 6f97dba0 aliguori
                tcp_chr_telnet_init(fd);
2641 6f97dba0 aliguori
            break;
2642 6f97dba0 aliguori
        }
2643 6f97dba0 aliguori
    }
2644 13661089 Daniel P. Berrange
    if (tcp_chr_add_client(chr, fd) < 0)
2645 13661089 Daniel P. Berrange
        close(fd);
2646 2ea5a7af Anthony Liguori
2647 2ea5a7af Anthony Liguori
    return TRUE;
2648 6f97dba0 aliguori
}
2649 6f97dba0 aliguori
2650 6f97dba0 aliguori
static void tcp_chr_close(CharDriverState *chr)
2651 6f97dba0 aliguori
{
2652 6f97dba0 aliguori
    TCPCharDriver *s = chr->opaque;
2653 819f56b7 aliguori
    if (s->fd >= 0) {
2654 2ea5a7af Anthony Liguori
        if (s->tag) {
2655 2b316774 Paolo Bonzini
            io_remove_watch_poll(s->tag);
2656 910b6368 Paolo Bonzini
            s->tag = 0;
2657 2ea5a7af Anthony Liguori
        }
2658 2ea5a7af Anthony Liguori
        if (s->chan) {
2659 2ea5a7af Anthony Liguori
            g_io_channel_unref(s->chan);
2660 2ea5a7af Anthony Liguori
        }
2661 6f97dba0 aliguori
        closesocket(s->fd);
2662 819f56b7 aliguori
    }
2663 819f56b7 aliguori
    if (s->listen_fd >= 0) {
2664 2ea5a7af Anthony Liguori
        if (s->listen_tag) {
2665 2ea5a7af Anthony Liguori
            g_source_remove(s->listen_tag);
2666 910b6368 Paolo Bonzini
            s->listen_tag = 0;
2667 2ea5a7af Anthony Liguori
        }
2668 2ea5a7af Anthony Liguori
        if (s->listen_chan) {
2669 2ea5a7af Anthony Liguori
            g_io_channel_unref(s->listen_chan);
2670 2ea5a7af Anthony Liguori
        }
2671 6f97dba0 aliguori
        closesocket(s->listen_fd);
2672 819f56b7 aliguori
    }
2673 7267c094 Anthony Liguori
    g_free(s);
2674 a425d23f Hans de Goede
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
2675 6f97dba0 aliguori
}
2676 6f97dba0 aliguori
2677 f6bd5d6e Gerd Hoffmann
static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
2678 f6bd5d6e Gerd Hoffmann
                                                bool is_listen, bool is_telnet,
2679 f6bd5d6e Gerd Hoffmann
                                                bool is_waitconnect,
2680 f6bd5d6e Gerd Hoffmann
                                                Error **errp)
2681 6f97dba0 aliguori
{
2682 6f97dba0 aliguori
    CharDriverState *chr = NULL;
2683 6f97dba0 aliguori
    TCPCharDriver *s = NULL;
2684 f6bd5d6e Gerd Hoffmann
    char host[NI_MAXHOST], serv[NI_MAXSERV];
2685 f6bd5d6e Gerd Hoffmann
    const char *left = "", *right = "";
2686 f6bd5d6e Gerd Hoffmann
    struct sockaddr_storage ss;
2687 f6bd5d6e Gerd Hoffmann
    socklen_t ss_len = sizeof(ss);
2688 f6bd5d6e Gerd Hoffmann
2689 f6bd5d6e Gerd Hoffmann
    memset(&ss, 0, ss_len);
2690 f6bd5d6e Gerd Hoffmann
    if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
2691 f6bd5d6e Gerd Hoffmann
        error_setg(errp, "getsockname: %s", strerror(errno));
2692 f6bd5d6e Gerd Hoffmann
        return NULL;
2693 f6bd5d6e Gerd Hoffmann
    }
2694 f6bd5d6e Gerd Hoffmann
2695 f6bd5d6e Gerd Hoffmann
    chr = g_malloc0(sizeof(CharDriverState));
2696 f6bd5d6e Gerd Hoffmann
    s = g_malloc0(sizeof(TCPCharDriver));
2697 f6bd5d6e Gerd Hoffmann
2698 f6bd5d6e Gerd Hoffmann
    s->connected = 0;
2699 f6bd5d6e Gerd Hoffmann
    s->fd = -1;
2700 f6bd5d6e Gerd Hoffmann
    s->listen_fd = -1;
2701 f6bd5d6e Gerd Hoffmann
    s->msgfd = -1;
2702 f6bd5d6e Gerd Hoffmann
2703 f6bd5d6e Gerd Hoffmann
    chr->filename = g_malloc(256);
2704 f6bd5d6e Gerd Hoffmann
    switch (ss.ss_family) {
2705 f6bd5d6e Gerd Hoffmann
#ifndef _WIN32
2706 f6bd5d6e Gerd Hoffmann
    case AF_UNIX:
2707 f6bd5d6e Gerd Hoffmann
        s->is_unix = 1;
2708 f6bd5d6e Gerd Hoffmann
        snprintf(chr->filename, 256, "unix:%s%s",
2709 f6bd5d6e Gerd Hoffmann
                 ((struct sockaddr_un *)(&ss))->sun_path,
2710 f6bd5d6e Gerd Hoffmann
                 is_listen ? ",server" : "");
2711 f6bd5d6e Gerd Hoffmann
        break;
2712 f6bd5d6e Gerd Hoffmann
#endif
2713 f6bd5d6e Gerd Hoffmann
    case AF_INET6:
2714 f6bd5d6e Gerd Hoffmann
        left  = "[";
2715 f6bd5d6e Gerd Hoffmann
        right = "]";
2716 f6bd5d6e Gerd Hoffmann
        /* fall through */
2717 f6bd5d6e Gerd Hoffmann
    case AF_INET:
2718 f6bd5d6e Gerd Hoffmann
        s->do_nodelay = do_nodelay;
2719 f6bd5d6e Gerd Hoffmann
        getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host),
2720 f6bd5d6e Gerd Hoffmann
                    serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
2721 e5545854 Igor Mitsyanko
        snprintf(chr->filename, 256, "%s:%s%s%s:%s%s",
2722 f6bd5d6e Gerd Hoffmann
                 is_telnet ? "telnet" : "tcp",
2723 f6bd5d6e Gerd Hoffmann
                 left, host, right, serv,
2724 f6bd5d6e Gerd Hoffmann
                 is_listen ? ",server" : "");
2725 f6bd5d6e Gerd Hoffmann
        break;
2726 f6bd5d6e Gerd Hoffmann
    }
2727 f6bd5d6e Gerd Hoffmann
2728 f6bd5d6e Gerd Hoffmann
    chr->opaque = s;
2729 f6bd5d6e Gerd Hoffmann
    chr->chr_write = tcp_chr_write;
2730 f6bd5d6e Gerd Hoffmann
    chr->chr_close = tcp_chr_close;
2731 f6bd5d6e Gerd Hoffmann
    chr->get_msgfd = tcp_get_msgfd;
2732 f6bd5d6e Gerd Hoffmann
    chr->chr_add_client = tcp_chr_add_client;
2733 d3cc5bc4 Amit Shah
    chr->chr_add_watch = tcp_chr_add_watch;
2734 f6bd5d6e Gerd Hoffmann
2735 f6bd5d6e Gerd Hoffmann
    if (is_listen) {
2736 f6bd5d6e Gerd Hoffmann
        s->listen_fd = fd;
2737 2ea5a7af Anthony Liguori
        s->listen_chan = io_channel_from_socket(s->listen_fd);
2738 2ea5a7af Anthony Liguori
        s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
2739 f6bd5d6e Gerd Hoffmann
        if (is_telnet) {
2740 f6bd5d6e Gerd Hoffmann
            s->do_telnetopt = 1;
2741 f6bd5d6e Gerd Hoffmann
        }
2742 f6bd5d6e Gerd Hoffmann
    } else {
2743 f6bd5d6e Gerd Hoffmann
        s->connected = 1;
2744 f6bd5d6e Gerd Hoffmann
        s->fd = fd;
2745 f6bd5d6e Gerd Hoffmann
        socket_set_nodelay(fd);
2746 2ea5a7af Anthony Liguori
        s->chan = io_channel_from_socket(s->fd);
2747 f6bd5d6e Gerd Hoffmann
        tcp_chr_connect(chr);
2748 f6bd5d6e Gerd Hoffmann
    }
2749 f6bd5d6e Gerd Hoffmann
2750 f6bd5d6e Gerd Hoffmann
    if (is_listen && is_waitconnect) {
2751 f6bd5d6e Gerd Hoffmann
        printf("QEMU waiting for connection on: %s\n",
2752 f6bd5d6e Gerd Hoffmann
               chr->filename);
2753 2ea5a7af Anthony Liguori
        tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
2754 f9e8cacc Stefan Hajnoczi
        qemu_set_nonblock(s->listen_fd);
2755 f6bd5d6e Gerd Hoffmann
    }
2756 f6bd5d6e Gerd Hoffmann
    return chr;
2757 f6bd5d6e Gerd Hoffmann
}
2758 f6bd5d6e Gerd Hoffmann
2759 f6bd5d6e Gerd Hoffmann
static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
2760 f6bd5d6e Gerd Hoffmann
{
2761 f6bd5d6e Gerd Hoffmann
    CharDriverState *chr = NULL;
2762 87d5f24f Paolo Bonzini
    Error *local_err = NULL;
2763 aeb2c47a Gerd Hoffmann
    int fd = -1;
2764 aeb2c47a Gerd Hoffmann
    int is_listen;
2765 aeb2c47a Gerd Hoffmann
    int is_waitconnect;
2766 aeb2c47a Gerd Hoffmann
    int do_nodelay;
2767 aeb2c47a Gerd Hoffmann
    int is_unix;
2768 aeb2c47a Gerd Hoffmann
    int is_telnet;
2769 aeb2c47a Gerd Hoffmann
2770 aeb2c47a Gerd Hoffmann
    is_listen      = qemu_opt_get_bool(opts, "server", 0);
2771 aeb2c47a Gerd Hoffmann
    is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);
2772 aeb2c47a Gerd Hoffmann
    is_telnet      = qemu_opt_get_bool(opts, "telnet", 0);
2773 aeb2c47a Gerd Hoffmann
    do_nodelay     = !qemu_opt_get_bool(opts, "delay", 1);
2774 aeb2c47a Gerd Hoffmann
    is_unix        = qemu_opt_get(opts, "path") != NULL;
2775 6f97dba0 aliguori
    if (!is_listen)
2776 6f97dba0 aliguori
        is_waitconnect = 0;
2777 6f97dba0 aliguori
2778 f07b6003 aliguori
    if (is_unix) {
2779 f07b6003 aliguori
        if (is_listen) {
2780 87d5f24f Paolo Bonzini
            fd = unix_listen_opts(opts, &local_err);
2781 f07b6003 aliguori
        } else {
2782 87d5f24f Paolo Bonzini
            fd = unix_connect_opts(opts, &local_err, NULL, NULL);
2783 f07b6003 aliguori
        }
2784 f07b6003 aliguori
    } else {
2785 f07b6003 aliguori
        if (is_listen) {
2786 87d5f24f Paolo Bonzini
            fd = inet_listen_opts(opts, 0, &local_err);
2787 f07b6003 aliguori
        } else {
2788 87d5f24f Paolo Bonzini
            fd = inet_connect_opts(opts, &local_err, NULL, NULL);
2789 f07b6003 aliguori
        }
2790 f07b6003 aliguori
    }
2791 a89dd6c3 Markus Armbruster
    if (fd < 0) {
2792 6f97dba0 aliguori
        goto fail;
2793 a89dd6c3 Markus Armbruster
    }
2794 6f97dba0 aliguori
2795 6f97dba0 aliguori
    if (!is_waitconnect)
2796 f9e8cacc Stefan Hajnoczi
        qemu_set_nonblock(fd);
2797 6f97dba0 aliguori
2798 f6bd5d6e Gerd Hoffmann
    chr = qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, is_telnet,
2799 f6bd5d6e Gerd Hoffmann
                                  is_waitconnect, &local_err);
2800 f6bd5d6e Gerd Hoffmann
    if (error_is_set(&local_err)) {
2801 f6bd5d6e Gerd Hoffmann
        goto fail;
2802 6f97dba0 aliguori
    }
2803 1f51470d Markus Armbruster
    return chr;
2804 aeb2c47a Gerd Hoffmann
2805 f6bd5d6e Gerd Hoffmann
2806 6f97dba0 aliguori
 fail:
2807 87d5f24f Paolo Bonzini
    if (local_err) {
2808 87d5f24f Paolo Bonzini
        qerror_report_err(local_err);
2809 87d5f24f Paolo Bonzini
        error_free(local_err);
2810 87d5f24f Paolo Bonzini
    }
2811 87d5f24f Paolo Bonzini
    if (fd >= 0) {
2812 6f97dba0 aliguori
        closesocket(fd);
2813 87d5f24f Paolo Bonzini
    }
2814 f6bd5d6e Gerd Hoffmann
    if (chr) {
2815 f6bd5d6e Gerd Hoffmann
        g_free(chr->opaque);
2816 f6bd5d6e Gerd Hoffmann
        g_free(chr);
2817 f6bd5d6e Gerd Hoffmann
    }
2818 1f51470d Markus Armbruster
    return NULL;
2819 6f97dba0 aliguori
}
2820 6f97dba0 aliguori
2821 51767e7c Lei Li
/*********************************************************/
2822 3949e594 Markus Armbruster
/* Ring buffer chardev */
2823 51767e7c Lei Li
2824 51767e7c Lei Li
typedef struct {
2825 51767e7c Lei Li
    size_t size;
2826 51767e7c Lei Li
    size_t prod;
2827 51767e7c Lei Li
    size_t cons;
2828 51767e7c Lei Li
    uint8_t *cbuf;
2829 3949e594 Markus Armbruster
} RingBufCharDriver;
2830 51767e7c Lei Li
2831 3949e594 Markus Armbruster
static size_t ringbuf_count(const CharDriverState *chr)
2832 51767e7c Lei Li
{
2833 3949e594 Markus Armbruster
    const RingBufCharDriver *d = chr->opaque;
2834 51767e7c Lei Li
2835 5c230105 Markus Armbruster
    return d->prod - d->cons;
2836 51767e7c Lei Li
}
2837 51767e7c Lei Li
2838 3949e594 Markus Armbruster
static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2839 51767e7c Lei Li
{
2840 3949e594 Markus Armbruster
    RingBufCharDriver *d = chr->opaque;
2841 51767e7c Lei Li
    int i;
2842 51767e7c Lei Li
2843 51767e7c Lei Li
    if (!buf || (len < 0)) {
2844 51767e7c Lei Li
        return -1;
2845 51767e7c Lei Li
    }
2846 51767e7c Lei Li
2847 51767e7c Lei Li
    for (i = 0; i < len; i++ ) {
2848 5c230105 Markus Armbruster
        d->cbuf[d->prod++ & (d->size - 1)] = buf[i];
2849 5c230105 Markus Armbruster
        if (d->prod - d->cons > d->size) {
2850 51767e7c Lei Li
            d->cons = d->prod - d->size;
2851 51767e7c Lei Li
        }
2852 51767e7c Lei Li
    }
2853 51767e7c Lei Li
2854 51767e7c Lei Li
    return 0;
2855 51767e7c Lei Li
}
2856 51767e7c Lei Li
2857 3949e594 Markus Armbruster
static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len)
2858 51767e7c Lei Li
{
2859 3949e594 Markus Armbruster
    RingBufCharDriver *d = chr->opaque;
2860 51767e7c Lei Li
    int i;
2861 51767e7c Lei Li
2862 5c230105 Markus Armbruster
    for (i = 0; i < len && d->cons != d->prod; i++) {
2863 5c230105 Markus Armbruster
        buf[i] = d->cbuf[d->cons++ & (d->size - 1)];
2864 51767e7c Lei Li
    }
2865 51767e7c Lei Li
2866 51767e7c Lei Li
    return i;
2867 51767e7c Lei Li
}
2868 51767e7c Lei Li
2869 3949e594 Markus Armbruster
static void ringbuf_chr_close(struct CharDriverState *chr)
2870 51767e7c Lei Li
{
2871 3949e594 Markus Armbruster
    RingBufCharDriver *d = chr->opaque;
2872 51767e7c Lei Li
2873 51767e7c Lei Li
    g_free(d->cbuf);
2874 51767e7c Lei Li
    g_free(d);
2875 51767e7c Lei Li
    chr->opaque = NULL;
2876 51767e7c Lei Li
}
2877 51767e7c Lei Li
2878 6a85e60c Lei Li
static CharDriverState *qemu_chr_open_memory(ChardevMemory *opts,
2879 6a85e60c Lei Li
                                             Error **errp)
2880 51767e7c Lei Li
{
2881 51767e7c Lei Li
    CharDriverState *chr;
2882 3949e594 Markus Armbruster
    RingBufCharDriver *d;
2883 51767e7c Lei Li
2884 51767e7c Lei Li
    chr = g_malloc0(sizeof(CharDriverState));
2885 51767e7c Lei Li
    d = g_malloc(sizeof(*d));
2886 51767e7c Lei Li
2887 1da48c65 Gerd Hoffmann
    d->size = opts->has_size ? opts->size : 65536;
2888 51767e7c Lei Li
2889 51767e7c Lei Li
    /* The size must be power of 2 */
2890 51767e7c Lei Li
    if (d->size & (d->size - 1)) {
2891 6a85e60c Lei Li
        error_setg(errp, "size of memory chardev must be power of two");
2892 51767e7c Lei Li
        goto fail;
2893 51767e7c Lei Li
    }
2894 51767e7c Lei Li
2895 51767e7c Lei Li
    d->prod = 0;
2896 51767e7c Lei Li
    d->cons = 0;
2897 51767e7c Lei Li
    d->cbuf = g_malloc0(d->size);
2898 51767e7c Lei Li
2899 51767e7c Lei Li
    chr->opaque = d;
2900 3949e594 Markus Armbruster
    chr->chr_write = ringbuf_chr_write;
2901 3949e594 Markus Armbruster
    chr->chr_close = ringbuf_chr_close;
2902 51767e7c Lei Li
2903 51767e7c Lei Li
    return chr;
2904 51767e7c Lei Li
2905 51767e7c Lei Li
fail:
2906 51767e7c Lei Li
    g_free(d);
2907 51767e7c Lei Li
    g_free(chr);
2908 51767e7c Lei Li
    return NULL;
2909 51767e7c Lei Li
}
2910 51767e7c Lei Li
2911 3949e594 Markus Armbruster
static bool chr_is_ringbuf(const CharDriverState *chr)
2912 1f590cf9 Lei Li
{
2913 3949e594 Markus Armbruster
    return chr->chr_write == ringbuf_chr_write;
2914 1f590cf9 Lei Li
}
2915 1f590cf9 Lei Li
2916 3949e594 Markus Armbruster
void qmp_ringbuf_write(const char *device, const char *data,
2917 82e59a67 Markus Armbruster
                       bool has_format, enum DataFormat format,
2918 1f590cf9 Lei Li
                       Error **errp)
2919 1f590cf9 Lei Li
{
2920 1f590cf9 Lei Li
    CharDriverState *chr;
2921 c4f331b6 Markus Armbruster
    const uint8_t *write_data;
2922 1f590cf9 Lei Li
    int ret;
2923 3d1bba20 Peter Crosthwaite
    gsize write_count;
2924 1f590cf9 Lei Li
2925 1f590cf9 Lei Li
    chr = qemu_chr_find(device);
2926 1f590cf9 Lei Li
    if (!chr) {
2927 1a69278e Markus Armbruster
        error_setg(errp, "Device '%s' not found", device);
2928 1f590cf9 Lei Li
        return;
2929 1f590cf9 Lei Li
    }
2930 1f590cf9 Lei Li
2931 3949e594 Markus Armbruster
    if (!chr_is_ringbuf(chr)) {
2932 3949e594 Markus Armbruster
        error_setg(errp,"%s is not a ringbuf device", device);
2933 1f590cf9 Lei Li
        return;
2934 1f590cf9 Lei Li
    }
2935 1f590cf9 Lei Li
2936 1f590cf9 Lei Li
    if (has_format && (format == DATA_FORMAT_BASE64)) {
2937 1f590cf9 Lei Li
        write_data = g_base64_decode(data, &write_count);
2938 1f590cf9 Lei Li
    } else {
2939 1f590cf9 Lei Li
        write_data = (uint8_t *)data;
2940 82e59a67 Markus Armbruster
        write_count = strlen(data);
2941 1f590cf9 Lei Li
    }
2942 1f590cf9 Lei Li
2943 3949e594 Markus Armbruster
    ret = ringbuf_chr_write(chr, write_data, write_count);
2944 1f590cf9 Lei Li
2945 13289fb5 Markus Armbruster
    if (write_data != (uint8_t *)data) {
2946 13289fb5 Markus Armbruster
        g_free((void *)write_data);
2947 13289fb5 Markus Armbruster
    }
2948 13289fb5 Markus Armbruster
2949 1f590cf9 Lei Li
    if (ret < 0) {
2950 1f590cf9 Lei Li
        error_setg(errp, "Failed to write to device %s", device);
2951 1f590cf9 Lei Li
        return;
2952 1f590cf9 Lei Li
    }
2953 1f590cf9 Lei Li
}
2954 1f590cf9 Lei Li
2955 3949e594 Markus Armbruster
char *qmp_ringbuf_read(const char *device, int64_t size,
2956 3ab651fc Markus Armbruster
                       bool has_format, enum DataFormat format,
2957 3ab651fc Markus Armbruster
                       Error **errp)
2958 49b6d722 Lei Li
{
2959 49b6d722 Lei Li
    CharDriverState *chr;
2960 c4f331b6 Markus Armbruster
    uint8_t *read_data;
2961 49b6d722 Lei Li
    size_t count;
2962 3ab651fc Markus Armbruster
    char *data;
2963 49b6d722 Lei Li
2964 49b6d722 Lei Li
    chr = qemu_chr_find(device);
2965 49b6d722 Lei Li
    if (!chr) {
2966 1a69278e Markus Armbruster
        error_setg(errp, "Device '%s' not found", device);
2967 49b6d722 Lei Li
        return NULL;
2968 49b6d722 Lei Li
    }
2969 49b6d722 Lei Li
2970 3949e594 Markus Armbruster
    if (!chr_is_ringbuf(chr)) {
2971 3949e594 Markus Armbruster
        error_setg(errp,"%s is not a ringbuf device", device);
2972 49b6d722 Lei Li
        return NULL;
2973 49b6d722 Lei Li
    }
2974 49b6d722 Lei Li
2975 49b6d722 Lei Li
    if (size <= 0) {
2976 49b6d722 Lei Li
        error_setg(errp, "size must be greater than zero");
2977 49b6d722 Lei Li
        return NULL;
2978 49b6d722 Lei Li
    }
2979 49b6d722 Lei Li
2980 3949e594 Markus Armbruster
    count = ringbuf_count(chr);
2981 49b6d722 Lei Li
    size = size > count ? count : size;
2982 44f3bcd2 Markus Armbruster
    read_data = g_malloc(size + 1);
2983 49b6d722 Lei Li
2984 3949e594 Markus Armbruster
    ringbuf_chr_read(chr, read_data, size);
2985 49b6d722 Lei Li
2986 49b6d722 Lei Li
    if (has_format && (format == DATA_FORMAT_BASE64)) {
2987 3ab651fc Markus Armbruster
        data = g_base64_encode(read_data, size);
2988 13289fb5 Markus Armbruster
        g_free(read_data);
2989 49b6d722 Lei Li
    } else {
2990 3949e594 Markus Armbruster
        /*
2991 3949e594 Markus Armbruster
         * FIXME should read only complete, valid UTF-8 characters up
2992 3949e594 Markus Armbruster
         * to @size bytes.  Invalid sequences should be replaced by a
2993 3949e594 Markus Armbruster
         * suitable replacement character.  Except when (and only
2994 3949e594 Markus Armbruster
         * when) ring buffer lost characters since last read, initial
2995 3949e594 Markus Armbruster
         * continuation characters should be dropped.
2996 3949e594 Markus Armbruster
         */
2997 44f3bcd2 Markus Armbruster
        read_data[size] = 0;
2998 3ab651fc Markus Armbruster
        data = (char *)read_data;
2999 49b6d722 Lei Li
    }
3000 49b6d722 Lei Li
3001 3ab651fc Markus Armbruster
    return data;
3002 49b6d722 Lei Li
}
3003 49b6d722 Lei Li
3004 33521634 Gerd Hoffmann
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
3005 191bc01b Gerd Hoffmann
{
3006 6ea314d9 Gerd Hoffmann
    char host[65], port[33], width[8], height[8];
3007 aeb2c47a Gerd Hoffmann
    int pos;
3008 7d31544f Gerd Hoffmann
    const char *p;
3009 191bc01b Gerd Hoffmann
    QemuOpts *opts;
3010 8be7e7e4 Luiz Capitulino
    Error *local_err = NULL;
3011 191bc01b Gerd Hoffmann
3012 8be7e7e4 Luiz Capitulino
    opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
3013 8be7e7e4 Luiz Capitulino
    if (error_is_set(&local_err)) {
3014 8be7e7e4 Luiz Capitulino
        qerror_report_err(local_err);
3015 8be7e7e4 Luiz Capitulino
        error_free(local_err);
3016 191bc01b Gerd Hoffmann
        return NULL;
3017 8be7e7e4 Luiz Capitulino
    }
3018 191bc01b Gerd Hoffmann
3019 7591c5c1 Gerd Hoffmann
    if (strstart(filename, "mon:", &p)) {
3020 7591c5c1 Gerd Hoffmann
        filename = p;
3021 7591c5c1 Gerd Hoffmann
        qemu_opt_set(opts, "mux", "on");
3022 7591c5c1 Gerd Hoffmann
    }
3023 7591c5c1 Gerd Hoffmann
3024 f0457e8d Gerd Hoffmann
    if (strcmp(filename, "null")    == 0 ||
3025 f0457e8d Gerd Hoffmann
        strcmp(filename, "pty")     == 0 ||
3026 f0457e8d Gerd Hoffmann
        strcmp(filename, "msmouse") == 0 ||
3027 dc1c21e6 Gerd Hoffmann
        strcmp(filename, "braille") == 0 ||
3028 f0457e8d Gerd Hoffmann
        strcmp(filename, "stdio")   == 0) {
3029 4490dadf Gerd Hoffmann
        qemu_opt_set(opts, "backend", filename);
3030 191bc01b Gerd Hoffmann
        return opts;
3031 191bc01b Gerd Hoffmann
    }
3032 6ea314d9 Gerd Hoffmann
    if (strstart(filename, "vc", &p)) {
3033 6ea314d9 Gerd Hoffmann
        qemu_opt_set(opts, "backend", "vc");
3034 6ea314d9 Gerd Hoffmann
        if (*p == ':') {
3035 6ea314d9 Gerd Hoffmann
            if (sscanf(p+1, "%8[0-9]x%8[0-9]", width, height) == 2) {
3036 6ea314d9 Gerd Hoffmann
                /* pixels */
3037 6ea314d9 Gerd Hoffmann
                qemu_opt_set(opts, "width", width);
3038 6ea314d9 Gerd Hoffmann
                qemu_opt_set(opts, "height", height);
3039 6ea314d9 Gerd Hoffmann
            } else if (sscanf(p+1, "%8[0-9]Cx%8[0-9]C", width, height) == 2) {
3040 6ea314d9 Gerd Hoffmann
                /* chars */
3041 6ea314d9 Gerd Hoffmann
                qemu_opt_set(opts, "cols", width);
3042 6ea314d9 Gerd Hoffmann
                qemu_opt_set(opts, "rows", height);
3043 6ea314d9 Gerd Hoffmann
            } else {
3044 6ea314d9 Gerd Hoffmann
                goto fail;
3045 6ea314d9 Gerd Hoffmann
            }
3046 6ea314d9 Gerd Hoffmann
        }
3047 6ea314d9 Gerd Hoffmann
        return opts;
3048 6ea314d9 Gerd Hoffmann
    }
3049 d6c983cd Gerd Hoffmann
    if (strcmp(filename, "con:") == 0) {
3050 d6c983cd Gerd Hoffmann
        qemu_opt_set(opts, "backend", "console");
3051 d6c983cd Gerd Hoffmann
        return opts;
3052 d6c983cd Gerd Hoffmann
    }
3053 48b76496 Gerd Hoffmann
    if (strstart(filename, "COM", NULL)) {
3054 48b76496 Gerd Hoffmann
        qemu_opt_set(opts, "backend", "serial");
3055 48b76496 Gerd Hoffmann
        qemu_opt_set(opts, "path", filename);
3056 48b76496 Gerd Hoffmann
        return opts;
3057 48b76496 Gerd Hoffmann
    }
3058 7d31544f Gerd Hoffmann
    if (strstart(filename, "file:", &p)) {
3059 7d31544f Gerd Hoffmann
        qemu_opt_set(opts, "backend", "file");
3060 7d31544f Gerd Hoffmann
        qemu_opt_set(opts, "path", p);
3061 7d31544f Gerd Hoffmann
        return opts;
3062 7d31544f Gerd Hoffmann
    }
3063 7d31544f Gerd Hoffmann
    if (strstart(filename, "pipe:", &p)) {
3064 7d31544f Gerd Hoffmann
        qemu_opt_set(opts, "backend", "pipe");
3065 7d31544f Gerd Hoffmann
        qemu_opt_set(opts, "path", p);
3066 7d31544f Gerd Hoffmann
        return opts;
3067 7d31544f Gerd Hoffmann
    }
3068 aeb2c47a Gerd Hoffmann
    if (strstart(filename, "tcp:", &p) ||
3069 aeb2c47a Gerd Hoffmann
        strstart(filename, "telnet:", &p)) {
3070 aeb2c47a Gerd Hoffmann
        if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
3071 aeb2c47a Gerd Hoffmann
            host[0] = 0;
3072 aeb2c47a Gerd Hoffmann
            if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
3073 aeb2c47a Gerd Hoffmann
                goto fail;
3074 aeb2c47a Gerd Hoffmann
        }
3075 aeb2c47a Gerd Hoffmann
        qemu_opt_set(opts, "backend", "socket");
3076 aeb2c47a Gerd Hoffmann
        qemu_opt_set(opts, "host", host);
3077 aeb2c47a Gerd Hoffmann
        qemu_opt_set(opts, "port", port);
3078 aeb2c47a Gerd Hoffmann
        if (p[pos] == ',') {
3079 aeb2c47a Gerd Hoffmann
            if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)
3080 aeb2c47a Gerd Hoffmann
                goto fail;
3081 aeb2c47a Gerd Hoffmann
        }
3082 aeb2c47a Gerd Hoffmann
        if (strstart(filename, "telnet:", &p))
3083 aeb2c47a Gerd Hoffmann
            qemu_opt_set(opts, "telnet", "on");
3084 aeb2c47a Gerd Hoffmann
        return opts;
3085 aeb2c47a Gerd Hoffmann
    }
3086 7e1b35b4 Gerd Hoffmann
    if (strstart(filename, "udp:", &p)) {
3087 7e1b35b4 Gerd Hoffmann
        qemu_opt_set(opts, "backend", "udp");
3088 7e1b35b4 Gerd Hoffmann
        if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
3089 7e1b35b4 Gerd Hoffmann
            host[0] = 0;
3090 39324ca4 Jan Kiszka
            if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
3091 7e1b35b4 Gerd Hoffmann
                goto fail;
3092 7e1b35b4 Gerd Hoffmann
            }
3093 7e1b35b4 Gerd Hoffmann
        }
3094 7e1b35b4 Gerd Hoffmann
        qemu_opt_set(opts, "host", host);
3095 7e1b35b4 Gerd Hoffmann
        qemu_opt_set(opts, "port", port);
3096 7e1b35b4 Gerd Hoffmann
        if (p[pos] == '@') {
3097 7e1b35b4 Gerd Hoffmann
            p += pos + 1;
3098 7e1b35b4 Gerd Hoffmann
            if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
3099 7e1b35b4 Gerd Hoffmann
                host[0] = 0;
3100 7e1b35b4 Gerd Hoffmann
                if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
3101 7e1b35b4 Gerd Hoffmann
                    goto fail;
3102 7e1b35b4 Gerd Hoffmann
                }
3103 7e1b35b4 Gerd Hoffmann
            }
3104 7e1b35b4 Gerd Hoffmann
            qemu_opt_set(opts, "localaddr", host);
3105 7e1b35b4 Gerd Hoffmann
            qemu_opt_set(opts, "localport", port);
3106 7e1b35b4 Gerd Hoffmann
        }
3107 7e1b35b4 Gerd Hoffmann
        return opts;
3108 7e1b35b4 Gerd Hoffmann
    }
3109 aeb2c47a Gerd Hoffmann
    if (strstart(filename, "unix:", &p)) {
3110 aeb2c47a Gerd Hoffmann
        qemu_opt_set(opts, "backend", "socket");
3111 aeb2c47a Gerd Hoffmann
        if (qemu_opts_do_parse(opts, p, "path") != 0)
3112 aeb2c47a Gerd Hoffmann
            goto fail;
3113 aeb2c47a Gerd Hoffmann
        return opts;
3114 aeb2c47a Gerd Hoffmann
    }
3115 48b76496 Gerd Hoffmann
    if (strstart(filename, "/dev/parport", NULL) ||
3116 48b76496 Gerd Hoffmann
        strstart(filename, "/dev/ppi", NULL)) {
3117 48b76496 Gerd Hoffmann
        qemu_opt_set(opts, "backend", "parport");
3118 48b76496 Gerd Hoffmann
        qemu_opt_set(opts, "path", filename);
3119 48b76496 Gerd Hoffmann
        return opts;
3120 48b76496 Gerd Hoffmann
    }
3121 48b76496 Gerd Hoffmann
    if (strstart(filename, "/dev/", NULL)) {
3122 48b76496 Gerd Hoffmann
        qemu_opt_set(opts, "backend", "tty");
3123 48b76496 Gerd Hoffmann
        qemu_opt_set(opts, "path", filename);
3124 48b76496 Gerd Hoffmann
        return opts;
3125 48b76496 Gerd Hoffmann
    }
3126 191bc01b Gerd Hoffmann
3127 aeb2c47a Gerd Hoffmann
fail:
3128 191bc01b Gerd Hoffmann
    qemu_opts_del(opts);
3129 191bc01b Gerd Hoffmann
    return NULL;
3130 191bc01b Gerd Hoffmann
}
3131 191bc01b Gerd Hoffmann
3132 846e2e49 Gerd Hoffmann
static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
3133 846e2e49 Gerd Hoffmann
                                    Error **errp)
3134 846e2e49 Gerd Hoffmann
{
3135 846e2e49 Gerd Hoffmann
    const char *path = qemu_opt_get(opts, "path");
3136 846e2e49 Gerd Hoffmann
3137 846e2e49 Gerd Hoffmann
    if (path == NULL) {
3138 846e2e49 Gerd Hoffmann
        error_setg(errp, "chardev: file: no filename given");
3139 846e2e49 Gerd Hoffmann
        return;
3140 846e2e49 Gerd Hoffmann
    }
3141 846e2e49 Gerd Hoffmann
    backend->file = g_new0(ChardevFile, 1);
3142 846e2e49 Gerd Hoffmann
    backend->file->out = g_strdup(path);
3143 846e2e49 Gerd Hoffmann
}
3144 846e2e49 Gerd Hoffmann
3145 7c358031 Gerd Hoffmann
static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
3146 7c358031 Gerd Hoffmann
                                 Error **errp)
3147 7c358031 Gerd Hoffmann
{
3148 7c358031 Gerd Hoffmann
    backend->stdio = g_new0(ChardevStdio, 1);
3149 7c358031 Gerd Hoffmann
    backend->stdio->has_signal = true;
3150 7c358031 Gerd Hoffmann
    backend->stdio->signal =
3151 7c358031 Gerd Hoffmann
        qemu_opt_get_bool(opts, "signal", display_type != DT_NOGRAPHIC);
3152 7c358031 Gerd Hoffmann
}
3153 7c358031 Gerd Hoffmann
3154 0f1cb51d Gerd Hoffmann
static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
3155 0f1cb51d Gerd Hoffmann
                                  Error **errp)
3156 0f1cb51d Gerd Hoffmann
{
3157 0f1cb51d Gerd Hoffmann
    const char *device = qemu_opt_get(opts, "path");
3158 0f1cb51d Gerd Hoffmann
3159 0f1cb51d Gerd Hoffmann
    if (device == NULL) {
3160 0f1cb51d Gerd Hoffmann
        error_setg(errp, "chardev: serial/tty: no device path given");
3161 0f1cb51d Gerd Hoffmann
        return;
3162 0f1cb51d Gerd Hoffmann
    }
3163 0f1cb51d Gerd Hoffmann
    backend->serial = g_new0(ChardevHostdev, 1);
3164 0f1cb51d Gerd Hoffmann
    backend->serial->device = g_strdup(device);
3165 0f1cb51d Gerd Hoffmann
}
3166 0f1cb51d Gerd Hoffmann
3167 dc375097 Gerd Hoffmann
static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
3168 dc375097 Gerd Hoffmann
                                    Error **errp)
3169 dc375097 Gerd Hoffmann
{
3170 dc375097 Gerd Hoffmann
    const char *device = qemu_opt_get(opts, "path");
3171 dc375097 Gerd Hoffmann
3172 dc375097 Gerd Hoffmann
    if (device == NULL) {
3173 dc375097 Gerd Hoffmann
        error_setg(errp, "chardev: parallel: no device path given");
3174 dc375097 Gerd Hoffmann
        return;
3175 dc375097 Gerd Hoffmann
    }
3176 dc375097 Gerd Hoffmann
    backend->parallel = g_new0(ChardevHostdev, 1);
3177 dc375097 Gerd Hoffmann
    backend->parallel->device = g_strdup(device);
3178 dc375097 Gerd Hoffmann
}
3179 dc375097 Gerd Hoffmann
3180 548cbb36 Gerd Hoffmann
static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
3181 548cbb36 Gerd Hoffmann
                                Error **errp)
3182 548cbb36 Gerd Hoffmann
{
3183 548cbb36 Gerd Hoffmann
    const char *device = qemu_opt_get(opts, "path");
3184 548cbb36 Gerd Hoffmann
3185 548cbb36 Gerd Hoffmann
    if (device == NULL) {
3186 548cbb36 Gerd Hoffmann
        error_setg(errp, "chardev: pipe: no device path given");
3187 548cbb36 Gerd Hoffmann
        return;
3188 548cbb36 Gerd Hoffmann
    }
3189 548cbb36 Gerd Hoffmann
    backend->pipe = g_new0(ChardevHostdev, 1);
3190 548cbb36 Gerd Hoffmann
    backend->pipe->device = g_strdup(device);
3191 548cbb36 Gerd Hoffmann
}
3192 548cbb36 Gerd Hoffmann
3193 6a85e60c Lei Li
static void qemu_chr_parse_memory(QemuOpts *opts, ChardevBackend *backend,
3194 6a85e60c Lei Li
                                  Error **errp)
3195 1da48c65 Gerd Hoffmann
{
3196 1da48c65 Gerd Hoffmann
    int val;
3197 1da48c65 Gerd Hoffmann
3198 6a85e60c Lei Li
    backend->memory = g_new0(ChardevMemory, 1);
3199 1da48c65 Gerd Hoffmann
3200 1da48c65 Gerd Hoffmann
    val = qemu_opt_get_number(opts, "size", 0);
3201 1da48c65 Gerd Hoffmann
    if (val != 0) {
3202 1da48c65 Gerd Hoffmann
        backend->memory->has_size = true;
3203 1da48c65 Gerd Hoffmann
        backend->memory->size = val;
3204 1da48c65 Gerd Hoffmann
    }
3205 1da48c65 Gerd Hoffmann
}
3206 1da48c65 Gerd Hoffmann
3207 d654f34e Anthony Liguori
typedef struct CharDriver {
3208 191bc01b Gerd Hoffmann
    const char *name;
3209 2c5f4882 Gerd Hoffmann
    /* old, pre qapi */
3210 1f51470d Markus Armbruster
    CharDriverState *(*open)(QemuOpts *opts);
3211 2c5f4882 Gerd Hoffmann
    /* new, qapi-based */
3212 2c5f4882 Gerd Hoffmann
    int kind;
3213 2c5f4882 Gerd Hoffmann
    void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
3214 d654f34e Anthony Liguori
} CharDriver;
3215 d654f34e Anthony Liguori
3216 d654f34e Anthony Liguori
static GSList *backends;
3217 d654f34e Anthony Liguori
3218 d654f34e Anthony Liguori
void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *))
3219 d654f34e Anthony Liguori
{
3220 d654f34e Anthony Liguori
    CharDriver *s;
3221 d654f34e Anthony Liguori
3222 d654f34e Anthony Liguori
    s = g_malloc0(sizeof(*s));
3223 d654f34e Anthony Liguori
    s->name = g_strdup(name);
3224 d654f34e Anthony Liguori
    s->open = open;
3225 d654f34e Anthony Liguori
3226 d654f34e Anthony Liguori
    backends = g_slist_append(backends, s);
3227 d654f34e Anthony Liguori
}
3228 191bc01b Gerd Hoffmann
3229 2c5f4882 Gerd Hoffmann
void register_char_driver_qapi(const char *name, int kind,
3230 2c5f4882 Gerd Hoffmann
        void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
3231 2c5f4882 Gerd Hoffmann
{
3232 2c5f4882 Gerd Hoffmann
    CharDriver *s;
3233 2c5f4882 Gerd Hoffmann
3234 2c5f4882 Gerd Hoffmann
    s = g_malloc0(sizeof(*s));
3235 2c5f4882 Gerd Hoffmann
    s->name = g_strdup(name);
3236 2c5f4882 Gerd Hoffmann
    s->kind = kind;
3237 2c5f4882 Gerd Hoffmann
    s->parse = parse;
3238 2c5f4882 Gerd Hoffmann
3239 2c5f4882 Gerd Hoffmann
    backends = g_slist_append(backends, s);
3240 2c5f4882 Gerd Hoffmann
}
3241 2c5f4882 Gerd Hoffmann
3242 f69554b9 Anthony Liguori
CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
3243 bd2d80b2 Gerd Hoffmann
                                    void (*init)(struct CharDriverState *s),
3244 bd2d80b2 Gerd Hoffmann
                                    Error **errp)
3245 191bc01b Gerd Hoffmann
{
3246 d654f34e Anthony Liguori
    CharDriver *cd;
3247 191bc01b Gerd Hoffmann
    CharDriverState *chr;
3248 d654f34e Anthony Liguori
    GSList *i;
3249 191bc01b Gerd Hoffmann
3250 191bc01b Gerd Hoffmann
    if (qemu_opts_id(opts) == NULL) {
3251 312fd5f2 Markus Armbruster
        error_setg(errp, "chardev: no id specified");
3252 2274ae9d Gerd Hoffmann
        goto err;
3253 191bc01b Gerd Hoffmann
    }
3254 191bc01b Gerd Hoffmann
3255 1bbd185f Stefan Hajnoczi
    if (qemu_opt_get(opts, "backend") == NULL) {
3256 312fd5f2 Markus Armbruster
        error_setg(errp, "chardev: \"%s\" missing backend",
3257 bd2d80b2 Gerd Hoffmann
                   qemu_opts_id(opts));
3258 2274ae9d Gerd Hoffmann
        goto err;
3259 1bbd185f Stefan Hajnoczi
    }
3260 d654f34e Anthony Liguori
    for (i = backends; i; i = i->next) {
3261 d654f34e Anthony Liguori
        cd = i->data;
3262 d654f34e Anthony Liguori
3263 d654f34e Anthony Liguori
        if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) {
3264 191bc01b Gerd Hoffmann
            break;
3265 d654f34e Anthony Liguori
        }
3266 191bc01b Gerd Hoffmann
    }
3267 d654f34e Anthony Liguori
    if (i == NULL) {
3268 312fd5f2 Markus Armbruster
        error_setg(errp, "chardev: backend \"%s\" not found",
3269 bd2d80b2 Gerd Hoffmann
                   qemu_opt_get(opts, "backend"));
3270 d654f34e Anthony Liguori
        return NULL;
3271 191bc01b Gerd Hoffmann
    }
3272 191bc01b Gerd Hoffmann
3273 2c5f4882 Gerd Hoffmann
    if (!cd->open) {
3274 2c5f4882 Gerd Hoffmann
        /* using new, qapi init */
3275 2c5f4882 Gerd Hoffmann
        ChardevBackend *backend = g_new0(ChardevBackend, 1);
3276 2c5f4882 Gerd Hoffmann
        ChardevReturn *ret = NULL;
3277 2c5f4882 Gerd Hoffmann
        const char *id = qemu_opts_id(opts);
3278 edb2fb3c Gerd Hoffmann
        const char *bid = NULL;
3279 edb2fb3c Gerd Hoffmann
3280 edb2fb3c Gerd Hoffmann
        if (qemu_opt_get_bool(opts, "mux", 0)) {
3281 edb2fb3c Gerd Hoffmann
            bid = g_strdup_printf("%s-base", id);
3282 edb2fb3c Gerd Hoffmann
        }
3283 2c5f4882 Gerd Hoffmann
3284 2c5f4882 Gerd Hoffmann
        chr = NULL;
3285 2c5f4882 Gerd Hoffmann
        backend->kind = cd->kind;
3286 2c5f4882 Gerd Hoffmann
        if (cd->parse) {
3287 2c5f4882 Gerd Hoffmann
            cd->parse(opts, backend, errp);
3288 2c5f4882 Gerd Hoffmann
            if (error_is_set(errp)) {
3289 2c5f4882 Gerd Hoffmann
                goto qapi_out;
3290 2c5f4882 Gerd Hoffmann
            }
3291 2c5f4882 Gerd Hoffmann
        }
3292 edb2fb3c Gerd Hoffmann
        ret = qmp_chardev_add(bid ? bid : id, backend, errp);
3293 2c5f4882 Gerd Hoffmann
        if (error_is_set(errp)) {
3294 2c5f4882 Gerd Hoffmann
            goto qapi_out;
3295 2c5f4882 Gerd Hoffmann
        }
3296 edb2fb3c Gerd Hoffmann
3297 edb2fb3c Gerd Hoffmann
        if (bid) {
3298 edb2fb3c Gerd Hoffmann
            qapi_free_ChardevBackend(backend);
3299 edb2fb3c Gerd Hoffmann
            qapi_free_ChardevReturn(ret);
3300 edb2fb3c Gerd Hoffmann
            backend = g_new0(ChardevBackend, 1);
3301 edb2fb3c Gerd Hoffmann
            backend->mux = g_new0(ChardevMux, 1);
3302 edb2fb3c Gerd Hoffmann
            backend->kind = CHARDEV_BACKEND_KIND_MUX;
3303 edb2fb3c Gerd Hoffmann
            backend->mux->chardev = g_strdup(bid);
3304 edb2fb3c Gerd Hoffmann
            ret = qmp_chardev_add(id, backend, errp);
3305 edb2fb3c Gerd Hoffmann
            if (error_is_set(errp)) {
3306 edb2fb3c Gerd Hoffmann
                goto qapi_out;
3307 edb2fb3c Gerd Hoffmann
            }
3308 edb2fb3c Gerd Hoffmann
        }
3309 edb2fb3c Gerd Hoffmann
3310 2c5f4882 Gerd Hoffmann
        chr = qemu_chr_find(id);
3311 2c5f4882 Gerd Hoffmann
3312 2c5f4882 Gerd Hoffmann
    qapi_out:
3313 2c5f4882 Gerd Hoffmann
        qapi_free_ChardevBackend(backend);
3314 2c5f4882 Gerd Hoffmann
        qapi_free_ChardevReturn(ret);
3315 2c5f4882 Gerd Hoffmann
        return chr;
3316 2c5f4882 Gerd Hoffmann
    }
3317 2c5f4882 Gerd Hoffmann
3318 d654f34e Anthony Liguori
    chr = cd->open(opts);
3319 1f51470d Markus Armbruster
    if (!chr) {
3320 312fd5f2 Markus Armbruster
        error_setg(errp, "chardev: opening backend \"%s\" failed",
3321 bd2d80b2 Gerd Hoffmann
                   qemu_opt_get(opts, "backend"));
3322 2274ae9d Gerd Hoffmann
        goto err;
3323 191bc01b Gerd Hoffmann
    }
3324 191bc01b Gerd Hoffmann
3325 191bc01b Gerd Hoffmann
    if (!chr->filename)
3326 7267c094 Anthony Liguori
        chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
3327 191bc01b Gerd Hoffmann
    chr->init = init;
3328 72cf2d4f Blue Swirl
    QTAILQ_INSERT_TAIL(&chardevs, chr, next);
3329 7591c5c1 Gerd Hoffmann
3330 7591c5c1 Gerd Hoffmann
    if (qemu_opt_get_bool(opts, "mux", 0)) {
3331 7591c5c1 Gerd Hoffmann
        CharDriverState *base = chr;
3332 7591c5c1 Gerd Hoffmann
        int len = strlen(qemu_opts_id(opts)) + 6;
3333 7267c094 Anthony Liguori
        base->label = g_malloc(len);
3334 7591c5c1 Gerd Hoffmann
        snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
3335 7591c5c1 Gerd Hoffmann
        chr = qemu_chr_open_mux(base);
3336 7591c5c1 Gerd Hoffmann
        chr->filename = base->filename;
3337 d5b27167 Kusanagi Kouichi
        chr->avail_connections = MAX_MUX;
3338 72cf2d4f Blue Swirl
        QTAILQ_INSERT_TAIL(&chardevs, chr, next);
3339 d5b27167 Kusanagi Kouichi
    } else {
3340 d5b27167 Kusanagi Kouichi
        chr->avail_connections = 1;
3341 7591c5c1 Gerd Hoffmann
    }
3342 7267c094 Anthony Liguori
    chr->label = g_strdup(qemu_opts_id(opts));
3343 2274ae9d Gerd Hoffmann
    chr->opts = opts;
3344 191bc01b Gerd Hoffmann
    return chr;
3345 2274ae9d Gerd Hoffmann
3346 2274ae9d Gerd Hoffmann
err:
3347 2274ae9d Gerd Hoffmann
    qemu_opts_del(opts);
3348 2274ae9d Gerd Hoffmann
    return NULL;
3349 191bc01b Gerd Hoffmann
}
3350 191bc01b Gerd Hoffmann
3351 27143a44 Anthony Liguori
CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
3352 6f97dba0 aliguori
{
3353 6f97dba0 aliguori
    const char *p;
3354 6f97dba0 aliguori
    CharDriverState *chr;
3355 191bc01b Gerd Hoffmann
    QemuOpts *opts;
3356 bd2d80b2 Gerd Hoffmann
    Error *err = NULL;
3357 191bc01b Gerd Hoffmann
3358 c845f401 Gerd Hoffmann
    if (strstart(filename, "chardev:", &p)) {
3359 c845f401 Gerd Hoffmann
        return qemu_chr_find(p);
3360 c845f401 Gerd Hoffmann
    }
3361 c845f401 Gerd Hoffmann
3362 191bc01b Gerd Hoffmann
    opts = qemu_chr_parse_compat(label, filename);
3363 7e1b35b4 Gerd Hoffmann
    if (!opts)
3364 7e1b35b4 Gerd Hoffmann
        return NULL;
3365 6f97dba0 aliguori
3366 bd2d80b2 Gerd Hoffmann
    chr = qemu_chr_new_from_opts(opts, init, &err);
3367 bd2d80b2 Gerd Hoffmann
    if (error_is_set(&err)) {
3368 bd2d80b2 Gerd Hoffmann
        fprintf(stderr, "%s\n", error_get_pretty(err));
3369 bd2d80b2 Gerd Hoffmann
        error_free(err);
3370 bd2d80b2 Gerd Hoffmann
    }
3371 7e1b35b4 Gerd Hoffmann
    if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
3372 456d6069 Hans de Goede
        qemu_chr_fe_claim_no_fail(chr);
3373 7e1b35b4 Gerd Hoffmann
        monitor_init(chr, MONITOR_USE_READLINE);
3374 6f97dba0 aliguori
    }
3375 6f97dba0 aliguori
    return chr;
3376 6f97dba0 aliguori
}
3377 6f97dba0 aliguori
3378 15f31519 Anthony Liguori
void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
3379 c48855e1 Paolo Bonzini
{
3380 c48855e1 Paolo Bonzini
    if (chr->chr_set_echo) {
3381 c48855e1 Paolo Bonzini
        chr->chr_set_echo(chr, echo);
3382 c48855e1 Paolo Bonzini
    }
3383 c48855e1 Paolo Bonzini
}
3384 c48855e1 Paolo Bonzini
3385 8e25daa8 Hans de Goede
void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open)
3386 7c32c4fe Hans de Goede
{
3387 8e25daa8 Hans de Goede
    if (chr->fe_open == fe_open) {
3388 c0c4bd2c Hans de Goede
        return;
3389 c0c4bd2c Hans de Goede
    }
3390 8e25daa8 Hans de Goede
    chr->fe_open = fe_open;
3391 574b711a Hans de Goede
    if (chr->chr_set_fe_open) {
3392 574b711a Hans de Goede
        chr->chr_set_fe_open(chr, fe_open);
3393 7c32c4fe Hans de Goede
    }
3394 7c32c4fe Hans de Goede
}
3395 7c32c4fe Hans de Goede
3396 2c8a5942 Kevin Wolf
int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
3397 2c8a5942 Kevin Wolf
                          GIOFunc func, void *user_data)
3398 23673ca7 Anthony Liguori
{
3399 23673ca7 Anthony Liguori
    GSource *src;
3400 23673ca7 Anthony Liguori
    guint tag;
3401 23673ca7 Anthony Liguori
3402 23673ca7 Anthony Liguori
    if (s->chr_add_watch == NULL) {
3403 23673ca7 Anthony Liguori
        return -ENOSYS;
3404 23673ca7 Anthony Liguori
    }
3405 23673ca7 Anthony Liguori
3406 23673ca7 Anthony Liguori
    src = s->chr_add_watch(s, cond);
3407 23673ca7 Anthony Liguori
    g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
3408 23673ca7 Anthony Liguori
    tag = g_source_attach(src, NULL);
3409 23673ca7 Anthony Liguori
    g_source_unref(src);
3410 23673ca7 Anthony Liguori
3411 23673ca7 Anthony Liguori
    return tag;
3412 23673ca7 Anthony Liguori
}
3413 23673ca7 Anthony Liguori
3414 44c473de Hans de Goede
int qemu_chr_fe_claim(CharDriverState *s)
3415 44c473de Hans de Goede
{
3416 44c473de Hans de Goede
    if (s->avail_connections < 1) {
3417 44c473de Hans de Goede
        return -1;
3418 44c473de Hans de Goede
    }
3419 44c473de Hans de Goede
    s->avail_connections--;
3420 44c473de Hans de Goede
    return 0;
3421 44c473de Hans de Goede
}
3422 44c473de Hans de Goede
3423 44c473de Hans de Goede
void qemu_chr_fe_claim_no_fail(CharDriverState *s)
3424 44c473de Hans de Goede
{
3425 44c473de Hans de Goede
    if (qemu_chr_fe_claim(s) != 0) {
3426 44c473de Hans de Goede
        fprintf(stderr, "%s: error chardev \"%s\" already used\n",
3427 44c473de Hans de Goede
                __func__, s->label);
3428 44c473de Hans de Goede
        exit(1);
3429 44c473de Hans de Goede
    }
3430 44c473de Hans de Goede
}
3431 44c473de Hans de Goede
3432 44c473de Hans de Goede
void qemu_chr_fe_release(CharDriverState *s)
3433 44c473de Hans de Goede
{
3434 44c473de Hans de Goede
    s->avail_connections++;
3435 44c473de Hans de Goede
}
3436 44c473de Hans de Goede
3437 70f24fb6 Anthony Liguori
void qemu_chr_delete(CharDriverState *chr)
3438 6f97dba0 aliguori
{
3439 72cf2d4f Blue Swirl
    QTAILQ_REMOVE(&chardevs, chr, next);
3440 2274ae9d Gerd Hoffmann
    if (chr->chr_close) {
3441 6f97dba0 aliguori
        chr->chr_close(chr);
3442 2274ae9d Gerd Hoffmann
    }
3443 7267c094 Anthony Liguori
    g_free(chr->filename);
3444 7267c094 Anthony Liguori
    g_free(chr->label);
3445 2274ae9d Gerd Hoffmann
    if (chr->opts) {
3446 2274ae9d Gerd Hoffmann
        qemu_opts_del(chr->opts);
3447 2274ae9d Gerd Hoffmann
    }
3448 7267c094 Anthony Liguori
    g_free(chr);
3449 6f97dba0 aliguori
}
3450 6f97dba0 aliguori
3451 c5a415a0 Luiz Capitulino
ChardevInfoList *qmp_query_chardev(Error **errp)
3452 6f97dba0 aliguori
{
3453 c5a415a0 Luiz Capitulino
    ChardevInfoList *chr_list = NULL;
3454 6f97dba0 aliguori
    CharDriverState *chr;
3455 6f97dba0 aliguori
3456 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(chr, &chardevs, next) {
3457 c5a415a0 Luiz Capitulino
        ChardevInfoList *info = g_malloc0(sizeof(*info));
3458 c5a415a0 Luiz Capitulino
        info->value = g_malloc0(sizeof(*info->value));
3459 c5a415a0 Luiz Capitulino
        info->value->label = g_strdup(chr->label);
3460 c5a415a0 Luiz Capitulino
        info->value->filename = g_strdup(chr->filename);
3461 c5a415a0 Luiz Capitulino
3462 c5a415a0 Luiz Capitulino
        info->next = chr_list;
3463 c5a415a0 Luiz Capitulino
        chr_list = info;
3464 6f97dba0 aliguori
    }
3465 588b3832 Luiz Capitulino
3466 c5a415a0 Luiz Capitulino
    return chr_list;
3467 6f97dba0 aliguori
}
3468 c845f401 Gerd Hoffmann
3469 c845f401 Gerd Hoffmann
CharDriverState *qemu_chr_find(const char *name)
3470 c845f401 Gerd Hoffmann
{
3471 c845f401 Gerd Hoffmann
    CharDriverState *chr;
3472 c845f401 Gerd Hoffmann
3473 72cf2d4f Blue Swirl
    QTAILQ_FOREACH(chr, &chardevs, next) {
3474 c845f401 Gerd Hoffmann
        if (strcmp(chr->label, name) != 0)
3475 c845f401 Gerd Hoffmann
            continue;
3476 c845f401 Gerd Hoffmann
        return chr;
3477 c845f401 Gerd Hoffmann
    }
3478 c845f401 Gerd Hoffmann
    return NULL;
3479 c845f401 Gerd Hoffmann
}
3480 0beb4942 Anthony Liguori
3481 0beb4942 Anthony Liguori
/* Get a character (serial) device interface.  */
3482 0beb4942 Anthony Liguori
CharDriverState *qemu_char_get_next_serial(void)
3483 0beb4942 Anthony Liguori
{
3484 0beb4942 Anthony Liguori
    static int next_serial;
3485 456d6069 Hans de Goede
    CharDriverState *chr;
3486 0beb4942 Anthony Liguori
3487 0beb4942 Anthony Liguori
    /* FIXME: This function needs to go away: use chardev properties!  */
3488 456d6069 Hans de Goede
3489 456d6069 Hans de Goede
    while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) {
3490 456d6069 Hans de Goede
        chr = serial_hds[next_serial++];
3491 456d6069 Hans de Goede
        qemu_chr_fe_claim_no_fail(chr);
3492 456d6069 Hans de Goede
        return chr;
3493 456d6069 Hans de Goede
    }
3494 456d6069 Hans de Goede
    return NULL;
3495 0beb4942 Anthony Liguori
}
3496 0beb4942 Anthony Liguori
3497 4d454574 Paolo Bonzini
QemuOptsList qemu_chardev_opts = {
3498 4d454574 Paolo Bonzini
    .name = "chardev",
3499 4d454574 Paolo Bonzini
    .implied_opt_name = "backend",
3500 4d454574 Paolo Bonzini
    .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
3501 4d454574 Paolo Bonzini
    .desc = {
3502 4d454574 Paolo Bonzini
        {
3503 4d454574 Paolo Bonzini
            .name = "backend",
3504 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
3505 4d454574 Paolo Bonzini
        },{
3506 4d454574 Paolo Bonzini
            .name = "path",
3507 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
3508 4d454574 Paolo Bonzini
        },{
3509 4d454574 Paolo Bonzini
            .name = "host",
3510 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
3511 4d454574 Paolo Bonzini
        },{
3512 4d454574 Paolo Bonzini
            .name = "port",
3513 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
3514 4d454574 Paolo Bonzini
        },{
3515 4d454574 Paolo Bonzini
            .name = "localaddr",
3516 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
3517 4d454574 Paolo Bonzini
        },{
3518 4d454574 Paolo Bonzini
            .name = "localport",
3519 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
3520 4d454574 Paolo Bonzini
        },{
3521 4d454574 Paolo Bonzini
            .name = "to",
3522 4d454574 Paolo Bonzini
            .type = QEMU_OPT_NUMBER,
3523 4d454574 Paolo Bonzini
        },{
3524 4d454574 Paolo Bonzini
            .name = "ipv4",
3525 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3526 4d454574 Paolo Bonzini
        },{
3527 4d454574 Paolo Bonzini
            .name = "ipv6",
3528 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3529 4d454574 Paolo Bonzini
        },{
3530 4d454574 Paolo Bonzini
            .name = "wait",
3531 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3532 4d454574 Paolo Bonzini
        },{
3533 4d454574 Paolo Bonzini
            .name = "server",
3534 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3535 4d454574 Paolo Bonzini
        },{
3536 4d454574 Paolo Bonzini
            .name = "delay",
3537 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3538 4d454574 Paolo Bonzini
        },{
3539 4d454574 Paolo Bonzini
            .name = "telnet",
3540 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3541 4d454574 Paolo Bonzini
        },{
3542 4d454574 Paolo Bonzini
            .name = "width",
3543 4d454574 Paolo Bonzini
            .type = QEMU_OPT_NUMBER,
3544 4d454574 Paolo Bonzini
        },{
3545 4d454574 Paolo Bonzini
            .name = "height",
3546 4d454574 Paolo Bonzini
            .type = QEMU_OPT_NUMBER,
3547 4d454574 Paolo Bonzini
        },{
3548 4d454574 Paolo Bonzini
            .name = "cols",
3549 4d454574 Paolo Bonzini
            .type = QEMU_OPT_NUMBER,
3550 4d454574 Paolo Bonzini
        },{
3551 4d454574 Paolo Bonzini
            .name = "rows",
3552 4d454574 Paolo Bonzini
            .type = QEMU_OPT_NUMBER,
3553 4d454574 Paolo Bonzini
        },{
3554 4d454574 Paolo Bonzini
            .name = "mux",
3555 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3556 4d454574 Paolo Bonzini
        },{
3557 4d454574 Paolo Bonzini
            .name = "signal",
3558 4d454574 Paolo Bonzini
            .type = QEMU_OPT_BOOL,
3559 4d454574 Paolo Bonzini
        },{
3560 4d454574 Paolo Bonzini
            .name = "name",
3561 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
3562 4d454574 Paolo Bonzini
        },{
3563 4d454574 Paolo Bonzini
            .name = "debug",
3564 4d454574 Paolo Bonzini
            .type = QEMU_OPT_NUMBER,
3565 51767e7c Lei Li
        },{
3566 3949e594 Markus Armbruster
            .name = "size",
3567 de1cc36e Markus Armbruster
            .type = QEMU_OPT_SIZE,
3568 4d454574 Paolo Bonzini
        },
3569 4d454574 Paolo Bonzini
        { /* end of list */ }
3570 4d454574 Paolo Bonzini
    },
3571 4d454574 Paolo Bonzini
};
3572 f1a1a356 Gerd Hoffmann
3573 ffbdbe59 Gerd Hoffmann
#ifdef _WIN32
3574 ffbdbe59 Gerd Hoffmann
3575 ffbdbe59 Gerd Hoffmann
static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
3576 ffbdbe59 Gerd Hoffmann
{
3577 ffbdbe59 Gerd Hoffmann
    HANDLE out;
3578 ffbdbe59 Gerd Hoffmann
3579 ffbdbe59 Gerd Hoffmann
    if (file->in) {
3580 ffbdbe59 Gerd Hoffmann
        error_setg(errp, "input file not supported");
3581 ffbdbe59 Gerd Hoffmann
        return NULL;
3582 ffbdbe59 Gerd Hoffmann
    }
3583 ffbdbe59 Gerd Hoffmann
3584 ffbdbe59 Gerd Hoffmann
    out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3585 ffbdbe59 Gerd Hoffmann
                     OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3586 ffbdbe59 Gerd Hoffmann
    if (out == INVALID_HANDLE_VALUE) {
3587 ffbdbe59 Gerd Hoffmann
        error_setg(errp, "open %s failed", file->out);
3588 ffbdbe59 Gerd Hoffmann
        return NULL;
3589 ffbdbe59 Gerd Hoffmann
    }
3590 ffbdbe59 Gerd Hoffmann
    return qemu_chr_open_win_file(out);
3591 ffbdbe59 Gerd Hoffmann
}
3592 ffbdbe59 Gerd Hoffmann
3593 d36b2b90 Markus Armbruster
static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
3594 d36b2b90 Markus Armbruster
                                                Error **errp)
3595 d59044ef Gerd Hoffmann
{
3596 d36b2b90 Markus Armbruster
    return qemu_chr_open_win_path(serial->device);
3597 d36b2b90 Markus Armbruster
}
3598 d36b2b90 Markus Armbruster
3599 d36b2b90 Markus Armbruster
static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
3600 d36b2b90 Markus Armbruster
                                                  Error **errp)
3601 d36b2b90 Markus Armbruster
{
3602 d36b2b90 Markus Armbruster
    error_setg(errp, "character device backend type 'parallel' not supported");
3603 d36b2b90 Markus Armbruster
    return NULL;
3604 d59044ef Gerd Hoffmann
}
3605 d59044ef Gerd Hoffmann
3606 ffbdbe59 Gerd Hoffmann
#else /* WIN32 */
3607 ffbdbe59 Gerd Hoffmann
3608 ffbdbe59 Gerd Hoffmann
static int qmp_chardev_open_file_source(char *src, int flags,
3609 ffbdbe59 Gerd Hoffmann
                                        Error **errp)
3610 ffbdbe59 Gerd Hoffmann
{
3611 ffbdbe59 Gerd Hoffmann
    int fd = -1;
3612 ffbdbe59 Gerd Hoffmann
3613 ffbdbe59 Gerd Hoffmann
    TFR(fd = qemu_open(src, flags, 0666));
3614 ffbdbe59 Gerd Hoffmann
    if (fd == -1) {
3615 ffbdbe59 Gerd Hoffmann
        error_setg(errp, "open %s: %s", src, strerror(errno));
3616 ffbdbe59 Gerd Hoffmann
    }
3617 ffbdbe59 Gerd Hoffmann
    return fd;
3618 ffbdbe59 Gerd Hoffmann
}
3619 ffbdbe59 Gerd Hoffmann
3620 ffbdbe59 Gerd Hoffmann
static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
3621 ffbdbe59 Gerd Hoffmann
{
3622 ffbdbe59 Gerd Hoffmann
    int flags, in = -1, out = -1;
3623 ffbdbe59 Gerd Hoffmann
3624 ffbdbe59 Gerd Hoffmann
    flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
3625 ffbdbe59 Gerd Hoffmann
    out = qmp_chardev_open_file_source(file->out, flags, errp);
3626 ffbdbe59 Gerd Hoffmann
    if (error_is_set(errp)) {
3627 ffbdbe59 Gerd Hoffmann
        return NULL;
3628 ffbdbe59 Gerd Hoffmann
    }
3629 ffbdbe59 Gerd Hoffmann
3630 ffbdbe59 Gerd Hoffmann
    if (file->in) {
3631 ffbdbe59 Gerd Hoffmann
        flags = O_RDONLY;
3632 ffbdbe59 Gerd Hoffmann
        in = qmp_chardev_open_file_source(file->in, flags, errp);
3633 ffbdbe59 Gerd Hoffmann
        if (error_is_set(errp)) {
3634 ffbdbe59 Gerd Hoffmann
            qemu_close(out);
3635 ffbdbe59 Gerd Hoffmann
            return NULL;
3636 ffbdbe59 Gerd Hoffmann
        }
3637 ffbdbe59 Gerd Hoffmann
    }
3638 ffbdbe59 Gerd Hoffmann
3639 ffbdbe59 Gerd Hoffmann
    return qemu_chr_open_fd(in, out);
3640 ffbdbe59 Gerd Hoffmann
}
3641 ffbdbe59 Gerd Hoffmann
3642 d36b2b90 Markus Armbruster
static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
3643 d36b2b90 Markus Armbruster
                                                Error **errp)
3644 d59044ef Gerd Hoffmann
{
3645 d59044ef Gerd Hoffmann
#ifdef HAVE_CHARDEV_TTY
3646 d36b2b90 Markus Armbruster
    int fd;
3647 d36b2b90 Markus Armbruster
3648 d36b2b90 Markus Armbruster
    fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
3649 d36b2b90 Markus Armbruster
    if (error_is_set(errp)) {
3650 d36b2b90 Markus Armbruster
        return NULL;
3651 39099991 Peter Maydell
    }
3652 f9e8cacc Stefan Hajnoczi
    qemu_set_nonblock(fd);
3653 d36b2b90 Markus Armbruster
    return qemu_chr_open_tty_fd(fd);
3654 d36b2b90 Markus Armbruster
#else
3655 d36b2b90 Markus Armbruster
    error_setg(errp, "character device backend type 'serial' not supported");
3656 d36b2b90 Markus Armbruster
    return NULL;
3657 d59044ef Gerd Hoffmann
#endif
3658 d36b2b90 Markus Armbruster
}
3659 d36b2b90 Markus Armbruster
3660 d36b2b90 Markus Armbruster
static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
3661 d36b2b90 Markus Armbruster
                                                  Error **errp)
3662 d36b2b90 Markus Armbruster
{
3663 88a946d3 Gerd Hoffmann
#ifdef HAVE_CHARDEV_PARPORT
3664 d36b2b90 Markus Armbruster
    int fd;
3665 d36b2b90 Markus Armbruster
3666 d36b2b90 Markus Armbruster
    fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
3667 d36b2b90 Markus Armbruster
    if (error_is_set(errp)) {
3668 d59044ef Gerd Hoffmann
        return NULL;
3669 d59044ef Gerd Hoffmann
    }
3670 d36b2b90 Markus Armbruster
    return qemu_chr_open_pp_fd(fd);
3671 d36b2b90 Markus Armbruster
#else
3672 d36b2b90 Markus Armbruster
    error_setg(errp, "character device backend type 'parallel' not supported");
3673 d36b2b90 Markus Armbruster
    return NULL;
3674 d36b2b90 Markus Armbruster
#endif
3675 d59044ef Gerd Hoffmann
}
3676 d59044ef Gerd Hoffmann
3677 ffbdbe59 Gerd Hoffmann
#endif /* WIN32 */
3678 ffbdbe59 Gerd Hoffmann
3679 f6bd5d6e Gerd Hoffmann
static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
3680 f6bd5d6e Gerd Hoffmann
                                                Error **errp)
3681 f6bd5d6e Gerd Hoffmann
{
3682 f6bd5d6e Gerd Hoffmann
    SocketAddress *addr = sock->addr;
3683 f6bd5d6e Gerd Hoffmann
    bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
3684 f6bd5d6e Gerd Hoffmann
    bool is_listen      = sock->has_server  ? sock->server  : true;
3685 f6bd5d6e Gerd Hoffmann
    bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
3686 f6bd5d6e Gerd Hoffmann
    bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
3687 f6bd5d6e Gerd Hoffmann
    int fd;
3688 f6bd5d6e Gerd Hoffmann
3689 f6bd5d6e Gerd Hoffmann
    if (is_listen) {
3690 f6bd5d6e Gerd Hoffmann
        fd = socket_listen(addr, errp);
3691 f6bd5d6e Gerd Hoffmann
    } else {
3692 f6bd5d6e Gerd Hoffmann
        fd = socket_connect(addr, errp, NULL, NULL);
3693 f6bd5d6e Gerd Hoffmann
    }
3694 f6bd5d6e Gerd Hoffmann
    if (error_is_set(errp)) {
3695 f6bd5d6e Gerd Hoffmann
        return NULL;
3696 f6bd5d6e Gerd Hoffmann
    }
3697 f6bd5d6e Gerd Hoffmann
    return qemu_chr_open_socket_fd(fd, do_nodelay, is_listen,
3698 f6bd5d6e Gerd Hoffmann
                                   is_telnet, is_waitconnect, errp);
3699 f6bd5d6e Gerd Hoffmann
}
3700 f6bd5d6e Gerd Hoffmann
3701 08d0ab3f Lei Li
static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp,
3702 08d0ab3f Lei Li
                                             Error **errp)
3703 3ecc059d Gerd Hoffmann
{
3704 3ecc059d Gerd Hoffmann
    int fd;
3705 3ecc059d Gerd Hoffmann
3706 08d0ab3f Lei Li
    fd = socket_dgram(udp->remote, udp->local, errp);
3707 3ecc059d Gerd Hoffmann
    if (error_is_set(errp)) {
3708 3ecc059d Gerd Hoffmann
        return NULL;
3709 3ecc059d Gerd Hoffmann
    }
3710 3ecc059d Gerd Hoffmann
    return qemu_chr_open_udp_fd(fd);
3711 3ecc059d Gerd Hoffmann
}
3712 3ecc059d Gerd Hoffmann
3713 f1a1a356 Gerd Hoffmann
ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
3714 f1a1a356 Gerd Hoffmann
                               Error **errp)
3715 f1a1a356 Gerd Hoffmann
{
3716 f1a1a356 Gerd Hoffmann
    ChardevReturn *ret = g_new0(ChardevReturn, 1);
3717 edb2fb3c Gerd Hoffmann
    CharDriverState *base, *chr = NULL;
3718 f1a1a356 Gerd Hoffmann
3719 f1a1a356 Gerd Hoffmann
    chr = qemu_chr_find(id);
3720 f1a1a356 Gerd Hoffmann
    if (chr) {
3721 f1a1a356 Gerd Hoffmann
        error_setg(errp, "Chardev '%s' already exists", id);
3722 f1a1a356 Gerd Hoffmann
        g_free(ret);
3723 f1a1a356 Gerd Hoffmann
        return NULL;
3724 f1a1a356 Gerd Hoffmann
    }
3725 f1a1a356 Gerd Hoffmann
3726 f1a1a356 Gerd Hoffmann
    switch (backend->kind) {
3727 ffbdbe59 Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_FILE:
3728 ffbdbe59 Gerd Hoffmann
        chr = qmp_chardev_open_file(backend->file, errp);
3729 ffbdbe59 Gerd Hoffmann
        break;
3730 d36b2b90 Markus Armbruster
    case CHARDEV_BACKEND_KIND_SERIAL:
3731 d36b2b90 Markus Armbruster
        chr = qmp_chardev_open_serial(backend->serial, errp);
3732 d36b2b90 Markus Armbruster
        break;
3733 d36b2b90 Markus Armbruster
    case CHARDEV_BACKEND_KIND_PARALLEL:
3734 d36b2b90 Markus Armbruster
        chr = qmp_chardev_open_parallel(backend->parallel, errp);
3735 d59044ef Gerd Hoffmann
        break;
3736 548cbb36 Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_PIPE:
3737 548cbb36 Gerd Hoffmann
        chr = qemu_chr_open_pipe(backend->pipe);
3738 548cbb36 Gerd Hoffmann
        break;
3739 f6bd5d6e Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_SOCKET:
3740 f6bd5d6e Gerd Hoffmann
        chr = qmp_chardev_open_socket(backend->socket, errp);
3741 f6bd5d6e Gerd Hoffmann
        break;
3742 08d0ab3f Lei Li
    case CHARDEV_BACKEND_KIND_UDP:
3743 08d0ab3f Lei Li
        chr = qmp_chardev_open_udp(backend->udp, errp);
3744 3ecc059d Gerd Hoffmann
        break;
3745 0a1a7fab Gerd Hoffmann
#ifdef HAVE_CHARDEV_TTY
3746 0a1a7fab Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_PTY:
3747 e68c5958 Gerd Hoffmann
        chr = qemu_chr_open_pty(id, ret);
3748 0a1a7fab Gerd Hoffmann
        break;
3749 0a1a7fab Gerd Hoffmann
#endif
3750 f1a1a356 Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_NULL:
3751 80dca9e6 Gerd Hoffmann
        chr = qemu_chr_open_null();
3752 f1a1a356 Gerd Hoffmann
        break;
3753 edb2fb3c Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_MUX:
3754 edb2fb3c Gerd Hoffmann
        base = qemu_chr_find(backend->mux->chardev);
3755 edb2fb3c Gerd Hoffmann
        if (base == NULL) {
3756 edb2fb3c Gerd Hoffmann
            error_setg(errp, "mux: base chardev %s not found",
3757 edb2fb3c Gerd Hoffmann
                       backend->mux->chardev);
3758 edb2fb3c Gerd Hoffmann
            break;
3759 edb2fb3c Gerd Hoffmann
        }
3760 edb2fb3c Gerd Hoffmann
        chr = qemu_chr_open_mux(base);
3761 edb2fb3c Gerd Hoffmann
        break;
3762 f5a51cab Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_MSMOUSE:
3763 f5a51cab Gerd Hoffmann
        chr = qemu_chr_open_msmouse();
3764 f5a51cab Gerd Hoffmann
        break;
3765 2d57286d Gerd Hoffmann
#ifdef CONFIG_BRLAPI
3766 2d57286d Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_BRAILLE:
3767 2d57286d Gerd Hoffmann
        chr = chr_baum_init();
3768 2d57286d Gerd Hoffmann
        break;
3769 2d57286d Gerd Hoffmann
#endif
3770 7c358031 Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_STDIO:
3771 7c358031 Gerd Hoffmann
        chr = qemu_chr_open_stdio(backend->stdio);
3772 7c358031 Gerd Hoffmann
        break;
3773 d9ac374f Gerd Hoffmann
#ifdef _WIN32
3774 d9ac374f Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_CONSOLE:
3775 d9ac374f Gerd Hoffmann
        chr = qemu_chr_open_win_con();
3776 d9ac374f Gerd Hoffmann
        break;
3777 d9ac374f Gerd Hoffmann
#endif
3778 cd153e2a Gerd Hoffmann
#ifdef CONFIG_SPICE
3779 cd153e2a Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_SPICEVMC:
3780 cd153e2a Gerd Hoffmann
        chr = qemu_chr_open_spice_vmc(backend->spicevmc->type);
3781 cd153e2a Gerd Hoffmann
        break;
3782 cd153e2a Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_SPICEPORT:
3783 cd153e2a Gerd Hoffmann
        chr = qemu_chr_open_spice_port(backend->spiceport->fqdn);
3784 cd153e2a Gerd Hoffmann
        break;
3785 cd153e2a Gerd Hoffmann
#endif
3786 702ec69c Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_VC:
3787 702ec69c Gerd Hoffmann
        chr = vc_init(backend->vc);
3788 702ec69c Gerd Hoffmann
        break;
3789 1da48c65 Gerd Hoffmann
    case CHARDEV_BACKEND_KIND_MEMORY:
3790 6a85e60c Lei Li
        chr = qemu_chr_open_memory(backend->memory, errp);
3791 1da48c65 Gerd Hoffmann
        break;
3792 f1a1a356 Gerd Hoffmann
    default:
3793 f1a1a356 Gerd Hoffmann
        error_setg(errp, "unknown chardev backend (%d)", backend->kind);
3794 f1a1a356 Gerd Hoffmann
        break;
3795 f1a1a356 Gerd Hoffmann
    }
3796 f1a1a356 Gerd Hoffmann
3797 f1a1a356 Gerd Hoffmann
    if (chr == NULL && !error_is_set(errp)) {
3798 f1a1a356 Gerd Hoffmann
        error_setg(errp, "Failed to create chardev");
3799 f1a1a356 Gerd Hoffmann
    }
3800 f1a1a356 Gerd Hoffmann
    if (chr) {
3801 f1a1a356 Gerd Hoffmann
        chr->label = g_strdup(id);
3802 edb2fb3c Gerd Hoffmann
        chr->avail_connections =
3803 edb2fb3c Gerd Hoffmann
            (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
3804 60d95386 Gerd Hoffmann
        if (!chr->filename) {
3805 60d95386 Gerd Hoffmann
            chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
3806 60d95386 Gerd Hoffmann
        }
3807 f1a1a356 Gerd Hoffmann
        QTAILQ_INSERT_TAIL(&chardevs, chr, next);
3808 f1a1a356 Gerd Hoffmann
        return ret;
3809 f1a1a356 Gerd Hoffmann
    } else {
3810 f1a1a356 Gerd Hoffmann
        g_free(ret);
3811 f1a1a356 Gerd Hoffmann
        return NULL;
3812 f1a1a356 Gerd Hoffmann
    }
3813 f1a1a356 Gerd Hoffmann
}
3814 f1a1a356 Gerd Hoffmann
3815 f1a1a356 Gerd Hoffmann
void qmp_chardev_remove(const char *id, Error **errp)
3816 f1a1a356 Gerd Hoffmann
{
3817 f1a1a356 Gerd Hoffmann
    CharDriverState *chr;
3818 f1a1a356 Gerd Hoffmann
3819 f1a1a356 Gerd Hoffmann
    chr = qemu_chr_find(id);
3820 f1a1a356 Gerd Hoffmann
    if (NULL == chr) {
3821 f1a1a356 Gerd Hoffmann
        error_setg(errp, "Chardev '%s' not found", id);
3822 f1a1a356 Gerd Hoffmann
        return;
3823 f1a1a356 Gerd Hoffmann
    }
3824 f1a1a356 Gerd Hoffmann
    if (chr->chr_can_read || chr->chr_read ||
3825 f1a1a356 Gerd Hoffmann
        chr->chr_event || chr->handler_opaque) {
3826 f1a1a356 Gerd Hoffmann
        error_setg(errp, "Chardev '%s' is busy", id);
3827 f1a1a356 Gerd Hoffmann
        return;
3828 f1a1a356 Gerd Hoffmann
    }
3829 f1a1a356 Gerd Hoffmann
    qemu_chr_delete(chr);
3830 f1a1a356 Gerd Hoffmann
}
3831 d654f34e Anthony Liguori
3832 d654f34e Anthony Liguori
static void register_types(void)
3833 d654f34e Anthony Liguori
{
3834 80dca9e6 Gerd Hoffmann
    register_char_driver_qapi("null", CHARDEV_BACKEND_KIND_NULL, NULL);
3835 d654f34e Anthony Liguori
    register_char_driver("socket", qemu_chr_open_socket);
3836 d654f34e Anthony Liguori
    register_char_driver("udp", qemu_chr_open_udp);
3837 1da48c65 Gerd Hoffmann
    register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY,
3838 6a85e60c Lei Li
                              qemu_chr_parse_memory);
3839 846e2e49 Gerd Hoffmann
    register_char_driver_qapi("file", CHARDEV_BACKEND_KIND_FILE,
3840 846e2e49 Gerd Hoffmann
                              qemu_chr_parse_file_out);
3841 7c358031 Gerd Hoffmann
    register_char_driver_qapi("stdio", CHARDEV_BACKEND_KIND_STDIO,
3842 7c358031 Gerd Hoffmann
                              qemu_chr_parse_stdio);
3843 0f1cb51d Gerd Hoffmann
    register_char_driver_qapi("serial", CHARDEV_BACKEND_KIND_SERIAL,
3844 0f1cb51d Gerd Hoffmann
                              qemu_chr_parse_serial);
3845 0f1cb51d Gerd Hoffmann
    register_char_driver_qapi("tty", CHARDEV_BACKEND_KIND_SERIAL,
3846 0f1cb51d Gerd Hoffmann
                              qemu_chr_parse_serial);
3847 dc375097 Gerd Hoffmann
    register_char_driver_qapi("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
3848 dc375097 Gerd Hoffmann
                              qemu_chr_parse_parallel);
3849 dc375097 Gerd Hoffmann
    register_char_driver_qapi("parport", CHARDEV_BACKEND_KIND_PARALLEL,
3850 dc375097 Gerd Hoffmann
                              qemu_chr_parse_parallel);
3851 e68c5958 Gerd Hoffmann
    register_char_driver_qapi("pty", CHARDEV_BACKEND_KIND_PTY, NULL);
3852 d9ac374f Gerd Hoffmann
    register_char_driver_qapi("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
3853 548cbb36 Gerd Hoffmann
    register_char_driver_qapi("pipe", CHARDEV_BACKEND_KIND_PIPE,
3854 548cbb36 Gerd Hoffmann
                              qemu_chr_parse_pipe);
3855 d654f34e Anthony Liguori
}
3856 d654f34e Anthony Liguori
3857 d654f34e Anthony Liguori
type_init(register_types);