fix handling of consecutive optional arguments am: fea05c6dca am: 76bdc68d7e
am: d8c4bac697

Change-Id: Ifcc3ca90850c83f21dbd0eaaf2f3b706de01b75a
diff --git a/minijail0.1 b/minijail0.1
index cf2ccee..52f98e2 100644
--- a/minijail0.1
+++ b/minijail0.1
@@ -64,8 +64,9 @@
 \fB-I\fR
 Run \fIprogram\fR as init (pid 1) inside a new pid namespace (implies \fB-p\fR).
 .TP
-\fB-k <src>,<dest>,<type>[,<flags>]\fR
-Mount \fIsrc\fR, a \fItype\fR filesystem, into the chroot directory at \fIdest\fR, with optional \fIflags\fR.
+\fB-k <src>,<dest>,<type>[,<flags>[,<data>]]\fR
+Mount \fIsrc\fR, a \fItype\fR filesystem, into the chroot directory at \fIdest\fR,
+with optional \fIflags\fR and optional \fIdata\fR (see \fBmount\fR(2)).
 If the mount is not a pseudo filesystem (e.g. proc or sysfs), \fIsrc\fR path
 must be an absolute path (e.g. \fI/dev/sda1\fR and not \fIsda1\fR).
 If the destination does not exist, it will be created as a directory.
diff --git a/minijail0.c b/minijail0.c
index 32995ab..425fbf0 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -92,16 +92,18 @@
 
 static void add_binding(struct minijail *j, char *arg)
 {
-	char *src = strtok(arg, ",");
-	char *dest = strtok(NULL, ",");
-	char *flags = strtok(NULL, ",");
-	if (!src) {
+	char *src = tokenize(&arg, ",");
+	char *dest = tokenize(&arg, ",");
+	char *flags = tokenize(&arg, ",");
+	if (!src || src[0] == '\0' || arg != NULL) {
 		fprintf(stderr, "Bad binding: %s %s\n", src, dest);
 		exit(1);
 	}
-	if (!dest)
+	if (dest == NULL || dest[0] == '\0')
 		dest = src;
-	if (minijail_bind(j, src, dest, flags ? atoi(flags) : 0)) {
+	if (flags == NULL || flags[0] == '\0')
+		flags = "0";
+	if (minijail_bind(j, src, dest, atoi(flags))) {
 		fprintf(stderr, "minijail_bind failed.\n");
 		exit(1);
 	}
@@ -109,10 +111,11 @@
 
 static void add_rlimit(struct minijail *j, char *arg)
 {
-	char *type = strtok(arg, ",");
-	char *cur = strtok(NULL, ",");
-	char *max = strtok(NULL, ",");
-	if (!type || !cur || !max) {
+	char *type = tokenize(&arg, ",");
+	char *cur = tokenize(&arg, ",");
+	char *max = tokenize(&arg, ",");
+	if (!type || type[0] == '\0' || !cur || cur[0] == '\0' ||
+	    !max || max[0] == '\0' || arg != NULL) {
 		fprintf(stderr, "Bad rlimit '%s'.\n", arg);
 		exit(1);
 	}
@@ -125,12 +128,13 @@
 
 static void add_mount(struct minijail *j, char *arg)
 {
-	char *src = strtok(arg, ",");
-	char *dest = strtok(NULL, ",");
-	char *type = strtok(NULL, ",");
-	char *flags = strtok(NULL, ",");
-	char *data = strtok(NULL, ",");
-	if (!src || !dest || !type) {
+	char *src = tokenize(&arg, ",");
+	char *dest = tokenize(&arg, ",");
+	char *type = tokenize(&arg, ",");
+	char *flags = tokenize(&arg, ",");
+	char *data = tokenize(&arg, ",");
+	if (!src || src[0] == '\0' || !dest || dest[0] == '\0' ||
+	    !type || type[0] == '\0' || arg != NULL) {
 		fprintf(stderr, "Bad mount: %s %s %s\n", src, dest, type);
 		exit(1);
 	}
@@ -296,7 +300,7 @@
 	/* clang-format off */
 	printf("Usage: %s [-dGhHiIKlLnNprRstUvyYz]\n"
 	       "  [-a <table>]\n"
-	       "  [-b <src>[,<dest>[,<writeable>]]] [-k <src>,<dest>,<type>[,<flags>][,<data>]]\n"
+	       "  [-b <src>[,<dest>[,<writeable>]]] [-k <src>,<dest>,<type>[,<flags>[,<data>]]]\n"
 	       "  [-c <caps>] [-C <dir>] [-P <dir>] [-e[file]] [-f <file>] [-g <group>]\n"
 	       "  [-m[<uid> <loweruid> <count>]*] [-M[<gid> <lowergid> <count>]*] [--profile <name>]\n"
 	       "  [-R <type,cur,max>] [-S <file>] [-t[size]] [-T <type>] [-u <user>] [-V <file>]\n"