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)
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;
......
......@@ -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)
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
......
......@@ -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) {
......
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