]> xenbits.xensource.com Git - rumpuser-xen.git/commitdiff
callmain: Split up command line into separate arguments for main()
authorIan Jackson <ian.jackson@eu.citrix.com>
Thu, 19 Jun 2014 15:45:48 +0000 (16:45 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Tue, 24 Jun 2014 16:32:38 +0000 (17:32 +0100)
We understand '' and "" quoting, with \-escapes for ' and ", like a
shell would.  (Of course we don't interpolate ` or $ in "".)

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
callmain.c

index 682a083bb9c1cf04211afb7fd15b0e2a4f28d550..8721c6c899f82ff272f0782d2a4c80b730d067cc 100644 (file)
  */
 
 #include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 #include <xen/xen.h>
 
 extern int main(int argc, char **argv);
 
+static void parseargs(void *cmdline, int *nargs, char **outarray) {
+       char *p = cmdline;
+       char *out = 0;
+       int quote = -1; /* -1 means outside arg, 0 or '"' or '\'' inside */
+
+       *nargs = 0;
+
+       for (;;) {
+               int ac = *p++;
+               int rc = ac;
+               if (ac == '\\')
+                       rc = *p++;
+               if (!rc || ac==' ' || ac=='\n' || ac=='\t') {
+                       /* any kind of delimiter */
+                       if (!rc || quote==0) {
+                               /* ending an argument */
+                               if (out)
+                                       *out++ = 0;
+                               quote = -1;
+                       }
+                       if (!rc)
+                               /* definitely quit then */
+                               break;
+                       if (quote<0)
+                               /* not in an argument now */
+                               continue;
+               }
+               if (quote<0) {
+                       /* starting an argument */
+                       if (outarray)
+                               outarray[*nargs] = out = p-1;
+                       (*nargs)++;
+                       quote = 0;
+               }
+               if (quote > 0 && ac == quote) {
+                       quote = 0;
+                       continue;
+               }
+               if (ac == '\'' || ac == '"') {
+                       quote = ac;
+                       continue;
+               }
+               if (out)
+                       *out++ = rc;
+       }
+}
+
 int
 __default_app_main(start_info_t *si)
 {
-        char argv0[] = "rumpuser-xen";
-        char *argv[3] = { argv0, (char*)si->cmd_line, 0 };
+       char argv0[] = "rumpuser-xen";
+       int nargs;
+       char **argv;
+
+       parseargs(si->cmd_line, &nargs, 0);
+       argv = malloc(sizeof(*argv) * (nargs+3));
+       argv[0] = argv0;
+       parseargs(si->cmd_line, &nargs, argv+1);
+       argv[nargs+1] = 0;
+       argv[nargs+2] = 0;
 
-        return main(2, argv);
+       return main(nargs+1, argv);
 }
 
 __weak_alias(app_main,__default_app_main)