Commit 8e09fd8b authored by Dridi Boukelmoune's avatar Dridi Boukelmoune

Handle VUT errors in a callback

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