[master] 8e09fd8 Handle VUT errors in a callback

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Wed Sep 13 22:21:05 UTC 2017


commit 8e09fd8ba9c812d35e6d4031ebf3bfc0e11c07b2
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Tue Sep 5 15:58:16 2017 +0200

    Handle VUT errors in a callback
    
    When omitted, the callback defaults to printing to stderr and exiting
    with the provided status.

diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c
index 7054b6d..b8ebc19 100644
--- a/bin/varnishhist/varnishhist.c
+++ b/bin/varnishhist/varnishhist.c
@@ -516,7 +516,7 @@ main(int argc, char **argv)
 		case 'p':
 			delay = strtod(optarg, NULL);
 			if (delay <= 0)
-				VUT_Error(1, "-p: invalid '%s'", optarg);
+				VUT_Error(vut, 1, "-p: invalid '%s'", optarg);
 			break;
 		case 'P':
 			colon = strchr(optarg, ':');
@@ -545,7 +545,7 @@ main(int argc, char **argv)
 
 			match_tag = VSL_Name2Tag(ptag, colon - ptag);
 			if (match_tag < 0)
-				VUT_Error(1,
+				VUT_Error(vut, 1,
 				    "-P: '%s' is not a valid tag name",
 				    optarg);
 			cli_p.name = "custom";
@@ -557,12 +557,12 @@ main(int argc, char **argv)
 		case 'B':
 			timebend = strtod(optarg, NULL);
 			if (timebend == 0)
-				VUT_Error(1,
+				VUT_Error(vut, 1,
 				    "-B: being able to bend time does not"
 				    " mean we can stop it"
 				    " (invalid factor '%s')", optarg);
 			if (timebend < 0)
-				VUT_Error(1,
+				VUT_Error(vut, 1,
 				    "-B: being able to bend time does not"
 				    " mean we can make it go backwards"
 				    " (invalid factor '%s')", optarg);
@@ -579,7 +579,7 @@ main(int argc, char **argv)
 	/* Check for valid grouping mode */
 	assert(vut->g_arg < VSL_g__MAX);
 	if (vut->g_arg != VSL_g_vxid && vut->g_arg != VSL_g_request)
-		VUT_Error(1, "Invalid grouping mode: %s"
+		VUT_Error(vut, 1, "Invalid grouping mode: %s"
 		    " (only vxid and request are supported)",
 		    VSLQ_grouping[vut->g_arg]);
 
@@ -592,7 +592,7 @@ main(int argc, char **argv)
 	}
 	AN(active_profile);
 	if (!active_profile->name)
-		VUT_Error(1, "-P: No such profile '%s'", profile);
+		VUT_Error(vut, 1, "-P: No such profile '%s'", profile);
 
 	assert(active_profile->VSL_arg == 'b' ||
 	    active_profile->VSL_arg == 'c');
@@ -622,7 +622,7 @@ main(int argc, char **argv)
 	VUT_Setup(vut);
 	ident = VSM_Dup(vut->vsm, "Arg", "-i");
 	if (pthread_create(&thr, NULL, do_curses, NULL) != 0)
-		VUT_Error(1, "pthread_create(): %s", strerror(errno));
+		VUT_Error(vut, 1, "pthread_create(): %s", strerror(errno));
 	vut->dispatch_f = accumulate;
 	vut->dispatch_priv = NULL;
 	vut->sighup_f = sighup;
diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c
index 6f6772b..60f46f9 100644
--- a/bin/varnishlog/varnishlog.c
+++ b/bin/varnishlog/varnishlog.c
@@ -83,7 +83,7 @@ openout(int append)
 	else
 		LOG.fo = VSL_WriteOpen(vut->vsl, LOG.w_arg, append, 0);
 	if (LOG.fo == NULL)
-		VUT_Error(2, "Cannot open output file (%s)",
+		VUT_Error(vut, 2, "Cannot open output file (%s)",
 		    LOG.A_opt ? strerror(errno) : VSL_Error(vut->vsl));
 	vut->dispatch_priv = LOG.fo;
 }
@@ -162,7 +162,7 @@ main(int argc, char * const *argv)
 		usage(1);
 
 	if (vut->D_opt && !LOG.w_arg)
-		VUT_Error(1, "Missing -w option");
+		VUT_Error(vut, 1, "Missing -w option");
 
 	/* Setup output */
 	if (LOG.A_opt || !LOG.w_arg)
diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c
index 22391d1..979e598 100644
--- a/bin/varnishncsa/varnishncsa.c
+++ b/bin/varnishncsa/varnishncsa.c
@@ -180,7 +180,7 @@ openout(int append)
 	AN(CTX.w_arg);
 	CTX.fo = fopen(CTX.w_arg, append ? "a" : "w");
 	if (CTX.fo == NULL)
-		VUT_Error(1, "Can't open output file (%s)",
+		VUT_Error(vut, 1, "Can't open output file (%s)",
 		    strerror(errno));
 }
 
@@ -630,19 +630,19 @@ parse_x_format(char *buf)
 		while (*e != '\0')
 			e++;
 		if (e == buf)
-			VUT_Error(1, "Missing tag in VSL:");
+			VUT_Error(vut, 1, "Missing tag in VSL:");
 		if (e[-1] == ']') {
 			r = e - 1;
 			while (r > buf && *r != '[')
 				r--;
 			if (r == buf || r[1] == ']')
-				VUT_Error(1, "Syntax error: VSL:%s", buf);
+				VUT_Error(vut, 1, "Syntax error: VSL:%s", buf);
 			e[-1] = '\0';
 			lval = strtol(r + 1, &s, 10);
 			if (s != e - 1)
-				VUT_Error(1, "Syntax error: VSL:%s]", buf);
+				VUT_Error(vut, 1, "Syntax error: VSL:%s]", buf);
 			if (lval <= 0 || lval > 255) {
-				VUT_Error(1,
+				VUT_Error(vut, 1,
 				    "Syntax error. Field specifier must be"
 				    " between 1 and 255: %s]",
 				    buf);
@@ -661,15 +661,15 @@ parse_x_format(char *buf)
 			r = NULL;
 		}
 		if (slt == -2)
-			VUT_Error(1, "Tag not unique: %s", buf);
+			VUT_Error(vut, 1, "Tag not unique: %s", buf);
 		if (slt == -1)
-			VUT_Error(1, "Unknown log tag: %s", buf);
+			VUT_Error(vut, 1, "Unknown log tag: %s", buf);
 		assert(slt >= 0);
 
 		addf_vsl(slt, lval, r);
 		return;
 	}
-	VUT_Error(1, "Unknown formatting extension: %s", buf);
+	VUT_Error(vut, 1, "Unknown formatting extension: %s", buf);
 }
 
 static void
@@ -763,7 +763,7 @@ parse_format(const char *format)
 			while (*q && *q != '}')
 				q++;
 			if (!*q)
-				VUT_Error(1, "Unmatched bracket at: %s",
+				VUT_Error(vut, 1, "Unmatched bracket at: %s",
 				    p - 2);
 			assert(q - p < sizeof buf - 1);
 			strncpy(buf, p, q - p);
@@ -783,14 +783,14 @@ parse_format(const char *format)
 				parse_x_format(buf);
 				break;
 			default:
-				VUT_Error(1,
+				VUT_Error(vut, 1,
 				    "Unknown format specifier at: %s",
 				    p - 2);
 			}
 			p = q;
 			break;
 		default:
-			VUT_Error(1, "Unknown format specifier at: %s",
+			VUT_Error(vut, 1, "Unknown format specifier at: %s",
 			    p - 1);
 		}
 	}
@@ -1131,16 +1131,16 @@ read_format(const char *formatfile)
 
 	fmtfile = fopen(formatfile, "r");
 	if (fmtfile == NULL)
-		VUT_Error(1, "Can't open format file (%s)",
+		VUT_Error(vut, 1, "Can't open format file (%s)",
 		    strerror(errno));
 	AN(fmtfile);
 	fmtlen = getline(&fmt, &len, fmtfile);
 	if (fmtlen == -1) {
 		free(fmt);
 		if (feof(fmtfile))
-			VUT_Error(1, "Empty format file");
+			VUT_Error(vut, 1, "Empty format file");
 		else
-			VUT_Error(1, "Can't read format from file (%s)",
+			VUT_Error(vut, 1, "Can't read format from file (%s)",
 			    strerror(errno));
 	}
 	fclose(fmtfile);
@@ -1216,12 +1216,12 @@ main(int argc, char * const *argv)
 		usage(1);
 
 	if (vut->D_opt && !CTX.w_arg)
-		VUT_Error(1, "Missing -w option");
+		VUT_Error(vut, 1, "Missing -w option");
 
 	/* Check for valid grouping mode */
 	assert(vut->g_arg < VSL_g__MAX);
 	if (vut->g_arg != VSL_g_vxid && vut->g_arg != VSL_g_request)
-		VUT_Error(1, "Invalid grouping mode: %s",
+		VUT_Error(vut, 1, "Invalid grouping mode: %s",
 		    VSLQ_grouping[vut->g_arg]);
 
 	/* Prepare output format */
diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c
index 7d02906..29fae97 100644
--- a/bin/varnishstat/varnishstat.c
+++ b/bin/varnishstat/varnishstat.c
@@ -293,7 +293,7 @@ main(int argc, char * const *argv)
 		default:
 			i = VSM_Arg(vd, opt, optarg);
 			if (i < 0)
-				VUT_Error(1, "%s", VSM_Error(vd));
+				VUT_Error(vut, 1, "%s", VSM_Error(vd));
 			if (!i)
 				usage(1);
 		}
@@ -306,7 +306,7 @@ main(int argc, char * const *argv)
 		curses = 1;
 
 	if (VSM_Attach(vd, STDERR_FILENO))
-		VUT_Error(1, "%s", VSM_Error(vd));
+		VUT_Error(vut, 1, "%s", VSM_Error(vd));
 
 	if (curses)
 		do_curses(vd, vsc, 1.0);
diff --git a/include/vut.h b/include/vut.h
index 2e3a3c7..1097700 100644
--- a/include/vut.h
+++ b/include/vut.h
@@ -34,6 +34,7 @@ struct vopt_spec;
 
 typedef void VUT_sighandler_f(int);
 typedef int VUT_cb_f(struct VUT *);
+typedef void VUT_error_f(struct VUT *, int, const char *, va_list);
 
 struct VUT {
 	const char	*progname;
@@ -60,13 +61,13 @@ struct VUT {
 	/* Callback functions */
 	VUT_cb_f	*idle_f;
 	VUT_cb_f	*sighup_f;
+	VUT_error_f	*error_f;
 	VSLQ_dispatch_f	*dispatch_f;
 	void		*dispatch_priv;
 };
 
-//lint -sem(VUT_Error, r_no)
-void VUT_Error(int status, const char *fmt, ...)
-	__v_printflike(2, 3) __attribute__((__noreturn__));
+void VUT_Error(struct VUT *, int status, const char *fmt, ...)
+    __v_printflike(3, 4);
 
 int VUT_Arg(struct VUT *, int opt, const char *arg);
 
diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c
index 6103e9c..fe8e815 100644
--- a/lib/libvarnishapi/vut.c
+++ b/lib/libvarnishapi/vut.c
@@ -63,10 +63,10 @@ static struct vpf_fh	*pfh;
 static unsigned		daemonized;
 
 static int
-vut_daemon(void)
+vut_daemon(struct VUT *vut)
 {
 	if (daemonized)
-		VUT_Error(1, "Already running as a daemon");
+		VUT_Error(vut, 1, "Already running as a daemon");
 	daemonized = 1;
 	return (varnish_daemon(0, 0));
 }
@@ -100,21 +100,30 @@ vut_dispatch(struct VSL_data *vsl, struct VSL_transaction * const trans[],
 	return (i);
 }
 
-void
-VUT_Error(int status, const char *fmt, ...)
+//lint -sem(vut_error, r_no)
+static void __attribute__((__noreturn__)) __match_proto__(VUT_error_f)
+vut_error(struct VUT *vut, int status, const char *fmt, va_list ap)
 {
-	va_list ap;
 
-	assert(status != 0);
+	AN(vut);
 	AN(fmt);
-	va_start(ap, fmt);
 	vfprintf(stderr, fmt, ap);
-	va_end(ap);
 	fprintf(stderr, "\n");
 
 	exit(status);
 }
 
+void
+VUT_Error(struct VUT *vut, int status, const char *fmt, ...)
+{
+	va_list ap;
+
+	assert(status != 0);
+	va_start(ap, fmt);
+	vut_error(vut, status, fmt, ap);
+	va_end(ap);
+}
+
 int
 VUT_Arg(struct VUT *vut, int opt, const char *arg)
 {
@@ -135,16 +144,16 @@ VUT_Arg(struct VUT *vut, int opt, const char *arg)
 		AN(arg);
 		vut->g_arg = VSLQ_Name2Grouping(arg, -1);
 		if (vut->g_arg == -2)
-			VUT_Error(1, "Ambiguous grouping type: %s", arg);
+			VUT_Error(vut, 1, "Ambiguous grouping type: %s", arg);
 		else if (vut->g_arg < 0)
-			VUT_Error(1, "Unknown grouping type: %s", arg);
+			VUT_Error(vut, 1, "Unknown grouping type: %s", arg);
 		return (1);
 	case 'k':
 		/* Log transaction limit */
 		AN(arg);
 		vut->k_arg = (int)strtol(arg, &p, 10);
 		if (*p != '\0' || vut->k_arg <= 0)
-			VUT_Error(1, "-k: Invalid number '%s'", arg);
+			VUT_Error(vut, 1, "-k: Invalid number '%s'", arg);
 		return (1);
 	case 'n':
 		/* Varnish instance name */
@@ -178,7 +187,7 @@ VUT_Arg(struct VUT *vut, int opt, const char *arg)
 		AN(vut->vsl);
 		i = VSL_Arg(vut->vsl, opt, arg);
 		if (i < 0)
-			VUT_Error(1, "%s", VSL_Error(vut->vsl));
+			VUT_Error(vut, 1, "%s", VSL_Error(vut->vsl));
 		return (i);
 	}
 }
@@ -203,10 +212,11 @@ VUT_Init(const char *progname, int argc, char * const *argv,
 
 	vut->progname = progname;
 	vut->g_arg = VSL_g_vxid;
+	vut->k_arg = -1;
+	vut->error_f = vut_error;
 	AZ(vut->vsl);
 	vut->vsl = VSL_New();
 	AN(vut->vsl);
-	vut->k_arg = -1;
 	return (vut);
 }
 
@@ -244,45 +254,45 @@ VUT_Setup(struct VUT *vut)
 	/* Check input arguments (2 used for bug in FlexeLint) */
 	if ((vut->n_arg == NULL ? 0 : 2) +
 	    (vut->r_arg == NULL ? 0 : 2) > 2)
-		VUT_Error(1, "Only one of -n and -r options may be used");
+		VUT_Error(vut, 1, "Only one of -n and -r options may be used");
 
 	/* Create and validate the query expression */
 	vut->vslq = VSLQ_New(vut->vsl, NULL, vut->g_arg, vut->q_arg);
 	if (vut->vslq == NULL)
-		VUT_Error(1, "Query expression error:\n%s",
+		VUT_Error(vut, 1, "Query expression error:\n%s",
 		    VSL_Error(vut->vsl));
 
 	/* Setup input */
 	if (vut->r_arg) {
 		c = VSL_CursorFile(vut->vsl, vut->r_arg, 0);
 		if (c == NULL)
-			VUT_Error(1, "%s", VSL_Error(vut->vsl));
+			VUT_Error(vut, 1, "%s", VSL_Error(vut->vsl));
 		VSLQ_SetCursor(vut->vslq, &c);
 		AZ(c);
 	} else {
 		vut->vsm = VSM_New();
 		AN(vut->vsm);
 		if (vut->n_arg && VSM_Arg(vut->vsm, 'n', vut->n_arg) <= 0)
-			VUT_Error(1, "%s", VSM_Error(vut->vsm));
+			VUT_Error(vut, 1, "%s", VSM_Error(vut->vsm));
 		if (vut->t_arg && VSM_Arg(vut->vsm, 't', vut->t_arg) <= 0)
-			VUT_Error(1, "%s", VSM_Error(vut->vsm));
+			VUT_Error(vut, 1, "%s", VSM_Error(vut->vsm));
 		if (VSM_Attach(vut->vsm, STDERR_FILENO))
-			VUT_Error(1, "VSM: %s", VSM_Error(vut->vsm));
+			VUT_Error(vut, 1, "VSM: %s", VSM_Error(vut->vsm));
 		// Cursor is handled in VUT_Main()
 	}
 
 	/* Open PID file */
 	if (vut->P_arg) {
 		if (pfh != NULL)
-			VUT_Error(1, "PID file already created");
+			VUT_Error(vut, 1, "PID file already created");
 		pfh = VPF_Open(vut->P_arg, 0644, NULL);
 		if (pfh == NULL)
-			VUT_Error(1, "%s: %s", vut->P_arg, strerror(errno));
+			VUT_Error(vut, 1, "%s: %s", vut->P_arg, strerror(errno));
 	}
 
 	/* Daemon mode */
-	if (vut->D_opt && vut_daemon() == -1)
-		VUT_Error(1, "Daemon mode: %s", strerror(errno));
+	if (vut->D_opt && vut_daemon(vut) == -1)
+		VUT_Error(vut, 1, "Daemon mode: %s", strerror(errno));
 
 	/* Write PID and setup exit handler */
 	if (vut->P_arg) {


More information about the varnish-commit mailing list