r630 - in trunk/varnish-cache: bin/varnishd include

phk at projects.linpro.no phk at projects.linpro.no
Fri Aug 4 08:53:26 CEST 2006


Author: phk
Date: 2006-08-04 08:53:26 +0200 (Fri, 04 Aug 2006)
New Revision: 630

Modified:
   trunk/varnish-cache/bin/varnishd/common_cli.c
   trunk/varnish-cache/bin/varnishd/common_cli.h
   trunk/varnish-cache/bin/varnishd/mgt_cli.c
   trunk/varnish-cache/include/cli.h
Log:
Change the CLI protocol in a subtle but useful way:

The first line of the response has a fixed format ("%-3d %-8u\n")
and consequently fixed length (CLI_LINE0_LEN == 13).

This makes parsing responses more efficient.  Add a function
in common_cli to do so.




Modified: trunk/varnish-cache/bin/varnishd/common_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/common_cli.c	2006-08-04 06:23:08 UTC (rev 629)
+++ trunk/varnish-cache/bin/varnishd/common_cli.c	2006-08-04 06:53:26 UTC (rev 630)
@@ -52,9 +52,14 @@
 {
 	int i, l;
 	struct iovec iov[3];
-	char res[32];
+	char res[CLI_LINE0_LEN + 2];	/*
+					 * NUL + one more so we can catch
+					 * any misformats by snprintf
+					 */
 
-	sprintf(res, "%d %d\n", cli->result, sbuf_len(cli->sb));
+	i = snprintf(res, sizeof res,
+	    "%-3d %-8d\n", cli->result, sbuf_len(cli->sb));
+	assert(i == CLI_LINE0_LEN);
 	iov[0].iov_base = (void*)(uintptr_t)res;
 	iov[1].iov_base = (void*)(uintptr_t)sbuf_data(cli->sb);
 	iov[2].iov_base = (void*)(uintptr_t)"\n";
@@ -65,3 +70,36 @@
 	i = writev(fd, iov, 3);
 	return (i != l);
 }
+
+int
+cli_readres(int fd, unsigned *status, char **ptr)
+{
+	char res[CLI_LINE0_LEN + 1];	/* For NUL */
+	int i, j;
+	unsigned u, v;
+	char *p;
+
+	i = read(fd, res, CLI_LINE0_LEN);
+	if (i < 0)
+		return (i);
+	assert(i == CLI_LINE0_LEN);	/* XXX: handle */
+	assert(res[3] == ' ');
+	assert(res[CLI_LINE0_LEN - 1] == '\n');
+	j = sscanf(res, "%u %u\n", &u, &v);
+	assert(j == 2);
+	if (status != NULL)
+		*status = u;
+	p = malloc(v + 1);
+	assert(p != NULL);
+	i = read(fd, p, v + 1);
+	if (i < 0)
+		return (i);
+	assert(i == v + 1);
+	assert(p[v] == '\n');
+	p[v] = '\0';
+	if (ptr == NULL)
+		free(p);
+	else
+		*ptr = p;
+	return (0);
+}

Modified: trunk/varnish-cache/bin/varnishd/common_cli.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/common_cli.h	2006-08-04 06:23:08 UTC (rev 629)
+++ trunk/varnish-cache/bin/varnishd/common_cli.h	2006-08-04 06:53:26 UTC (rev 630)
@@ -13,4 +13,5 @@
 void cli_suspend(struct cli *cli);
 void cli_resume(struct cli *cli);
 int cli_writeres(int fd, struct cli *cli);
+int cli_readres(int fd, unsigned *status, char **ptr);
 extern struct cli_proto CLI_cmds[];

Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_cli.c	2006-08-04 06:23:08 UTC (rev 629)
+++ trunk/varnish-cache/bin/varnishd/mgt_cli.c	2006-08-04 06:53:26 UTC (rev 630)
@@ -37,18 +37,21 @@
 }
 
 /*--------------------------------------------------------------------
- * Passthru of cli commands.
+ * Passthru of cli commands.  It is more or less just undoing what
+ * the cli parser did, but such is life...
  */
 
 static void
 mcf_passthru(struct cli *cli, char **av, void *priv)
 {
-	char buf[BUFSIZ], *bp, *be;
-	char *p;
+	char *p, *q, *r;
 	unsigned u, v;
-	int i, j, k;
+	int i;
 
+	(void)priv;
+
 	AZ(pthread_mutex_lock(&cli_mtx));
+
 	/* Request */
 	if (cli_o <= 0) {
 		AZ(pthread_mutex_unlock(&cli_mtx));
@@ -56,46 +59,37 @@
 		cli_out(cli, "Cache process not running");
 		return;
 	}
-	(void)priv;
-	bp = buf;
-	be = bp + sizeof buf;
+	v = 0;
+	for (u = 1; av[u] != NULL; u++)
+		v += strlen(av[u]) + 3;
+	p = malloc(v);
+	assert(p != NULL);
+	q = p;
 	for (u = 1; av[u] != NULL; u++) {
-		v = strlen(av[u]);
-		if (5 + bp + 4 * v > be) {
-			*bp = '\0';
-			v = bp - buf;
-			i = write(cli_o, buf, v);
-			assert(i == v);
-			bp = buf;
-		}
-		*bp++ = '"';
-		for (p = av[u]; *p; p++) {
-			switch (*p) {
-			case '\\':	*bp++ = '\\'; *bp++ = '\\'; break;
-			case '\n':	*bp++ = '\\'; *bp++ = 'n'; break;
-			case '"':	*bp++ = '\\'; *bp++ = '"'; break;
-			default:	*bp++ = *p; break;
+		*q++ = '"';
+		for (r = av[u]; *r; r++) {
+			switch (*r) {
+			case '\\':	*q++ = '\\'; *q++ = '\\'; break;
+			case '\n':	*q++ = '\\'; *q++ = 'n'; break;
+			case '"':	*q++ = '\\'; *q++ = '"'; break;
+			default:	*q++ = *r; break;
 			}
 		}
-		*bp++ = '"';
-		*bp++ = ' ';
+		*q++ = '"';
+		*q++ = ' ';
 	}
-	if (bp != buf) {
-		*bp++ = '\n';
-		v = bp - buf;
-		i = write(cli_o, buf, v);
-		assert(i == v);
-	}
+	*q++ = '\n';
+	v = q - p;
+	i = write(cli_o, p, v);
+	assert(i == v);
+	free(p);
 
-	/* Response */
-	i = read(cli_i, buf, sizeof buf - 1);
-	assert(i > 0);
-	buf[i] = '\0';
-	j = sscanf(buf, "%u %u\n%n", &u, &v, &k);
-	assert(j == 2);
-	assert(i == k + v + 1);
+	i = cli_readres(cli_i, &u, &p);
+	assert(i == 0);
 	cli_result(cli, u);
-	cli_out(cli, "%*.*s", v, v, buf + k);
+	cli_out(cli, "%s", p);
+	free(p);
+
 	AZ(pthread_mutex_unlock(&cli_mtx));
 }
 

Modified: trunk/varnish-cache/include/cli.h
===================================================================
--- trunk/varnish-cache/include/cli.h	2006-08-04 06:23:08 UTC (rev 629)
+++ trunk/varnish-cache/include/cli.h	2006-08-04 06:53:26 UTC (rev 630)
@@ -181,3 +181,6 @@
 	CLIS_OK		= 200,
 	CLIS_CANT	= 300
 };
+
+/* Length of first line of response */
+#define CLI_LINE0_LEN	13




More information about the varnish-commit mailing list