Patchwork multiboot: Support quotable commas in module list

login
register
mail settings
Submitter Adam Lackorzynski
Date April 15, 2011, 7:56 a.m.
Message ID <1302854186-6772-1-git-send-email-adam@os.inf.tu-dresden.de>
Download mbox | patch
Permalink /patch/91325/
State New
Headers show

Comments

Adam Lackorzynski - April 15, 2011, 7:56 a.m.
Support quoting of ',' (and '\') to allow commas in the parameter list of
modules.

Signed-off-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
---
 hw/multiboot.c |   33 +++++++++++++++++++++++++++++----
 1 files changed, 29 insertions(+), 4 deletions(-)
Stefan Hajnoczi - April 15, 2011, 9:09 a.m.
On Fri, Apr 15, 2011 at 8:56 AM, Adam Lackorzynski
<adam@os.inf.tu-dresden.de> wrote:
> Support quoting of ',' (and '\') to allow commas in the parameter list of
> modules.
>
> Signed-off-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
> ---
>  hw/multiboot.c |   33 +++++++++++++++++++++++++++++----
>  1 files changed, 29 insertions(+), 4 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Kevin Wolf - April 15, 2011, 1:17 p.m.
Am 15.04.2011 09:56, schrieb Adam Lackorzynski:
> Support quoting of ',' (and '\') to allow commas in the parameter list of
> modules.
> 
> Signed-off-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>

Other options in qemu use double commas for escaping. So maybe reusing
get_opt_value() would make things more consistent. It also has the
advantage that double commas don't need additional escape characters for
the shell.

On the other hand, using backslashes for escaping is probably more
familiar for most people, so I don't have a very strong opinion on it.

Kevin

Patch

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 394ed01..73f01aa 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -95,13 +95,26 @@  typedef struct {
     int mb_mods_count;
 } MultibootState;
 
+static int mb_is_cmdline_quote(const char *c)
+{
+    return c[0] == '\\' && (c[1] == '\\' || c[1] == ',');
+}
+
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
     int len = strlen(cmdline) + 1;
+    int ci, bi;
     target_phys_addr_t p = s->offset_cmdlines;
+    char *b = (char *)s->mb_buf + p;
 
-    pstrcpy((char *)s->mb_buf + p, len, cmdline);
-    s->offset_cmdlines += len;
+    for (ci = 0, bi = 0; ci < len - 1; ci++, bi++) {
+        if (mb_is_cmdline_quote(&cmdline[ci])) {
+            ci++;
+        }
+        b[bi] = cmdline[ci];
+    }
+    b[bi] = 0;
+    s->offset_cmdlines += bi + 1;
     return s->mb_buf_phys + p;
 }
 
@@ -124,6 +137,18 @@  static void mb_add_mod(MultibootState *s,
     s->mb_mods_count++;
 }
 
+static const char *mb_cmdline_next_module(const char *c)
+{
+    for (; *c; c++) {
+        if (mb_is_cmdline_quote(c)) {
+            c++;
+        } else if (c[0] == ',') {
+            return c;
+        }
+    }
+    return 0;
+}
+
 int load_multiboot(void *fw_cfg,
                    FILE *f,
                    const char *kernel_filename,
@@ -238,7 +263,7 @@  int load_multiboot(void *fw_cfg,
         const char *r = initrd_filename;
         mbs.mb_buf_size += strlen(r) + 1;
         mbs.mb_mods_avail = 1;
-        while ((r = strchr(r, ','))) {
+        while ((r = mb_cmdline_next_module(r))) {
            mbs.mb_mods_avail++;
            r++;
         }
@@ -261,7 +286,7 @@  int load_multiboot(void *fw_cfg,
             int mb_mod_length;
             uint32_t offs = mbs.mb_buf_size;
 
-            next_initrd = strchr(initrd_filename, ',');
+            next_initrd = (char *)mb_cmdline_next_module(initrd_filename);
             if (next_initrd)
                 *next_initrd = '\0';
             /* if a space comes after the module filename, treat everything