qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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).