* [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts.
@ 2009-09-07 16:06 Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 01/23] QemuOpts: split option parser into two functions Gerd Hoffmann
` (22 more replies)
0 siblings, 23 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Hi,
This patch series switches the chardev initialization to QemuOpts,
brings a few improvements and paves the way for qdev-ifying devices
which need a chardev on the host side (i.e. serial ports + friends).
Changes:
* switch sockets to QemuOpts.
* switch chardevs to QemuOpts.
* new -chardev switch, create named and unconnected chardevs.
* lookup chardevs by name.
* IPv6 support for udp chardev.
* A few cleanups and fixes along the way.
Check the individual patches for all the details.
cheers,
Gerd
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 01/23] QemuOpts: split option parser into two functions.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 02/23] qemu-option.h include protectors Gerd Hoffmann
` (21 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
looking for id= and creating a new QemuOpts instance is splitted from
the actual option parser code now, so the parser can be called from
other contexts too.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-option.c | 46 +++++++++++++++++++++++++++++-----------------
qemu-option.h | 1 +
2 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index 61141e0..d37ffe9 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -709,23 +709,11 @@ int qemu_opts_print(QemuOpts *opts, void *dummy)
return 0;
}
-QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
+int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
{
- char option[128], value[128], *id = NULL;
- QemuOpts *opts;
+ char option[128], value[128];
const char *p,*pe,*pc;
- if (strncmp(params, "id=", 3) == 0) {
- get_opt_value(value, sizeof(value), params+3);
- id = qemu_strdup(value);
- } else if ((p = strstr(params, ",id=")) != NULL) {
- get_opt_value(value, sizeof(value), p+4);
- id = qemu_strdup(value);
- }
- opts = qemu_opts_create(list, id, 1);
- if (opts == NULL)
- return NULL;
-
p = params;
for(;;) {
pe = strchr(p, '=');
@@ -739,7 +727,7 @@ QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *fi
} else {
/* option without value, probably a flag */
p = get_opt_name(option, sizeof(option), p, ',');
- if (strncmp(p, "no", 2) == 0) {
+ if (strncmp(option, "no", 2) == 0) {
memmove(option, option+2, strlen(option+2)+1);
pstrcpy(value, sizeof(value), "off");
} else {
@@ -758,8 +746,7 @@ QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *fi
if (strcmp(option, "id") != 0) {
/* store and parse */
if (-1 == qemu_opt_set(opts, option, value)) {
- qemu_opts_del(opts);
- return NULL;
+ return -1;
}
}
if (*p != ',') {
@@ -767,6 +754,31 @@ QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *fi
}
p++;
}
+ return 0;
+}
+
+QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
+{
+ char value[128], *id = NULL;
+ const char *p;
+ QemuOpts *opts;
+
+ if (strncmp(params, "id=", 3) == 0) {
+ get_opt_value(value, sizeof(value), params+3);
+ id = qemu_strdup(value);
+ } else if ((p = strstr(params, ",id=")) != NULL) {
+ get_opt_value(value, sizeof(value), p+4);
+ id = qemu_strdup(value);
+ }
+ opts = qemu_opts_create(list, id, 1);
+ if (opts == NULL)
+ return NULL;
+
+ if (qemu_opts_do_parse(opts, params, firstname) != 0) {
+ qemu_opts_del(opts);
+ return NULL;
+ }
+
return opts;
}
diff --git a/qemu-option.h b/qemu-option.h
index 56c7eac..9e52625 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -114,6 +114,7 @@ int qemu_opts_set(QemuOptsList *list, const char *id,
const char *name, const char *value);
const char *qemu_opts_id(QemuOpts *opts);
void qemu_opts_del(QemuOpts *opts);
+int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname);
typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 02/23] qemu-option.h include protectors
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 01/23] QemuOpts: split option parser into two functions Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 03/23] switch chardev to QemuOpts: infrastructure, null device Gerd Hoffmann
` (20 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
qemu-option.h has no protection against including it twice.
This patch adds the usual "#ifndef header" bits.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-config.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/qemu-config.h b/qemu-config.h
index 08629de..e49d715 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -1,4 +1,9 @@
+#ifndef QEMU_CONFIG_H
+#define QEMU_CONFIG_H
+
extern QemuOptsList qemu_drive_opts;
extern QemuOptsList qemu_device_opts;
int qemu_set_option(const char *str);
+
+#endif /* QEMU_CONFIG_H */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 03/23] switch chardev to QemuOpts: infrastructure, null device
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 01/23] QemuOpts: split option parser into two functions Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 02/23] qemu-option.h include protectors Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:52 ` Blue Swirl
2009-09-07 16:06 ` [Qemu-devel] [PATCH 04/23] convert file+pipe chardevs to QemuOpts Gerd Hoffmann
` (19 subsequent siblings)
22 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
start switching chardevs to QemuOpts. This patch adds the
infrastructure and converts the null device.
The patch brings two new functions:
qemu_chr_open_opts()
same as qemu_chr_open(), but uses QemuOpts instead of a
option char string.
qemu_chr_parse_compat()
accepts a traditional chardev option string, returns the
corresponding QemuOpts instance, to handle backward
compatibility.
The patch also adds a new -chardev switch which can be used to create
named+unconnected chardevs, like this:
-chardev null,id=test
This uses the new qemu_chr_open_opts. Thus with this patch alone only
the null device works. The other devices will follow ...
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++---
qemu-char.h | 4 +++
qemu-config.c | 9 +++++++
qemu-config.h | 1 +
qemu-options.hx | 2 +
vl.c | 10 +++++++
6 files changed, 93 insertions(+), 4 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index c25ed1c..97877ce 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -214,7 +214,7 @@ static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
return len;
}
-static CharDriverState *qemu_chr_open_null(void)
+static CharDriverState *qemu_chr_open_null(QemuOpts *opts)
{
CharDriverState *chr;
@@ -2216,10 +2216,76 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
return NULL;
}
+static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
+{
+ QemuOpts *opts;
+
+ opts = qemu_opts_create(&qemu_chardev_opts, label, 1);
+ if (NULL == opts)
+ return NULL;
+
+ if (strcmp(filename, "null") == 0) {
+ qemu_opt_set(opts, "backend", "null");
+ return opts;
+ }
+
+ qemu_opts_del(opts);
+ return NULL;
+}
+
+static struct {
+ const char *name;
+ CharDriverState *(*open)(QemuOpts *opts);
+} backend_table[] = {
+ { .name = "null", .open = qemu_chr_open_null },
+};
+
+CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
+ void (*init)(struct CharDriverState *s))
+{
+ CharDriverState *chr;
+ int i;
+
+ if (qemu_opts_id(opts) == NULL) {
+ fprintf(stderr, "chardev: no id specified\n");
+ return NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(backend_table); i++) {
+ if (strcmp(backend_table[i].name, qemu_opt_get(opts, "backend")) == 0)
+ break;
+ }
+ if (i == ARRAY_SIZE(backend_table)) {
+ fprintf(stderr, "chardev: backend \"%s\" not found\n",
+ qemu_opt_get(opts, "backend"));
+ return NULL;
+ }
+
+ chr = backend_table[i].open(opts);
+ if (!chr) {
+ fprintf(stderr, "chardev: opening backend \"%s\" failed\n",
+ qemu_opt_get(opts, "backend"));
+ return NULL;
+ }
+
+ if (!chr->filename)
+ chr->filename = qemu_strdup(qemu_opt_get(opts, "backend"));
+ chr->init = init;
+ chr->label = qemu_strdup(qemu_opts_id(opts));
+ TAILQ_INSERT_TAIL(&chardevs, chr, next);
+ return chr;
+}
+
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
{
const char *p;
CharDriverState *chr;
+ QemuOpts *opts;
+
+ opts = qemu_chr_parse_compat(label, filename);
+ if (opts) {
+ return qemu_chr_open_opts(opts, init);
+ }
if (!strcmp(filename, "vc")) {
chr = text_console_init(NULL);
@@ -2227,9 +2293,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
if (strstart(filename, "vc:", &p)) {
chr = text_console_init(p);
} else
- if (!strcmp(filename, "null")) {
- chr = qemu_chr_open_null();
- } else
if (strstart(filename, "tcp:", &p)) {
chr = qemu_chr_open_tcp(p, 0, 0);
} else
diff --git a/qemu-char.h b/qemu-char.h
index df620bc..9bff0c7 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -3,6 +3,8 @@
#include "qemu-common.h"
#include "sys-queue.h"
+#include "qemu-option.h"
+#include "qemu-config.h"
/* character device */
@@ -68,6 +70,8 @@ struct CharDriverState {
TAILQ_ENTRY(CharDriverState) next;
};
+CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
+ void (*init)(struct CharDriverState *s));
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
void qemu_chr_close(CharDriverState *chr);
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
diff --git a/qemu-config.c b/qemu-config.c
index 4808db0..b156c24 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -75,6 +75,14 @@ QemuOptsList qemu_drive_opts = {
},
};
+QemuOptsList qemu_chardev_opts = {
+ .name = "chardev",
+ .head = TAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
+ .desc = {
+ { /* end if list */ }
+ },
+};
+
QemuOptsList qemu_device_opts = {
.name = "device",
.head = TAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
@@ -90,6 +98,7 @@ QemuOptsList qemu_device_opts = {
static QemuOptsList *lists[] = {
&qemu_drive_opts,
+ &qemu_chardev_opts,
&qemu_device_opts,
NULL,
};
diff --git a/qemu-config.h b/qemu-config.h
index e49d715..13b0f19 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -2,6 +2,7 @@
#define QEMU_CONFIG_H
extern QemuOptsList qemu_drive_opts;
+extern QemuOptsList qemu_chardev_opts;
extern QemuOptsList qemu_device_opts;
int qemu_set_option(const char *str);
diff --git a/qemu-options.hx b/qemu-options.hx
index ce38a3b..d3aa55b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1195,6 +1195,8 @@ STEXI
@table @option
ETEXI
+DEF("chardev", HAS_ARG, QEMU_OPTION_chardev, \
+ "-chardev spec create unconnected chardev\n")
DEF("serial", HAS_ARG, QEMU_OPTION_serial, \
"-serial dev redirect the serial port to char device 'dev'\n")
STEXI
diff --git a/vl.c b/vl.c
index 098daaa..0ea2206 100644
--- a/vl.c
+++ b/vl.c
@@ -5369,6 +5369,16 @@ int main(int argc, char **argv, char **envp)
monitor_devices[monitor_device_index] = optarg;
monitor_device_index++;
break;
+ case QEMU_OPTION_chardev:
+ opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend");
+ if (!opts) {
+ fprintf(stderr, "parse error: %s\n", optarg);
+ exit(1);
+ }
+ if (NULL == qemu_chr_open_opts(opts, NULL)) {
+ exit(1);
+ }
+ break;
case QEMU_OPTION_serial:
if (serial_device_index >= MAX_SERIAL_PORTS) {
fprintf(stderr, "qemu: too many serial ports\n");
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 04/23] convert file+pipe chardevs to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (2 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 03/23] switch chardev to QemuOpts: infrastructure, null device Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 05/23] sockets: add unix_connect_opts Gerd Hoffmann
` (18 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
new cmd line syntax:
-chardev file,id=name,path=/path/to/file
-chardev pipe,id=name,path=/path/to/pipe
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 47 ++++++++++++++++++++++++++++++++---------------
qemu-config.c | 7 +++++++
2 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 97877ce..10f58ca 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -626,20 +626,27 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
return chr;
}
-static CharDriverState *qemu_chr_open_file_out(const char *file_out)
+static CharDriverState *qemu_chr_open_file_out(QemuOpts *opts)
{
int fd_out;
- TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
+ TFR(fd_out = open(qemu_opt_get(opts, "path"),
+ O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
if (fd_out < 0)
return NULL;
return qemu_chr_open_fd(-1, fd_out);
}
-static CharDriverState *qemu_chr_open_pipe(const char *filename)
+static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts)
{
int fd_in, fd_out;
char filename_in[256], filename_out[256];
+ const char *filename = qemu_opt_get(opts, "path");
+
+ if (filename == NULL) {
+ fprintf(stderr, "chardev: pipe: no filename given\n");
+ return NULL;
+ }
snprintf(filename_in, 256, "%s.in", filename);
snprintf(filename_out, 256, "%s.out", filename);
@@ -1658,8 +1665,9 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
}
-static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
+static CharDriverState *qemu_chr_open_win_pipe(QemuOpts *opts)
{
+ const char *filename = qemu_opt_get(opts, "path");
CharDriverState *chr;
WinCharState *s;
@@ -1697,8 +1705,9 @@ static CharDriverState *qemu_chr_open_win_con(const char *filename)
return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
}
-static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
+static CharDriverState *qemu_chr_open_win_file_out(QemuOpts *opts)
{
+ const char *file_out = qemu_opt_get(opts, "path");
HANDLE fd_out;
fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
@@ -2218,6 +2227,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
{
+ const char *p;
QemuOpts *opts;
opts = qemu_opts_create(&qemu_chardev_opts, label, 1);
@@ -2228,6 +2238,16 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
qemu_opt_set(opts, "backend", "null");
return opts;
}
+ if (strstart(filename, "file:", &p)) {
+ qemu_opt_set(opts, "backend", "file");
+ qemu_opt_set(opts, "path", p);
+ return opts;
+ }
+ if (strstart(filename, "pipe:", &p)) {
+ qemu_opt_set(opts, "backend", "pipe");
+ qemu_opt_set(opts, "path", p);
+ return opts;
+ }
qemu_opts_del(opts);
return NULL;
@@ -2238,6 +2258,13 @@ static struct {
CharDriverState *(*open)(QemuOpts *opts);
} backend_table[] = {
{ .name = "null", .open = qemu_chr_open_null },
+#ifdef _WIN32
+ { .name = "file", .open = qemu_chr_open_win_file_out },
+ { .name = "pipe", .open = qemu_chr_open_win_pipe },
+#else
+ { .name = "file", .open = qemu_chr_open_file_out },
+ { .name = "pipe", .open = qemu_chr_open_pipe },
+#endif
};
CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
@@ -2316,10 +2343,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
#ifndef _WIN32
if (strstart(filename, "unix:", &p)) {
chr = qemu_chr_open_tcp(p, 0, 1);
- } else if (strstart(filename, "file:", &p)) {
- chr = qemu_chr_open_file_out(p);
- } else if (strstart(filename, "pipe:", &p)) {
- chr = qemu_chr_open_pipe(p);
} else if (!strcmp(filename, "pty")) {
chr = qemu_chr_open_pty();
} else if (!strcmp(filename, "stdio")) {
@@ -2344,15 +2367,9 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
if (strstart(filename, "COM", NULL)) {
chr = qemu_chr_open_win(filename);
} else
- if (strstart(filename, "pipe:", &p)) {
- chr = qemu_chr_open_win_pipe(p);
- } else
if (strstart(filename, "con:", NULL)) {
chr = qemu_chr_open_win_con(filename);
} else
- if (strstart(filename, "file:", &p)) {
- chr = qemu_chr_open_win_file_out(p);
- } else
#endif
#ifdef CONFIG_BRLAPI
if (!strcmp(filename, "braille")) {
diff --git a/qemu-config.c b/qemu-config.c
index b156c24..49be6be 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -79,6 +79,13 @@ QemuOptsList qemu_chardev_opts = {
.name = "chardev",
.head = TAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
.desc = {
+ {
+ .name = "backend",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "path",
+ .type = QEMU_OPT_STRING,
+ },
{ /* end if list */ }
},
};
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 05/23] sockets: add unix_connect_opts
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (3 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 04/23] convert file+pipe chardevs to QemuOpts Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 06/23] sockets: add unix_listen_opts Gerd Hoffmann
` (17 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add unix_connect_opts(). Does the same as unix_connect(), but uses
QemuOpts. unix_connect() is a compatibility wrapper for
unix_connect_opts() now and should go away some day.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-sockets.c | 34 +++++++++++++++++++++++++++++++++-
qemu_socket.h | 3 +++
2 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/qemu-sockets.c b/qemu-sockets.c
index bd49d29..732d3e0 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -29,6 +29,19 @@
static int sockets_debug = 0;
static const int on=1, off=0;
+/* used temporarely until all users are converted to QemuOpts */
+QemuOptsList dummy_opts = {
+ .name = "dummy",
+ .head = TAILQ_HEAD_INITIALIZER(dummy_opts.head),
+ .desc = {
+ {
+ .name = "path",
+ .type = QEMU_OPT_STRING,
+ },
+ { /* end if list */ }
+ },
+};
+
static int inet_getport(struct addrinfo *e)
{
struct sockaddr_in *i4;
@@ -376,11 +389,17 @@ err:
return -1;
}
-int unix_connect(const char *path)
+int unix_connect_opts(QemuOpts *opts)
{
struct sockaddr_un un;
+ const char *path = qemu_opt_get(opts, "path");
int sock;
+ if (NULL == path) {
+ fprintf(stderr, "unix connect: no path specified\n");
+ return -1;
+ }
+
sock = socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket(unix)");
@@ -400,6 +419,19 @@ int unix_connect(const char *path)
return sock;
}
+/* compatibility wrapper */
+int unix_connect(const char *path)
+{
+ QemuOpts *opts;
+ int sock;
+
+ opts = qemu_opts_create(&dummy_opts, NULL, 0);
+ qemu_opt_set(opts, "path", path);
+ sock = unix_connect_opts(opts);
+ qemu_opts_del(opts);
+ return sock;
+}
+
#else
int unix_listen(const char *path, char *ostr, int olen)
diff --git a/qemu_socket.h b/qemu_socket.h
index fc5b588..7ca4af7 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -29,6 +29,8 @@ int inet_aton(const char *cp, struct in_addr *ia);
#endif /* !_WIN32 */
+#include "qemu-option.h"
+
/* misc helpers */
void socket_set_nonblock(int fd);
int send_all(int fd, const void *buf, int len1);
@@ -39,6 +41,7 @@ int inet_listen(const char *str, char *ostr, int olen,
int inet_connect(const char *str, int socktype);
int unix_listen(const char *path, char *ostr, int olen);
+int unix_connect_opts(QemuOpts *opts);
int unix_connect(const char *path);
/* Old, ipv4 only bits. Don't use for new code. */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 06/23] sockets: add unix_listen_opts
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (4 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 05/23] sockets: add unix_connect_opts Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 07/23] sockets: add unix_*_opts for windows Gerd Hoffmann
` (16 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add unix_listen_opts(). Does the same as unix_listen(), but uses
QemuOpts. unix_listen() is a compatibility wrapper for
unix_listen_opts() now and should go away some day.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-sockets.c | 47 +++++++++++++++++++++++++++++++++--------------
qemu_socket.h | 1 +
2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 732d3e0..6e212fe 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -329,11 +329,11 @@ int inet_connect(const char *str, int socktype)
#ifndef _WIN32
-int unix_listen(const char *str, char *ostr, int olen)
+int unix_listen_opts(QemuOpts *opts)
{
struct sockaddr_un un;
- char *path, *opts;
- int sock, fd, len;
+ const char *path = qemu_opt_get(opts, "path");
+ int sock, fd;
sock = socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
@@ -341,14 +341,6 @@ int unix_listen(const char *str, char *ostr, int olen)
return -1;
}
- opts = strchr(str, ',');
- if (opts) {
- len = opts - str;
- path = qemu_malloc(len+1);
- snprintf(path, len+1, "%.*s", len, str);
- } else
- path = qemu_strdup(str);
-
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
if (path && strlen(path)) {
@@ -365,8 +357,8 @@ int unix_listen(const char *str, char *ostr, int olen)
* worst case possible is bind() failing, i.e. a DoS attack.
*/
fd = mkstemp(un.sun_path); close(fd);
+ qemu_opt_set(opts, "path", un.sun_path);
}
- snprintf(ostr, olen, "%s%s", un.sun_path, opts ? opts : "");
unlink(un.sun_path);
if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
@@ -380,11 +372,9 @@ int unix_listen(const char *str, char *ostr, int olen)
if (sockets_debug)
fprintf(stderr, "bind(unix:%s): OK\n", un.sun_path);
- qemu_free(path);
return sock;
err:
- qemu_free(path);
closesocket(sock);
return -1;
}
@@ -420,6 +410,35 @@ int unix_connect_opts(QemuOpts *opts)
}
/* compatibility wrapper */
+int unix_listen(const char *str, char *ostr, int olen)
+{
+ QemuOpts *opts;
+ char *path, *optstr;
+ int sock, len;
+
+ opts = qemu_opts_create(&dummy_opts, NULL, 0);
+
+ optstr = strchr(str, ',');
+ if (optstr) {
+ len = optstr - str;
+ if (len) {
+ path = qemu_malloc(len+1);
+ snprintf(path, len+1, "%.*s", len, str);
+ qemu_opt_set(opts, "path", path);
+ qemu_free(path);
+ }
+ } else {
+ qemu_opt_set(opts, "path", str);
+ }
+
+ sock = unix_listen_opts(opts);
+
+ if (sock != -1 && ostr)
+ snprintf(ostr, olen, "%s%s", qemu_opt_get(opts, "path"), optstr ? optstr : "");
+ qemu_opts_del(opts);
+ return sock;
+}
+
int unix_connect(const char *path)
{
QemuOpts *opts;
diff --git a/qemu_socket.h b/qemu_socket.h
index 7ca4af7..354c114 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -40,6 +40,7 @@ int inet_listen(const char *str, char *ostr, int olen,
int socktype, int port_offset);
int inet_connect(const char *str, int socktype);
+int unix_listen_opts(QemuOpts *opts);
int unix_listen(const char *path, char *ostr, int olen);
int unix_connect_opts(QemuOpts *opts);
int unix_connect(const char *path);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 07/23] sockets: add unix_*_opts for windows.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (5 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 06/23] sockets: add unix_listen_opts Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 08/23] sockets: add inet_connect_opts Gerd Hoffmann
` (15 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add unix_*_opts function dummys for windows.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-sockets.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 6e212fe..0d0ce44 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -453,6 +453,18 @@ int unix_connect(const char *path)
#else
+int unix_listen_opts(QemuOpts *opts)
+{
+ fprintf(stderr, "unix sockets are not available on windows\n");
+ return -1;
+}
+
+int unix_connect_opts(QemuOpts *opts)
+{
+ fprintf(stderr, "unix sockets are not available on windows\n");
+ return -1;
+}
+
int unix_listen(const char *path, char *ostr, int olen)
{
fprintf(stderr, "unix sockets are not available on windows\n");
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 08/23] sockets: add inet_connect_opts
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (6 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 07/23] sockets: add unix_*_opts for windows Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 09/23] sockets: add inet_listen_opts Gerd Hoffmann
` (14 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add inet_connect_opts(). Does the same as inet_connect(), but uses
QemuOpts. inet_connect() is a compatibility wrapper for
inet_connect_opts() now and should go away some day.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-sockets.c | 129 +++++++++++++++++++++++++++++++++++++++++--------------
qemu_socket.h | 1 +
2 files changed, 97 insertions(+), 33 deletions(-)
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 0d0ce44..65db94e 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -37,6 +37,21 @@ QemuOptsList dummy_opts = {
{
.name = "path",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "host",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "port",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "to",
+ .type = QEMU_OPT_NUMBER,
+ },{
+ .name = "ipv4",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "ipv6",
+ .type = QEMU_OPT_BOOL,
},
{ /* end if list */ }
},
@@ -237,11 +252,11 @@ listen:
return slisten;
}
-int inet_connect(const char *str, int socktype)
+int inet_connect_opts(QemuOpts *opts)
{
struct addrinfo ai,*res,*e;
- char addr[64];
- char port[33];
+ const char *addr;
+ const char *port;
char uaddr[INET6_ADDRSTRLEN+1];
char uport[33];
int sock,rc;
@@ -249,44 +264,24 @@ int inet_connect(const char *str, int socktype)
memset(&ai,0, sizeof(ai));
ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
ai.ai_family = PF_UNSPEC;
- ai.ai_socktype = socktype;
+ ai.ai_socktype = SOCK_STREAM;
- /* parse address */
- if (str[0] == '[') {
- /* IPv6 addr */
- if (2 != sscanf(str,"[%64[^]]]:%32[^,]",addr,port)) {
- fprintf(stderr, "%s: ipv6 parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
- ai.ai_family = PF_INET6;
- } else if (qemu_isdigit(str[0])) {
- /* IPv4 addr */
- if (2 != sscanf(str,"%64[0-9.]:%32[^,]",addr,port)) {
- fprintf(stderr, "%s: ipv4 parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
- ai.ai_family = PF_INET;
- } else {
- /* hostname */
- if (2 != sscanf(str,"%64[^:]:%32[^,]",addr,port)) {
- fprintf(stderr, "%s: hostname parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
+ addr = qemu_opt_get(opts, "host");
+ port = qemu_opt_get(opts, "port");
+ if (addr == NULL || port == NULL) {
+ fprintf(stderr, "inet_connect: host and/or port not specified\n");
+ return -1;
}
- /* parse options */
- if (strstr(str, ",ipv4"))
+ if (qemu_opt_get_bool(opts, "ipv4", 0))
ai.ai_family = PF_INET;
- if (strstr(str, ",ipv6"))
+ if (qemu_opt_get_bool(opts, "ipv6", 0))
ai.ai_family = PF_INET6;
/* lookup */
if (0 != (rc = getaddrinfo(addr, port, &ai, &res))) {
- fprintf(stderr,"getaddrinfo(%s,%s): %s\n", gai_strerror(rc),
- addr, port);
+ fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
+ gai_strerror(rc));
return -1;
}
if (sockets_debug)
@@ -327,6 +322,74 @@ int inet_connect(const char *str, int socktype)
return -1;
}
+/* compatibility wrapper */
+static int inet_parse(QemuOpts *opts, const char *str)
+{
+ const char *optstr, *h;
+ char addr[64];
+ char port[33];
+ int pos;
+
+ /* parse address */
+ if (str[0] == ':') {
+ /* no host given */
+ addr[0] = '\0';
+ if (1 != sscanf(str,":%32[^,]%n",port,&pos)) {
+ fprintf(stderr, "%s: portonly parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ } else if (str[0] == '[') {
+ /* IPv6 addr */
+ if (2 != sscanf(str,"[%64[^]]]:%32[^,]%n",addr,port,&pos)) {
+ fprintf(stderr, "%s: ipv6 parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ qemu_opt_set(opts, "ipv6", "yes");
+ } else if (qemu_isdigit(str[0])) {
+ /* IPv4 addr */
+ if (2 != sscanf(str,"%64[0-9.]:%32[^,]%n",addr,port,&pos)) {
+ fprintf(stderr, "%s: ipv4 parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ qemu_opt_set(opts, "ipv4", "yes");
+ } else {
+ /* hostname */
+ if (2 != sscanf(str,"%64[^:]:%32[^,]%n",addr,port,&pos)) {
+ fprintf(stderr, "%s: hostname parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ }
+ qemu_opt_set(opts, "host", addr);
+ qemu_opt_set(opts, "port", port);
+
+ /* parse options */
+ optstr = str + pos;
+ h = strstr(optstr, ",to=");
+ if (h)
+ qemu_opt_set(opts, "to", h+4);
+ if (strstr(optstr, ",ipv4"))
+ qemu_opt_set(opts, "ipv4", "yes");
+ if (strstr(optstr, ",ipv6"))
+ qemu_opt_set(opts, "ipv6", "yes");
+ return 0;
+}
+
+int inet_connect(const char *str, int socktype)
+{
+ QemuOpts *opts;
+ int sock = -1;
+
+ opts = qemu_opts_create(&dummy_opts, NULL, 0);
+ if (inet_parse(opts, str) == 0)
+ sock = inet_connect_opts(opts);
+ qemu_opts_del(opts);
+ return sock;
+}
+
#ifndef _WIN32
int unix_listen_opts(QemuOpts *opts)
diff --git a/qemu_socket.h b/qemu_socket.h
index 354c114..662f427 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -38,6 +38,7 @@ int send_all(int fd, const void *buf, int len1);
/* New, ipv6-ready socket helper functions, see qemu-sockets.c */
int inet_listen(const char *str, char *ostr, int olen,
int socktype, int port_offset);
+int inet_connect_opts(QemuOpts *opts);
int inet_connect(const char *str, int socktype);
int unix_listen_opts(QemuOpts *opts);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 09/23] sockets: add inet_listen_opts
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (7 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 08/23] sockets: add inet_connect_opts Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 10/23] convert unix+tcp chardevs to QemuOpts Gerd Hoffmann
` (13 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add inet_listen_opts(). Does the same as inet_listen(), but uses
QemuOpts. inet_listen() is a compatibility wrapper for
inet_listen_opts() now and should go away some day.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-sockets.c | 103 ++++++++++++++++++++++++++------------------------------
qemu_socket.h | 1 +
2 files changed, 49 insertions(+), 55 deletions(-)
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 65db94e..ec9777f 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -116,63 +116,31 @@ static void inet_print_addrinfo(const char *tag, struct addrinfo *res)
}
}
-int inet_listen(const char *str, char *ostr, int olen,
- int socktype, int port_offset)
+int inet_listen_opts(QemuOpts *opts, int port_offset)
{
struct addrinfo ai,*res,*e;
- char addr[64];
+ const char *addr;
char port[33];
char uaddr[INET6_ADDRSTRLEN+1];
char uport[33];
- const char *opts, *h;
- int slisten,rc,pos,to,try_next;
+ int slisten,rc,to,try_next;
memset(&ai,0, sizeof(ai));
ai.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
ai.ai_family = PF_UNSPEC;
- ai.ai_socktype = socktype;
+ ai.ai_socktype = SOCK_STREAM;
- /* parse address */
- if (str[0] == ':') {
- /* no host given */
- addr[0] = '\0';
- if (1 != sscanf(str,":%32[^,]%n",port,&pos)) {
- fprintf(stderr, "%s: portonly parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
- } else if (str[0] == '[') {
- /* IPv6 addr */
- if (2 != sscanf(str,"[%64[^]]]:%32[^,]%n",addr,port,&pos)) {
- fprintf(stderr, "%s: ipv6 parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
- ai.ai_family = PF_INET6;
- } else if (qemu_isdigit(str[0])) {
- /* IPv4 addr */
- if (2 != sscanf(str,"%64[0-9.]:%32[^,]%n",addr,port,&pos)) {
- fprintf(stderr, "%s: ipv4 parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
- ai.ai_family = PF_INET;
- } else {
- /* hostname */
- if (2 != sscanf(str,"%64[^:]:%32[^,]%n",addr,port,&pos)) {
- fprintf(stderr, "%s: hostname parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
+ if (qemu_opt_get(opts, "port") == NULL) {
+ fprintf(stderr, "%s: host and/or port not specified\n", __FUNCTION__);
+ return -1;
}
+ pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
+ addr = qemu_opt_get(opts, "host");
- /* parse options */
- opts = str + pos;
- h = strstr(opts, ",to=");
- to = h ? atoi(h+4) : 0;
- if (strstr(opts, ",ipv4"))
+ to = qemu_opt_get_number(opts, "to", 0);
+ if (qemu_opt_get_bool(opts, "ipv4", 0))
ai.ai_family = PF_INET;
- if (strstr(opts, ",ipv6"))
+ if (qemu_opt_get_bool(opts, "ipv6", 0))
ai.ai_family = PF_INET6;
/* lookup */
@@ -180,8 +148,8 @@ int inet_listen(const char *str, char *ostr, int olen,
snprintf(port, sizeof(port), "%d", atoi(port) + port_offset);
rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res);
if (rc != 0) {
- fprintf(stderr,"%s: getaddrinfo(%s,%s): %s\n", __FUNCTION__,
- addr, port, gai_strerror(rc));
+ fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
+ gai_strerror(rc));
return -1;
}
if (sockets_debug)
@@ -239,15 +207,11 @@ listen:
freeaddrinfo(res);
return -1;
}
- if (ostr) {
- if (e->ai_family == PF_INET6) {
- snprintf(ostr, olen, "[%s]:%d%s", uaddr,
- inet_getport(e) - port_offset, opts);
- } else {
- snprintf(ostr, olen, "%s:%d%s", uaddr,
- inet_getport(e) - port_offset, opts);
- }
- }
+ snprintf(uport, sizeof(uport), "%d", inet_getport(e) - port_offset);
+ qemu_opt_set(opts, "host", uaddr);
+ qemu_opt_set(opts, "port", uport);
+ qemu_opt_set(opts, "ipv6", (e->ai_family == PF_INET6) ? "on" : "off");
+ qemu_opt_set(opts, "ipv4", (e->ai_family != PF_INET6) ? "on" : "off");
freeaddrinfo(res);
return slisten;
}
@@ -378,6 +342,35 @@ static int inet_parse(QemuOpts *opts, const char *str)
return 0;
}
+int inet_listen(const char *str, char *ostr, int olen,
+ int socktype, int port_offset)
+{
+ QemuOpts *opts;
+ char *optstr;
+ int sock = -1;
+
+ opts = qemu_opts_create(&dummy_opts, NULL, 0);
+ if (inet_parse(opts, str) == 0) {
+ sock = inet_listen_opts(opts, port_offset);
+ if (sock != -1 && ostr) {
+ optstr = strchr(str, ',');
+ if (qemu_opt_get_bool(opts, "ipv6", 0)) {
+ snprintf(ostr, olen, "[%s]:%s%s",
+ qemu_opt_get(opts, "host"),
+ qemu_opt_get(opts, "port"),
+ optstr ? optstr : "");
+ } else {
+ snprintf(ostr, olen, "%s:%s%s",
+ qemu_opt_get(opts, "host"),
+ qemu_opt_get(opts, "port"),
+ optstr ? optstr : "");
+ }
+ }
+ }
+ qemu_opts_del(opts);
+ return sock;
+}
+
int inet_connect(const char *str, int socktype)
{
QemuOpts *opts;
diff --git a/qemu_socket.h b/qemu_socket.h
index 662f427..6ee9510 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -36,6 +36,7 @@ void socket_set_nonblock(int fd);
int send_all(int fd, const void *buf, int len1);
/* New, ipv6-ready socket helper functions, see qemu-sockets.c */
+int inet_listen_opts(QemuOpts *opts, int port_offset);
int inet_listen(const char *str, char *ostr, int olen,
int socktype, int port_offset);
int inet_connect_opts(QemuOpts *opts);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 10/23] convert unix+tcp chardevs to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (8 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 09/23] sockets: add inet_listen_opts Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 11/23] convert pty chardev " Gerd Hoffmann
` (12 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
new cmd line syntax:
unix socket:
-chardev socket,id=name,path=/path/to/socket
tcp socket:
-chardev socket,id=name,host=hostaddr|ipaddr,port=portnr
server and nowait options work as usual. Alternatively you can use
server=[on|off] + wait=[on|off] syntax.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 122 +++++++++++++++++++++++++++++++--------------------------
qemu-config.c | 27 +++++++++++++
2 files changed, 93 insertions(+), 56 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 10f58ca..c5ea5be 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2116,67 +2116,39 @@ static void tcp_chr_close(CharDriverState *chr)
qemu_chr_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_tcp(const char *host_str,
- int is_telnet,
- int is_unix)
+static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
{
CharDriverState *chr = NULL;
TCPCharDriver *s = NULL;
- int fd = -1, offset = 0;
- int is_listen = 0;
- int is_waitconnect = 1;
- int do_nodelay = 0;
- const char *ptr;
-
- ptr = host_str;
- while((ptr = strchr(ptr,','))) {
- ptr++;
- if (!strncmp(ptr,"server",6)) {
- is_listen = 1;
- } else if (!strncmp(ptr,"nowait",6)) {
- is_waitconnect = 0;
- } else if (!strncmp(ptr,"nodelay",6)) {
- do_nodelay = 1;
- } else if (!strncmp(ptr,"to=",3)) {
- /* nothing, inet_listen() parses this one */;
- } else if (!strncmp(ptr,"ipv4",4)) {
- /* nothing, inet_connect() and inet_listen() parse this one */;
- } else if (!strncmp(ptr,"ipv6",4)) {
- /* nothing, inet_connect() and inet_listen() parse this one */;
- } else {
- printf("Unknown option: %s\n", ptr);
- goto fail;
- }
- }
+ int fd = -1;
+ int is_listen;
+ int is_waitconnect;
+ int do_nodelay;
+ int is_unix;
+ int is_telnet;
+
+ is_listen = qemu_opt_get_bool(opts, "server", 0);
+ is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);
+ is_telnet = qemu_opt_get_bool(opts, "telnet", 0);
+ do_nodelay = !qemu_opt_get_bool(opts, "delay", 1);
+ is_unix = qemu_opt_get(opts, "path") != NULL;
if (!is_listen)
is_waitconnect = 0;
chr = qemu_mallocz(sizeof(CharDriverState));
s = qemu_mallocz(sizeof(TCPCharDriver));
- if (is_listen) {
- chr->filename = qemu_malloc(256);
- if (is_unix) {
- pstrcpy(chr->filename, 256, "unix:");
- } else if (is_telnet) {
- pstrcpy(chr->filename, 256, "telnet:");
- } else {
- pstrcpy(chr->filename, 256, "tcp:");
- }
- offset = strlen(chr->filename);
- }
if (is_unix) {
if (is_listen) {
- fd = unix_listen(host_str, chr->filename + offset, 256 - offset);
+ fd = unix_listen_opts(opts);
} else {
- fd = unix_connect(host_str);
+ fd = unix_connect_opts(opts);
}
} else {
if (is_listen) {
- fd = inet_listen(host_str, chr->filename + offset, 256 - offset,
- SOCK_STREAM, 0);
+ fd = inet_listen_opts(opts, 0);
} else {
- fd = inet_connect(host_str, SOCK_STREAM);
+ fd = inet_connect_opts(opts);
}
}
if (fd < 0)
@@ -2202,6 +2174,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
if (is_telnet)
s->do_telnetopt = 1;
+
} else {
s->connected = 1;
s->fd = fd;
@@ -2209,14 +2182,30 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
tcp_chr_connect(chr);
}
+ /* for "info chardev" monitor command */
+ chr->filename = qemu_malloc(256);
+ if (is_unix) {
+ snprintf(chr->filename, 256, "unix:%s%s",
+ qemu_opt_get(opts, "path"),
+ qemu_opt_get_bool(opts, "server", 0) ? ",server" : "");
+ } else if (is_telnet) {
+ snprintf(chr->filename, 256, "telnet:%s:%s%s",
+ qemu_opt_get(opts, "host"), qemu_opt_get(opts, "port"),
+ qemu_opt_get_bool(opts, "server", 0) ? ",server" : "");
+ } else {
+ snprintf(chr->filename, 256, "tcp:%s:%s%s",
+ qemu_opt_get(opts, "host"), qemu_opt_get(opts, "port"),
+ qemu_opt_get_bool(opts, "server", 0) ? ",server" : "");
+ }
+
if (is_listen && is_waitconnect) {
printf("QEMU waiting for connection on: %s\n",
- chr->filename ? chr->filename : host_str);
+ chr->filename);
tcp_chr_accept(chr);
socket_set_nonblock(s->listen_fd);
}
-
return chr;
+
fail:
if (fd >= 0)
closesocket(fd);
@@ -2227,6 +2216,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
{
+ char host[65], port[33];
+ int pos;
const char *p;
QemuOpts *opts;
@@ -2248,7 +2239,33 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
qemu_opt_set(opts, "path", p);
return opts;
}
+ if (strstart(filename, "tcp:", &p) ||
+ strstart(filename, "telnet:", &p)) {
+ if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
+ host[0] = 0;
+ if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
+ goto fail;
+ }
+ qemu_opt_set(opts, "backend", "socket");
+ qemu_opt_set(opts, "host", host);
+ qemu_opt_set(opts, "port", port);
+ if (p[pos] == ',') {
+ if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)
+ goto fail;
+ }
+ if (strstart(filename, "telnet:", &p))
+ qemu_opt_set(opts, "telnet", "on");
+ return opts;
+ }
+ if (strstart(filename, "unix:", &p)) {
+ qemu_opt_set(opts, "backend", "socket");
+ if (qemu_opts_do_parse(opts, p, "path") != 0)
+ goto fail;
+ return opts;
+ }
+fail:
+ fprintf(stderr, "%s: fail on \"%s\"\n", __FUNCTION__, filename);
qemu_opts_del(opts);
return NULL;
}
@@ -2258,6 +2275,7 @@ static struct {
CharDriverState *(*open)(QemuOpts *opts);
} backend_table[] = {
{ .name = "null", .open = qemu_chr_open_null },
+ { .name = "socket", .open = qemu_chr_open_socket },
#ifdef _WIN32
{ .name = "file", .open = qemu_chr_open_win_file_out },
{ .name = "pipe", .open = qemu_chr_open_win_pipe },
@@ -2320,12 +2338,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
if (strstart(filename, "vc:", &p)) {
chr = text_console_init(p);
} else
- if (strstart(filename, "tcp:", &p)) {
- chr = qemu_chr_open_tcp(p, 0, 0);
- } else
- if (strstart(filename, "telnet:", &p)) {
- chr = qemu_chr_open_tcp(p, 1, 0);
- } else
if (strstart(filename, "udp:", &p)) {
chr = qemu_chr_open_udp(p);
} else
@@ -2341,9 +2353,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
chr = qemu_chr_open_msmouse();
} else
#ifndef _WIN32
- if (strstart(filename, "unix:", &p)) {
- chr = qemu_chr_open_tcp(p, 0, 1);
- } else if (!strcmp(filename, "pty")) {
+ if (!strcmp(filename, "pty")) {
chr = qemu_chr_open_pty();
} else if (!strcmp(filename, "stdio")) {
chr = qemu_chr_open_stdio();
diff --git a/qemu-config.c b/qemu-config.c
index 49be6be..3b5083c 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -85,6 +85,33 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "path",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "host",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "port",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "to",
+ .type = QEMU_OPT_NUMBER,
+ },{
+ .name = "ipv4",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "ipv6",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "wait",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "server",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "delay",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "telnet",
+ .type = QEMU_OPT_BOOL,
},
{ /* end if list */ }
},
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 11/23] convert pty chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (9 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 10/23] convert unix+tcp chardevs to QemuOpts Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 12/23] convert stdio " Gerd Hoffmann
` (11 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index c5ea5be..ef6ab87 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -956,7 +956,7 @@ static void pty_chr_close(struct CharDriverState *chr)
qemu_chr_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_pty(void)
+static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)
{
CharDriverState *chr;
PtyCharDriver *s;
@@ -986,6 +986,7 @@ static CharDriverState *qemu_chr_open_pty(void)
len = strlen(q_ptsname(s->fd)) + 5;
chr->filename = qemu_malloc(len);
snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd));
+ qemu_opt_set(opts, "path", q_ptsname(s->fd));
fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
chr->opaque = s;
@@ -2225,8 +2226,9 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
if (NULL == opts)
return NULL;
- if (strcmp(filename, "null") == 0) {
- qemu_opt_set(opts, "backend", "null");
+ if (strcmp(filename, "null") == 0 ||
+ strcmp(filename, "pty") == 0) {
+ qemu_opt_set(opts, "backend", filename);
return opts;
}
if (strstart(filename, "file:", &p)) {
@@ -2282,6 +2284,7 @@ static struct {
#else
{ .name = "file", .open = qemu_chr_open_file_out },
{ .name = "pipe", .open = qemu_chr_open_pipe },
+ { .name = "pty", .open = qemu_chr_open_pty },
#endif
};
@@ -2353,9 +2356,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
chr = qemu_chr_open_msmouse();
} else
#ifndef _WIN32
- if (!strcmp(filename, "pty")) {
- chr = qemu_chr_open_pty();
- } else if (!strcmp(filename, "stdio")) {
+ if (!strcmp(filename, "stdio")) {
chr = qemu_chr_open_stdio();
} else
#if defined(__linux__)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 12/23] convert stdio chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (10 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 11/23] convert pty chardev " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 13/23] convert msmouse " Gerd Hoffmann
` (10 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index ef6ab87..f649280 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -758,7 +758,7 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr)
fd_chr_close(chr);
}
-static CharDriverState *qemu_chr_open_stdio(void)
+static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts)
{
CharDriverState *chr;
@@ -2227,7 +2227,8 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
return NULL;
if (strcmp(filename, "null") == 0 ||
- strcmp(filename, "pty") == 0) {
+ strcmp(filename, "pty") == 0 ||
+ strcmp(filename, "stdio") == 0) {
qemu_opt_set(opts, "backend", filename);
return opts;
}
@@ -2285,6 +2286,7 @@ static struct {
{ .name = "file", .open = qemu_chr_open_file_out },
{ .name = "pipe", .open = qemu_chr_open_pipe },
{ .name = "pty", .open = qemu_chr_open_pty },
+ { .name = "stdio", .open = qemu_chr_open_stdio },
#endif
};
@@ -2356,9 +2358,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
chr = qemu_chr_open_msmouse();
} else
#ifndef _WIN32
- if (!strcmp(filename, "stdio")) {
- chr = qemu_chr_open_stdio();
- } else
#if defined(__linux__)
if (strstart(filename, "/dev/parport", NULL)) {
chr = qemu_chr_open_pp(filename);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 13/23] convert msmouse chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (11 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 12/23] convert stdio " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 14/23] convert braille " Gerd Hoffmann
` (9 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/msmouse.c | 2 +-
hw/msmouse.h | 2 +-
qemu-char.c | 10 +++++-----
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/hw/msmouse.c b/hw/msmouse.c
index 69356a5..05f893c 100644
--- a/hw/msmouse.c
+++ b/hw/msmouse.c
@@ -64,7 +64,7 @@ static void msmouse_chr_close (struct CharDriverState *chr)
qemu_free (chr);
}
-CharDriverState *qemu_chr_open_msmouse(void)
+CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts)
{
CharDriverState *chr;
diff --git a/hw/msmouse.h b/hw/msmouse.h
index 947afd9..456cb21 100644
--- a/hw/msmouse.h
+++ b/hw/msmouse.h
@@ -1,2 +1,2 @@
/* msmouse.c */
-CharDriverState *qemu_chr_open_msmouse(void);
+CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts);
diff --git a/qemu-char.c b/qemu-char.c
index f649280..b8ed7be 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2226,9 +2226,10 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
if (NULL == opts)
return NULL;
- if (strcmp(filename, "null") == 0 ||
- strcmp(filename, "pty") == 0 ||
- strcmp(filename, "stdio") == 0) {
+ if (strcmp(filename, "null") == 0 ||
+ strcmp(filename, "pty") == 0 ||
+ strcmp(filename, "msmouse") == 0 ||
+ strcmp(filename, "stdio") == 0) {
qemu_opt_set(opts, "backend", filename);
return opts;
}
@@ -2279,6 +2280,7 @@ static struct {
} backend_table[] = {
{ .name = "null", .open = qemu_chr_open_null },
{ .name = "socket", .open = qemu_chr_open_socket },
+ { .name = "msmouse", .open = qemu_chr_open_msmouse },
#ifdef _WIN32
{ .name = "file", .open = qemu_chr_open_win_file_out },
{ .name = "pipe", .open = qemu_chr_open_win_pipe },
@@ -2354,8 +2356,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
} else {
printf("Unable to open driver: %s\n", p);
}
- } else if (!strcmp(filename, "msmouse")) {
- chr = qemu_chr_open_msmouse();
} else
#ifndef _WIN32
#if defined(__linux__)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 14/23] convert braille chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (12 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 13/23] convert msmouse " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 15/23] convert windows console " Gerd Hoffmann
` (8 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/baum.c | 2 +-
hw/baum.h | 2 +-
qemu-char.c | 9 ++++-----
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/hw/baum.c b/hw/baum.c
index b47ea34..a23e685 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -563,7 +563,7 @@ static void baum_chr_read(void *opaque)
}
}
-CharDriverState *chr_baum_init(void)
+CharDriverState *chr_baum_init(QemuOpts *opts)
{
BaumDriverState *baum;
CharDriverState *chr;
diff --git a/hw/baum.h b/hw/baum.h
index ac34b30..39ca4b1 100644
--- a/hw/baum.h
+++ b/hw/baum.h
@@ -26,4 +26,4 @@
USBDevice *usb_baum_init(void);
/* char device */
-CharDriverState *chr_baum_init(void);
+CharDriverState *chr_baum_init(QemuOpts *opts);
diff --git a/qemu-char.c b/qemu-char.c
index b8ed7be..125197f 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2229,6 +2229,7 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
if (strcmp(filename, "null") == 0 ||
strcmp(filename, "pty") == 0 ||
strcmp(filename, "msmouse") == 0 ||
+ strcmp(filename, "braille") == 0 ||
strcmp(filename, "stdio") == 0) {
qemu_opt_set(opts, "backend", filename);
return opts;
@@ -2290,6 +2291,9 @@ static struct {
{ .name = "pty", .open = qemu_chr_open_pty },
{ .name = "stdio", .open = qemu_chr_open_stdio },
#endif
+#ifdef CONFIG_BRLAPI
+ { .name = "braille", .open = chr_baum_init },
+#endif
};
CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
@@ -2381,11 +2385,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
chr = qemu_chr_open_win_con(filename);
} else
#endif
-#ifdef CONFIG_BRLAPI
- if (!strcmp(filename, "braille")) {
- chr = chr_baum_init();
- } else
-#endif
{
chr = NULL;
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 15/23] convert windows console chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (13 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 14/23] convert braille " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 16/23] convert tty + parport chardevs " Gerd Hoffmann
` (7 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 125197f..5ec864e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1701,7 +1701,7 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
return chr;
}
-static CharDriverState *qemu_chr_open_win_con(const char *filename)
+static CharDriverState *qemu_chr_open_win_con(QemuOpts *opts)
{
return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
}
@@ -2234,6 +2234,10 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
qemu_opt_set(opts, "backend", filename);
return opts;
}
+ if (strcmp(filename, "con:") == 0) {
+ qemu_opt_set(opts, "backend", "console");
+ return opts;
+ }
if (strstart(filename, "file:", &p)) {
qemu_opt_set(opts, "backend", "file");
qemu_opt_set(opts, "path", p);
@@ -2285,6 +2289,7 @@ static struct {
#ifdef _WIN32
{ .name = "file", .open = qemu_chr_open_win_file_out },
{ .name = "pipe", .open = qemu_chr_open_win_pipe },
+ { .name = "console", .open = qemu_chr_open_win_con },
#else
{ .name = "file", .open = qemu_chr_open_file_out },
{ .name = "pipe", .open = qemu_chr_open_pipe },
@@ -2381,9 +2386,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
if (strstart(filename, "COM", NULL)) {
chr = qemu_chr_open_win(filename);
} else
- if (strstart(filename, "con:", NULL)) {
- chr = qemu_chr_open_win_con(filename);
- } else
#endif
{
chr = NULL;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 16/23] convert tty + parport chardevs to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (14 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 15/23] convert windows console " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 17/23] convert vc chardev " Gerd Hoffmann
` (6 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
new cmd line syntax:
-chardev tty,id=name,path=/dev/tty*
-chardev parport,id=name,path=/dev/parport*
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 57 ++++++++++++++++++++++++++++++++-------------------------
1 files changed, 32 insertions(+), 25 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 5ec864e..6066c08 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1146,8 +1146,9 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
return 0;
}
-static CharDriverState *qemu_chr_open_tty(const char *filename)
+static CharDriverState *qemu_chr_open_tty(QemuOpts *opts)
{
+ const char *filename = qemu_opt_get(opts, "path");
CharDriverState *chr;
int fd;
@@ -1279,8 +1280,9 @@ static void pp_close(CharDriverState *chr)
qemu_chr_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_pp(const char *filename)
+static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
{
+ const char *filename = qemu_opt_get(opts, "path");
CharDriverState *chr;
ParallelCharDriver *drv;
int fd;
@@ -1348,8 +1350,9 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
return 0;
}
-static CharDriverState *qemu_chr_open_pp(const char *filename)
+static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
{
+ const char *filename = qemu_opt_get(opts, "path");
CharDriverState *chr;
int fd;
@@ -1567,8 +1570,9 @@ static int win_chr_poll(void *opaque)
return 0;
}
-static CharDriverState *qemu_chr_open_win(const char *filename)
+static CharDriverState *qemu_chr_open_win(QemuOpts *opts)
{
+ const char *filename = qemu_opt_get(opts, "path");
CharDriverState *chr;
WinCharState *s;
@@ -2238,6 +2242,11 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
qemu_opt_set(opts, "backend", "console");
return opts;
}
+ if (strstart(filename, "COM", NULL)) {
+ qemu_opt_set(opts, "backend", "serial");
+ qemu_opt_set(opts, "path", filename);
+ return opts;
+ }
if (strstart(filename, "file:", &p)) {
qemu_opt_set(opts, "backend", "file");
qemu_opt_set(opts, "path", p);
@@ -2272,6 +2281,17 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
goto fail;
return opts;
}
+ if (strstart(filename, "/dev/parport", NULL) ||
+ strstart(filename, "/dev/ppi", NULL)) {
+ qemu_opt_set(opts, "backend", "parport");
+ qemu_opt_set(opts, "path", filename);
+ return opts;
+ }
+ if (strstart(filename, "/dev/", NULL)) {
+ qemu_opt_set(opts, "backend", "tty");
+ qemu_opt_set(opts, "path", filename);
+ return opts;
+ }
fail:
fprintf(stderr, "%s: fail on \"%s\"\n", __FUNCTION__, filename);
@@ -2290,6 +2310,7 @@ static struct {
{ .name = "file", .open = qemu_chr_open_win_file_out },
{ .name = "pipe", .open = qemu_chr_open_win_pipe },
{ .name = "console", .open = qemu_chr_open_win_con },
+ { .name = "serial", .open = qemu_chr_open_win },
#else
{ .name = "file", .open = qemu_chr_open_file_out },
{ .name = "pipe", .open = qemu_chr_open_pipe },
@@ -2299,6 +2320,13 @@ static struct {
#ifdef CONFIG_BRLAPI
{ .name = "braille", .open = chr_baum_init },
#endif
+#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
+ || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+ { .name = "tty", .open = qemu_chr_open_tty },
+#endif
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+ { .name = "parport", .open = qemu_chr_open_pp },
+#endif
};
CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
@@ -2366,27 +2394,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
printf("Unable to open driver: %s\n", p);
}
} else
-#ifndef _WIN32
-#if defined(__linux__)
- if (strstart(filename, "/dev/parport", NULL)) {
- chr = qemu_chr_open_pp(filename);
- } else
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
- if (strstart(filename, "/dev/ppi", NULL)) {
- chr = qemu_chr_open_pp(filename);
- } else
-#endif
-#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
- || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
- if (strstart(filename, "/dev/", NULL)) {
- chr = qemu_chr_open_tty(filename);
- } else
-#endif
-#else /* !_WIN32 */
- if (strstart(filename, "COM", NULL)) {
- chr = qemu_chr_open_win(filename);
- } else
-#endif
{
chr = NULL;
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 17/23] convert vc chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (15 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 16/23] convert tty + parport chardevs " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 18/23] convert mux " Gerd Hoffmann
` (5 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
new cmd line syntax:
-chardev vc,id=name
-chardev vc,id=name,width=pixels,height=pixels
-chardev vc,id=name,cols=chars,rows=chars
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
console.c | 47 +++++++++++++++++++++++------------------------
console.h | 2 +-
qemu-char.c | 26 +++++++++++++++++++-------
qemu-config.c | 12 ++++++++++++
4 files changed, 55 insertions(+), 32 deletions(-)
diff --git a/console.c b/console.c
index d55e0fd..9bbef59 100644
--- a/console.c
+++ b/console.c
@@ -1317,16 +1317,31 @@ void console_color_init(DisplayState *ds)
static int n_text_consoles;
static CharDriverState *text_consoles[128];
-static char *text_console_strs[128];
+static QemuOpts *text_console_opts[128];
-static void text_console_do_init(CharDriverState *chr, DisplayState *ds, const char *p)
+static void text_console_do_init(CharDriverState *chr, DisplayState *ds, QemuOpts *opts)
{
TextConsole *s;
unsigned width;
unsigned height;
static int color_inited;
- s = new_console(ds, (p == NULL) ? TEXT_CONSOLE : TEXT_CONSOLE_FIXED_SIZE);
+ width = qemu_opt_get_number(opts, "width", 0);
+ if (width == 0)
+ width = qemu_opt_get_number(opts, "cols", 0) * FONT_WIDTH;
+
+ height = qemu_opt_get_number(opts, "height", 0);
+ if (height == 0)
+ height = qemu_opt_get_number(opts, "rows", 0) * FONT_HEIGHT;
+
+ if (width == 0 || height == 0) {
+ s = new_console(ds, TEXT_CONSOLE);
+ width = ds_get_width(s->ds);
+ height = ds_get_height(s->ds);
+ } else {
+ s = new_console(ds, TEXT_CONSOLE_FIXED_SIZE);
+ }
+
if (!s) {
free(chr);
return;
@@ -1350,23 +1365,6 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds, const c
s->total_height = DEFAULT_BACKSCROLL;
s->x = 0;
s->y = 0;
- width = ds_get_width(s->ds);
- height = ds_get_height(s->ds);
- if (p != NULL) {
- width = strtoul(p, (char **)&p, 10);
- if (*p == 'C') {
- p++;
- width *= FONT_WIDTH;
- }
- if (*p == 'x') {
- p++;
- height = strtoul(p, (char **)&p, 10);
- if (*p == 'C') {
- p++;
- height *= FONT_HEIGHT;
- }
- }
- }
s->g_width = width;
s->g_height = height;
@@ -1391,7 +1389,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds, const c
chr->init(chr);
}
-CharDriverState *text_console_init(const char *p)
+CharDriverState *text_console_init(QemuOpts *opts)
{
CharDriverState *chr;
@@ -1402,7 +1400,7 @@ CharDriverState *text_console_init(const char *p)
exit(1);
}
text_consoles[n_text_consoles] = chr;
- text_console_strs[n_text_consoles] = p ? qemu_strdup(p) : NULL;
+ text_console_opts[n_text_consoles] = opts;
n_text_consoles++;
return chr;
@@ -1413,8 +1411,9 @@ void text_consoles_set_display(DisplayState *ds)
int i;
for (i = 0; i < n_text_consoles; i++) {
- text_console_do_init(text_consoles[i], ds, text_console_strs[i]);
- qemu_free(text_console_strs[i]);
+ text_console_do_init(text_consoles[i], ds, text_console_opts[i]);
+ qemu_opts_del(text_console_opts[i]);
+ text_console_opts[i] = NULL;
}
n_text_consoles = 0;
diff --git a/console.h b/console.h
index c8922e4..9615f56 100644
--- a/console.h
+++ b/console.h
@@ -303,7 +303,7 @@ void vga_hw_text_update(console_ch_t *chardata);
int is_graphic_console(void);
int is_fixedsize_console(void);
-CharDriverState *text_console_init(const char *p);
+CharDriverState *text_console_init(QemuOpts *opts);
void text_consoles_set_display(DisplayState *ds);
void console_select(unsigned int index);
void console_color_init(DisplayState *ds);
diff --git a/qemu-char.c b/qemu-char.c
index 6066c08..429ba2d 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2221,7 +2221,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
{
- char host[65], port[33];
+ char host[65], port[33], width[8], height[8];
int pos;
const char *p;
QemuOpts *opts;
@@ -2238,6 +2238,23 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
qemu_opt_set(opts, "backend", filename);
return opts;
}
+ if (strstart(filename, "vc", &p)) {
+ qemu_opt_set(opts, "backend", "vc");
+ if (*p == ':') {
+ if (sscanf(p+1, "%8[0-9]x%8[0-9]", width, height) == 2) {
+ /* pixels */
+ qemu_opt_set(opts, "width", width);
+ qemu_opt_set(opts, "height", height);
+ } else if (sscanf(p+1, "%8[0-9]Cx%8[0-9]C", width, height) == 2) {
+ /* chars */
+ qemu_opt_set(opts, "cols", width);
+ qemu_opt_set(opts, "rows", height);
+ } else {
+ goto fail;
+ }
+ }
+ return opts;
+ }
if (strcmp(filename, "con:") == 0) {
qemu_opt_set(opts, "backend", "console");
return opts;
@@ -2306,6 +2323,7 @@ static struct {
{ .name = "null", .open = qemu_chr_open_null },
{ .name = "socket", .open = qemu_chr_open_socket },
{ .name = "msmouse", .open = qemu_chr_open_msmouse },
+ { .name = "vc", .open = text_console_init },
#ifdef _WIN32
{ .name = "file", .open = qemu_chr_open_win_file_out },
{ .name = "pipe", .open = qemu_chr_open_win_pipe },
@@ -2376,12 +2394,6 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
return qemu_chr_open_opts(opts, init);
}
- if (!strcmp(filename, "vc")) {
- chr = text_console_init(NULL);
- } else
- if (strstart(filename, "vc:", &p)) {
- chr = text_console_init(p);
- } else
if (strstart(filename, "udp:", &p)) {
chr = qemu_chr_open_udp(p);
} else
diff --git a/qemu-config.c b/qemu-config.c
index 3b5083c..09ef481 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -112,6 +112,18 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "telnet",
.type = QEMU_OPT_BOOL,
+ },{
+ .name = "width",
+ .type = QEMU_OPT_NUMBER,
+ },{
+ .name = "height",
+ .type = QEMU_OPT_NUMBER,
+ },{
+ .name = "cols",
+ .type = QEMU_OPT_NUMBER,
+ },{
+ .name = "rows",
+ .type = QEMU_OPT_NUMBER,
},
{ /* end if list */ }
},
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 18/23] convert mux chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (16 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 17/23] convert vc chardev " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 19/23] convert udp " Gerd Hoffmann
` (4 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
new cmd line syntax: you can add mux=1 to any chardev to enable muxing,
then attach it multiple times, like this:
-chardev pty,name=mux,mux=on
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 32 +++++++++++++++++++++-----------
1 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 429ba2d..5442226 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2230,6 +2230,11 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
if (NULL == opts)
return NULL;
+ if (strstart(filename, "mon:", &p)) {
+ filename = p;
+ qemu_opt_set(opts, "mux", "on");
+ }
+
if (strcmp(filename, "null") == 0 ||
strcmp(filename, "pty") == 0 ||
strcmp(filename, "msmouse") == 0 ||
@@ -2378,8 +2383,18 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
if (!chr->filename)
chr->filename = qemu_strdup(qemu_opt_get(opts, "backend"));
chr->init = init;
- chr->label = qemu_strdup(qemu_opts_id(opts));
TAILQ_INSERT_TAIL(&chardevs, chr, next);
+
+ if (qemu_opt_get_bool(opts, "mux", 0)) {
+ CharDriverState *base = chr;
+ int len = strlen(qemu_opts_id(opts)) + 6;
+ base->label = qemu_malloc(len);
+ snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
+ chr = qemu_chr_open_mux(base);
+ chr->filename = base->filename;
+ TAILQ_INSERT_TAIL(&chardevs, chr, next);
+ }
+ chr->label = qemu_strdup(qemu_opts_id(opts));
return chr;
}
@@ -2391,21 +2406,16 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
opts = qemu_chr_parse_compat(label, filename);
if (opts) {
- return qemu_chr_open_opts(opts, init);
+ chr = qemu_chr_open_opts(opts, init);
+ if (qemu_opt_get_bool(opts, "mux", 0)) {
+ monitor_init(chr, MONITOR_USE_READLINE);
+ }
+ return chr;
}
if (strstart(filename, "udp:", &p)) {
chr = qemu_chr_open_udp(p);
} else
- if (strstart(filename, "mon:", &p)) {
- chr = qemu_chr_open(label, p, NULL);
- if (chr) {
- chr = qemu_chr_open_mux(chr);
- monitor_init(chr, MONITOR_USE_READLINE);
- } else {
- printf("Unable to open driver: %s\n", p);
- }
- } else
{
chr = NULL;
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 19/23] convert udp chardev to QemuOpts.
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (17 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 18/23] convert mux " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-09 20:27 ` [Qemu-devel] " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 20/23] Allow -serial chardev:<name> Gerd Hoffmann
` (3 subsequent siblings)
22 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
While being at it: create a new inet_dgram_opts() function for udp setup,
so udp can handle IPv6 now.
new cmd line syntax:
-chardev udp,id=name,host=remotehost,port=remoteport,\
localaddr=bindaddr,localport=bindport
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 73 +++++++++++++++++------------------
qemu-config.c | 6 +++
qemu-sockets.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
qemu_socket.h | 1 +
4 files changed, 157 insertions(+), 39 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 5442226..e31f97b 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1729,7 +1729,6 @@ static CharDriverState *qemu_chr_open_win_file_out(QemuOpts *opts)
typedef struct {
int fd;
- struct sockaddr_in daddr;
uint8_t buf[1024];
int bufcnt;
int bufptr;
@@ -1740,8 +1739,7 @@ static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
NetCharDriver *s = chr->opaque;
- return sendto(s->fd, (const void *)buf, len, 0,
- (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
+ return send(s->fd, (const void *)buf, len, 0);
}
static int udp_chr_read_poll(void *opaque)
@@ -1803,30 +1801,18 @@ static void udp_chr_close(CharDriverState *chr)
qemu_chr_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_udp(const char *def)
+static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
{
CharDriverState *chr = NULL;
NetCharDriver *s = NULL;
int fd = -1;
- struct sockaddr_in saddr;
chr = qemu_mallocz(sizeof(CharDriverState));
s = qemu_mallocz(sizeof(NetCharDriver));
- fd = socket(PF_INET, SOCK_DGRAM, 0);
+ fd = inet_dgram_opts(opts);
if (fd < 0) {
- perror("socket(PF_INET, SOCK_DGRAM)");
- goto return_err;
- }
-
- if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
- printf("Could not parse: %s\n", def);
- goto return_err;
- }
-
- if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
- {
- perror("bind");
+ fprintf(stderr, "inet_dgram_opts failed\n");
goto return_err;
}
@@ -2297,6 +2283,31 @@ static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
qemu_opt_set(opts, "telnet", "on");
return opts;
}
+ if (strstart(filename, "udp:", &p)) {
+ qemu_opt_set(opts, "backend", "udp");
+ if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
+ host[0] = 0;
+ if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
+ fprintf(stderr, "udp #1\n");
+ goto fail;
+ }
+ }
+ qemu_opt_set(opts, "host", host);
+ qemu_opt_set(opts, "port", port);
+ if (p[pos] == '@') {
+ p += pos + 1;
+ if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
+ host[0] = 0;
+ if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
+ fprintf(stderr, "udp #2\n");
+ goto fail;
+ }
+ }
+ qemu_opt_set(opts, "localaddr", host);
+ qemu_opt_set(opts, "localport", port);
+ }
+ return opts;
+ }
if (strstart(filename, "unix:", &p)) {
qemu_opt_set(opts, "backend", "socket");
if (qemu_opts_do_parse(opts, p, "path") != 0)
@@ -2327,6 +2338,7 @@ static struct {
} backend_table[] = {
{ .name = "null", .open = qemu_chr_open_null },
{ .name = "socket", .open = qemu_chr_open_socket },
+ { .name = "udp", .open = qemu_chr_open_udp },
{ .name = "msmouse", .open = qemu_chr_open_msmouse },
{ .name = "vc", .open = text_console_init },
#ifdef _WIN32
@@ -2405,27 +2417,12 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
QemuOpts *opts;
opts = qemu_chr_parse_compat(label, filename);
- if (opts) {
- chr = qemu_chr_open_opts(opts, init);
- if (qemu_opt_get_bool(opts, "mux", 0)) {
- monitor_init(chr, MONITOR_USE_READLINE);
- }
- return chr;
- }
-
- if (strstart(filename, "udp:", &p)) {
- chr = qemu_chr_open_udp(p);
- } else
- {
- chr = NULL;
- }
+ if (!opts)
+ return NULL;
- if (chr) {
- if (!chr->filename)
- chr->filename = qemu_strdup(filename);
- chr->init = init;
- chr->label = qemu_strdup(label);
- TAILQ_INSERT_TAIL(&chardevs, chr, next);
+ chr = qemu_chr_open_opts(opts, init);
+ if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
+ monitor_init(chr, MONITOR_USE_READLINE);
}
return chr;
}
diff --git a/qemu-config.c b/qemu-config.c
index 09ef481..8404f1b 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -92,6 +92,12 @@ QemuOptsList qemu_chardev_opts = {
.name = "port",
.type = QEMU_OPT_STRING,
},{
+ .name = "localaddr",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "localport",
+ .type = QEMU_OPT_STRING,
+ },{
.name = "to",
.type = QEMU_OPT_NUMBER,
},{
diff --git a/qemu-sockets.c b/qemu-sockets.c
index ec9777f..6248b24 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -26,7 +26,7 @@
# define AI_ADDRCONFIG 0
#endif
-static int sockets_debug = 0;
+static int sockets_debug = 1;
static const int on=1, off=0;
/* used temporarely until all users are converted to QemuOpts */
@@ -286,6 +286,120 @@ int inet_connect_opts(QemuOpts *opts)
return -1;
}
+int inet_dgram_opts(QemuOpts *opts)
+{
+ struct addrinfo ai, *peer = NULL, *local = NULL;
+ const char *addr;
+ const char *port;
+ char uaddr[INET6_ADDRSTRLEN+1];
+ char uport[33];
+ int sock = -1, rc;
+
+ /* lookup peer addr */
+ memset(&ai,0, sizeof(ai));
+ ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
+ ai.ai_family = PF_UNSPEC;
+ ai.ai_socktype = SOCK_DGRAM;
+
+ addr = qemu_opt_get(opts, "host");
+ port = qemu_opt_get(opts, "port");
+ if (addr == NULL || strlen(addr) == 0) {
+ addr = "localhost";
+ }
+ if (port == NULL || strlen(port) == 0) {
+ fprintf(stderr, "inet_dgram: port not specified\n");
+ return -1;
+ }
+
+ if (qemu_opt_get_bool(opts, "ipv4", 0))
+ ai.ai_family = PF_INET;
+ if (qemu_opt_get_bool(opts, "ipv6", 0))
+ ai.ai_family = PF_INET6;
+
+ if (0 != (rc = getaddrinfo(addr, port, &ai, &peer))) {
+ fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
+ gai_strerror(rc));
+ return -1;
+ }
+ if (sockets_debug) {
+ fprintf(stderr, "%s: peer (%s:%s)\n", __FUNCTION__, addr, port);
+ inet_print_addrinfo(__FUNCTION__, peer);
+ }
+
+ /* lookup local addr */
+ memset(&ai,0, sizeof(ai));
+ ai.ai_flags = AI_PASSIVE;
+ ai.ai_family = peer->ai_family;
+ ai.ai_socktype = SOCK_DGRAM;
+
+ addr = qemu_opt_get(opts, "localaddr");
+ port = qemu_opt_get(opts, "localport");
+ if (addr == NULL || strlen(addr) == 0) {
+ addr = NULL;
+ }
+ if (!port || strlen(port) == 0)
+ port = "0";
+
+ if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) {
+ fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
+ gai_strerror(rc));
+ return -1;
+ }
+ if (sockets_debug) {
+ fprintf(stderr, "%s: local (%s:%s)\n", __FUNCTION__, addr, port);
+ inet_print_addrinfo(__FUNCTION__, local);
+ }
+
+ /* create socket */
+ sock = socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
+ if (sock < 0) {
+ fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
+ inet_strfamily(peer->ai_family), strerror(errno));
+ goto err;
+ }
+ setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
+
+ /* bind socket */
+ if (getnameinfo((struct sockaddr*)local->ai_addr,local->ai_addrlen,
+ uaddr,INET6_ADDRSTRLEN,uport,32,
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
+ fprintf(stderr, "%s: getnameinfo: oops\n", __FUNCTION__);
+ goto err;
+ }
+ if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
+ fprintf(stderr,"%s: bind(%s,%s,%d): OK\n", __FUNCTION__,
+ inet_strfamily(local->ai_family), uaddr, inet_getport(local));
+ goto err;
+ }
+
+ /* connect to peer */
+ if (getnameinfo((struct sockaddr*)peer->ai_addr, peer->ai_addrlen,
+ uaddr, INET6_ADDRSTRLEN, uport, 32,
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
+ fprintf(stderr, "%s: getnameinfo: oops\n", __FUNCTION__);
+ goto err;
+ }
+ if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
+ fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__,
+ inet_strfamily(peer->ai_family),
+ peer->ai_canonname, uaddr, uport, strerror(errno));
+ goto err;
+ }
+
+ freeaddrinfo(local);
+ freeaddrinfo(peer);
+ return sock;
+
+err:
+ if (-1 != sock)
+ closesocket(sock);
+ if (local)
+ freeaddrinfo(local);
+ if (peer)
+ freeaddrinfo(peer);
+ return -1;
+}
+
/* compatibility wrapper */
static int inet_parse(QemuOpts *opts, const char *str)
{
diff --git a/qemu_socket.h b/qemu_socket.h
index 6ee9510..c253b32 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -41,6 +41,7 @@ int inet_listen(const char *str, char *ostr, int olen,
int socktype, int port_offset);
int inet_connect_opts(QemuOpts *opts);
int inet_connect(const char *str, int socktype);
+int inet_dgram_opts(QemuOpts *opts);
int unix_listen_opts(QemuOpts *opts);
int unix_listen(const char *path, char *ostr, int olen);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 20/23] Allow -serial chardev:<name>
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (18 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 19/23] convert udp " Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 21/23] qdev: add parser for chardev properties Gerd Hoffmann
` (2 subsequent siblings)
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Lets put -chardev into use now. With this patch applied chardev:name is
accepted as chardev specification everywhere, i.e. now you can:
-chardev stdio,id=ttyS0
-serial chardev:ttyS0
which does the same as '-serial stdio".
Muxing can be done this way:
-chardev stdio,id=mux,mux=on
-serial chardev:mux
-monitor chardev:mux
You can mux more than two streams.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 16 ++++++++++++++++
qemu-char.h | 1 +
qemu-config.c | 3 +++
3 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index e31f97b..2e71038 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2416,6 +2416,10 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
CharDriverState *chr;
QemuOpts *opts;
+ if (strstart(filename, "chardev:", &p)) {
+ return qemu_chr_find(p);
+ }
+
opts = qemu_chr_parse_compat(label, filename);
if (!opts)
return NULL;
@@ -2445,3 +2449,15 @@ void qemu_chr_info(Monitor *mon)
monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename);
}
}
+
+CharDriverState *qemu_chr_find(const char *name)
+{
+ CharDriverState *chr;
+
+ TAILQ_FOREACH(chr, &chardevs, next) {
+ if (strcmp(chr->label, name) != 0)
+ continue;
+ return chr;
+ }
+ return NULL;
+}
diff --git a/qemu-char.h b/qemu-char.h
index 9bff0c7..0bf8944 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -90,6 +90,7 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
int qemu_chr_get_msgfd(CharDriverState *s);
void qemu_chr_accept_input(CharDriverState *s);
void qemu_chr_info(Monitor *mon);
+CharDriverState *qemu_chr_find(const char *name);
extern int term_escape_char;
diff --git a/qemu-config.c b/qemu-config.c
index 8404f1b..f6f4cb4 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -130,6 +130,9 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "rows",
.type = QEMU_OPT_NUMBER,
+ },{
+ .name = "mux",
+ .type = QEMU_OPT_BOOL,
},
{ /* end if list */ }
},
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 21/23] qdev: add parser for chardev properties
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (19 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 20/23] Allow -serial chardev:<name> Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 22/23] monitor: fix muxing Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 23/23] move mux focus field from CharDriverState to MuxDriver Gerd Hoffmann
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qdev-properties.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 12ff46b..0e5e5b5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -170,6 +170,16 @@ PropertyInfo qdev_prop_drive = {
/* --- character device --- */
+static int parse_chr(DeviceState *dev, Property *prop, const char *str)
+{
+ CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+
+ *ptr = qemu_chr_find(str);
+ if (*ptr == NULL)
+ return -1;
+ return 0;
+}
+
static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
{
CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
@@ -185,6 +195,7 @@ PropertyInfo qdev_prop_chr = {
.name = "chr",
.type = PROP_TYPE_CHR,
.size = sizeof(CharDriverState*),
+ .parse = parse_chr,
.print = print_chr,
};
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 22/23] monitor: fix muxing
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (20 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 21/23] qdev: add parser for chardev properties Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
2009-09-09 19:51 ` [Qemu-devel] " Jan Kiszka
2009-09-07 16:06 ` [Qemu-devel] [PATCH 23/23] move mux focus field from CharDriverState to MuxDriver Gerd Hoffmann
22 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
make the mux driver send mux_in and mux_out events when switching
focus while hooking up more handlers.
stop using CharDriverState->focus in monitor.c, track state using
the mux events instead. This also removes the implicit assumtion
that a muxed monitor allways has mux channel 0.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
monitor.c | 33 ++++++++++++++++++++++-----------
qemu-char.c | 3 +++
2 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/monitor.c b/monitor.c
index f5f4d0e..edf48f3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -85,6 +85,8 @@ struct mon_fd_t {
struct Monitor {
CharDriverState *chr;
+ int mux_out;
+ int reset_seen;
int flags;
int suspend_cnt;
uint8_t outbuf[1024];
@@ -129,7 +131,7 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
void monitor_flush(Monitor *mon)
{
- if (mon && mon->outbuf_index != 0 && mon->chr->focus == 0) {
+ if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
mon->outbuf_index = 0;
}
@@ -3111,23 +3113,34 @@ static void monitor_event(void *opaque, int event)
switch (event) {
case CHR_EVENT_MUX_IN:
- readline_restart(mon->rs);
- monitor_resume(mon);
- monitor_flush(mon);
+ if (mon->reset_seen) {
+ readline_restart(mon->rs);
+ monitor_resume(mon);
+ monitor_flush(mon);
+ } else {
+ mon->suspend_cnt = 0;
+ }
+ mon->mux_out = 0;
break;
case CHR_EVENT_MUX_OUT:
- if (mon->suspend_cnt == 0)
- monitor_printf(mon, "\n");
- monitor_flush(mon);
- monitor_suspend(mon);
+ if (mon->reset_seen) {
+ if (mon->suspend_cnt == 0)
+ monitor_printf(mon, "\n");
+ monitor_flush(mon);
+ monitor_suspend(mon);
+ } else {
+ mon->suspend_cnt++;
+ }
+ mon->mux_out = 1;
break;
case CHR_EVENT_RESET:
monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
"information\n", QEMU_VERSION);
- if (mon->chr->focus == 0)
+ if (!mon->mux_out)
readline_show_prompt(mon->rs);
+ mon->reset_seen = 1;
break;
}
}
@@ -3155,8 +3168,6 @@ void monitor_init(CharDriverState *chr, int flags)
mon->chr = chr;
mon->flags = flags;
- if (mon->chr->focus != 0)
- mon->suspend_cnt = 1; /* mux'ed monitors start suspended */
if (flags & MONITOR_USE_READLINE) {
mon->rs = readline_init(mon, monitor_find_completion);
monitor_read_command(mon, 0);
diff --git a/qemu-char.c b/qemu-char.c
index 2e71038..daa8587 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -456,8 +456,11 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
mux_chr_event, chr);
}
+ if (-1 != chr->focus)
+ mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT);
chr->focus = d->mux_cnt;
d->mux_cnt++;
+ mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN);
}
static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 23/23] move mux focus field from CharDriverState to MuxDriver
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
` (21 preceding siblings ...)
2009-09-07 16:06 ` [Qemu-devel] [PATCH 22/23] monitor: fix muxing Gerd Hoffmann
@ 2009-09-07 16:06 ` Gerd Hoffmann
22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-07 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Now that monitor stopped using focus we can make it internal
to the mux driver.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qemu-char.c | 27 ++++++++++++++-------------
qemu-char.h | 1 -
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index daa8587..f46cef5 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -233,6 +233,7 @@ typedef struct {
IOEventHandler *chr_event[MAX_MUX];
void *ext_opaque[MAX_MUX];
CharDriverState *drv;
+ int focus;
int mux_cnt;
int term_got_escape;
int max_size;
@@ -361,11 +362,11 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
break;
case 'c':
/* Switch to the next registered device */
- mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT);
- chr->focus++;
- if (chr->focus >= d->mux_cnt)
- chr->focus = 0;
- mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN);
+ mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
+ d->focus++;
+ if (d->focus >= d->mux_cnt)
+ d->focus = 0;
+ mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
break;
case 't':
d->timestamps = !d->timestamps;
@@ -384,8 +385,8 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
static void mux_chr_accept_input(CharDriverState *chr)
{
- int m = chr->focus;
MuxDriver *d = chr->opaque;
+ int m = d->focus;
while (d->prod[m] != d->cons[m] &&
d->chr_can_read[m] &&
@@ -399,7 +400,7 @@ static int mux_chr_can_read(void *opaque)
{
CharDriverState *chr = opaque;
MuxDriver *d = chr->opaque;
- int m = chr->focus;
+ int m = d->focus;
if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
return 1;
@@ -412,7 +413,7 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
{
CharDriverState *chr = opaque;
MuxDriver *d = chr->opaque;
- int m = chr->focus;
+ int m = d->focus;
int i;
mux_chr_accept_input (opaque);
@@ -456,11 +457,11 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
mux_chr_event, chr);
}
- if (-1 != chr->focus)
- mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT);
- chr->focus = d->mux_cnt;
+ if (-1 != d->focus)
+ mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
+ d->focus = d->mux_cnt;
d->mux_cnt++;
- mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN);
+ mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
}
static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
@@ -473,7 +474,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
chr->opaque = d;
d->drv = drv;
- chr->focus = -1;
+ d->focus = -1;
chr->chr_write = mux_chr_write;
chr->chr_update_read_handler = mux_chr_update_read_handler;
chr->chr_accept_input = mux_chr_accept_input;
diff --git a/qemu-char.h b/qemu-char.h
index 0bf8944..d12ab11 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -63,7 +63,6 @@ struct CharDriverState {
void (*chr_close)(struct CharDriverState *chr);
void (*chr_accept_input)(struct CharDriverState *chr);
void *opaque;
- int focus;
QEMUBH *bh;
char *label;
char *filename;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 03/23] switch chardev to QemuOpts: infrastructure, null device
2009-09-07 16:06 ` [Qemu-devel] [PATCH 03/23] switch chardev to QemuOpts: infrastructure, null device Gerd Hoffmann
@ 2009-09-07 16:52 ` Blue Swirl
0 siblings, 0 replies; 29+ messages in thread
From: Blue Swirl @ 2009-09-07 16:52 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Mon, Sep 7, 2009 at 7:06 PM, Gerd Hoffmann<kraxel@redhat.com> wrote:
> start switching chardevs to QemuOpts. This patch adds the
> infrastructure and converts the null device.
> +static struct {
> + const char *name;
> + CharDriverState *(*open)(QemuOpts *opts);
> +} backend_table[] = {
> + { .name = "null", .open = qemu_chr_open_null },
> +};
'const'?
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 22/23] monitor: fix muxing
2009-09-07 16:06 ` [Qemu-devel] [PATCH 22/23] monitor: fix muxing Gerd Hoffmann
@ 2009-09-09 19:51 ` Jan Kiszka
2009-09-09 20:18 ` Gerd Hoffmann
0 siblings, 1 reply; 29+ messages in thread
From: Jan Kiszka @ 2009-09-09 19:51 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 3881 bytes --]
Gerd Hoffmann wrote:
> make the mux driver send mux_in and mux_out events when switching
> focus while hooking up more handlers.
>
> stop using CharDriverState->focus in monitor.c, track state using
> the mux events instead. This also removes the implicit assumtion
> that a muxed monitor allways has mux channel 0.
Nice patch in the right direction, but it comes with a regression: When
you enable the monitor on mux'ed stdio via CTRL-A C, you don't get a
prompt until pressing some key.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> monitor.c | 33 ++++++++++++++++++++++-----------
> qemu-char.c | 3 +++
> 2 files changed, 25 insertions(+), 11 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index f5f4d0e..edf48f3 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -85,6 +85,8 @@ struct mon_fd_t {
>
> struct Monitor {
> CharDriverState *chr;
> + int mux_out;
> + int reset_seen;
> int flags;
> int suspend_cnt;
> uint8_t outbuf[1024];
> @@ -129,7 +131,7 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
>
> void monitor_flush(Monitor *mon)
> {
> - if (mon && mon->outbuf_index != 0 && mon->chr->focus == 0) {
> + if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
> qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
> mon->outbuf_index = 0;
> }
> @@ -3111,23 +3113,34 @@ static void monitor_event(void *opaque, int event)
>
> switch (event) {
> case CHR_EVENT_MUX_IN:
> - readline_restart(mon->rs);
> - monitor_resume(mon);
> - monitor_flush(mon);
> + if (mon->reset_seen) {
> + readline_restart(mon->rs);
> + monitor_resume(mon);
> + monitor_flush(mon);
> + } else {
> + mon->suspend_cnt = 0;
> + }
> + mon->mux_out = 0;
> break;
>
> case CHR_EVENT_MUX_OUT:
> - if (mon->suspend_cnt == 0)
> - monitor_printf(mon, "\n");
> - monitor_flush(mon);
> - monitor_suspend(mon);
> + if (mon->reset_seen) {
> + if (mon->suspend_cnt == 0)
> + monitor_printf(mon, "\n");
> + monitor_flush(mon);
> + monitor_suspend(mon);
> + } else {
> + mon->suspend_cnt++;
> + }
> + mon->mux_out = 1;
> break;
>
> case CHR_EVENT_RESET:
> monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
> "information\n", QEMU_VERSION);
> - if (mon->chr->focus == 0)
> + if (!mon->mux_out)
> readline_show_prompt(mon->rs);
Please add braces at this chance.
> + mon->reset_seen = 1;
> break;
> }
> }
> @@ -3155,8 +3168,6 @@ void monitor_init(CharDriverState *chr, int flags)
>
> mon->chr = chr;
> mon->flags = flags;
> - if (mon->chr->focus != 0)
> - mon->suspend_cnt = 1; /* mux'ed monitors start suspended */
> if (flags & MONITOR_USE_READLINE) {
> mon->rs = readline_init(mon, monitor_find_completion);
> monitor_read_command(mon, 0);
> diff --git a/qemu-char.c b/qemu-char.c
> index 2e71038..daa8587 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -456,8 +456,11 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
> qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
> mux_chr_event, chr);
> }
> + if (-1 != chr->focus)
> + mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT);
{ }
> chr->focus = d->mux_cnt;
> d->mux_cnt++;
> + mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN);
> }
>
> static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 22/23] monitor: fix muxing
2009-09-09 19:51 ` [Qemu-devel] " Jan Kiszka
@ 2009-09-09 20:18 ` Gerd Hoffmann
2009-09-09 20:27 ` Jan Kiszka
0 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-09 20:18 UTC (permalink / raw)
To: Jan Kiszka; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 635 bytes --]
On 09/09/09 21:51, Jan Kiszka wrote:
> Gerd Hoffmann wrote:
>> make the mux driver send mux_in and mux_out events when switching
>> focus while hooking up more handlers.
>>
>> stop using CharDriverState->focus in monitor.c, track state using
>> the mux events instead. This also removes the implicit assumtion
>> that a muxed monitor allways has mux channel 0.
>
> Nice patch in the right direction, but it comes with a regression: When
> you enable the monitor on mux'ed stdio via CTRL-A C, you don't get a
> prompt until pressing some key.
Incremental fix attached.
> Please add braces at this chance.
Will do.
cheers,
Gerd
[-- Attachment #2: fix --]
[-- Type: text/plain, Size: 566 bytes --]
diff --git a/monitor.c b/monitor.c
index edf48f3..476eab5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3113,6 +3113,7 @@ static void monitor_event(void *opaque, int event)
switch (event) {
case CHR_EVENT_MUX_IN:
+ mon->mux_out = 0;
if (mon->reset_seen) {
readline_restart(mon->rs);
monitor_resume(mon);
@@ -3120,7 +3121,6 @@ static void monitor_event(void *opaque, int event)
} else {
mon->suspend_cnt = 0;
}
- mon->mux_out = 0;
break;
case CHR_EVENT_MUX_OUT:
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 22/23] monitor: fix muxing
2009-09-09 20:18 ` Gerd Hoffmann
@ 2009-09-09 20:27 ` Jan Kiszka
0 siblings, 0 replies; 29+ messages in thread
From: Jan Kiszka @ 2009-09-09 20:27 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 776 bytes --]
Gerd Hoffmann wrote:
> On 09/09/09 21:51, Jan Kiszka wrote:
>> Gerd Hoffmann wrote:
>>> make the mux driver send mux_in and mux_out events when switching
>>> focus while hooking up more handlers.
>>>
>>> stop using CharDriverState->focus in monitor.c, track state using
>>> the mux events instead. This also removes the implicit assumtion
>>> that a muxed monitor allways has mux channel 0.
>>
>> Nice patch in the right direction, but it comes with a regression: When
>> you enable the monitor on mux'ed stdio via CTRL-A C, you don't get a
>> prompt until pressing some key.
>
> Incremental fix attached.
Works, perfect.
>
>> Please add braces at this chance.
>
> Will do.
Fine. And please also reorder that "if (-1 != chr->focus)" :)
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 19/23] convert udp chardev to QemuOpts.
2009-09-07 16:06 ` [Qemu-devel] [PATCH 19/23] convert udp " Gerd Hoffmann
@ 2009-09-09 20:27 ` Gerd Hoffmann
0 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2009-09-09 20:27 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
> --- a/qemu-sockets.c
> +++ b/qemu-sockets.c
> @@ -26,7 +26,7 @@
> # define AI_ADDRCONFIG 0
> #endif
>
> -static int sockets_debug = 0;
> +static int sockets_debug = 1;
Oops. That debug leftover makes qemu a bit verbose ...
cheers,
Gerd
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2009-09-09 20:27 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-07 16:06 [Qemu-devel] [PATCH 00/23] switch sockets+chardev to QemuOpts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 01/23] QemuOpts: split option parser into two functions Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 02/23] qemu-option.h include protectors Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 03/23] switch chardev to QemuOpts: infrastructure, null device Gerd Hoffmann
2009-09-07 16:52 ` Blue Swirl
2009-09-07 16:06 ` [Qemu-devel] [PATCH 04/23] convert file+pipe chardevs to QemuOpts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 05/23] sockets: add unix_connect_opts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 06/23] sockets: add unix_listen_opts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 07/23] sockets: add unix_*_opts for windows Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 08/23] sockets: add inet_connect_opts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 09/23] sockets: add inet_listen_opts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 10/23] convert unix+tcp chardevs to QemuOpts Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 11/23] convert pty chardev " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 12/23] convert stdio " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 13/23] convert msmouse " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 14/23] convert braille " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 15/23] convert windows console " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 16/23] convert tty + parport chardevs " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 17/23] convert vc chardev " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 18/23] convert mux " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 19/23] convert udp " Gerd Hoffmann
2009-09-09 20:27 ` [Qemu-devel] " Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 20/23] Allow -serial chardev:<name> Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 21/23] qdev: add parser for chardev properties Gerd Hoffmann
2009-09-07 16:06 ` [Qemu-devel] [PATCH 22/23] monitor: fix muxing Gerd Hoffmann
2009-09-09 19:51 ` [Qemu-devel] " Jan Kiszka
2009-09-09 20:18 ` Gerd Hoffmann
2009-09-09 20:27 ` Jan Kiszka
2009-09-07 16:06 ` [Qemu-devel] [PATCH 23/23] move mux focus field from CharDriverState to MuxDriver Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).