mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-14 01:30:54 +00:00
MINOR: cli: add two new states to print messages on the CLI
Right now we used to have extremely inconsistent states to report output, one is CLI_ST_PRINT which prints constant message cli->msg with the assigned severity, and CLI_ST_PRINT_FREE which prints dynamically allocated cli->err with severity LOG_ERR, and nothing in between, eventhough it's useful to be able to report dynamically allocated messages as well as constant error messages. This patch adds two extra states, which are not particularly well named given the constraints imposed by existing ones. One is CLI_ST_PRINT_ERR which prints a constant error message. The other one is CLI_ST_PRINT_DYN which prints a dynamically allocated message. By doing so we maintain the compatibility with current code. It is important to keep in mind that we cannot pre-initialize pointers and automatically detect what message type it is based on the assigned fields, because the CLI's context is in a union shared with all other users, thus unused fields contain anything upon return. This is why we have no choice but using 4 states. Keeping the two fields <msg> and <err> remains useful because one is const and not the other one, and this catches may copy-paste mistakes. It's just that <err> is pretty confusing here, it should be renamed.
This commit is contained in:
parent
247a8b1d81
commit
d50c7feaa1
@ -46,8 +46,10 @@ enum {
|
||||
CLI_ST_GETREQ, /* wait for a request */
|
||||
CLI_ST_OUTPUT, /* all states after this one are responses */
|
||||
CLI_ST_PROMPT, /* display the prompt (first output, same code) */
|
||||
CLI_ST_PRINT, /* display message in cli->msg */
|
||||
CLI_ST_PRINT_FREE, /* display message in cli->msg. After the display, free the pointer */
|
||||
CLI_ST_PRINT, /* display const message in cli->msg */
|
||||
CLI_ST_PRINT_ERR, /* display const error in cli->msg */
|
||||
CLI_ST_PRINT_DYN, /* display dynamic message in cli->err. After the display, free the pointer */
|
||||
CLI_ST_PRINT_FREE, /* display dynamic error in cli->err. After the display, free the pointer */
|
||||
CLI_ST_CALLBACK, /* custom callback pointer */
|
||||
};
|
||||
|
||||
|
49
src/cli.c
49
src/cli.c
@ -767,30 +767,47 @@ static void cli_io_handler(struct appctx *appctx)
|
||||
req->flags |= CF_READ_DONTWAIT; /* we plan to read small requests */
|
||||
}
|
||||
else { /* output functions */
|
||||
const char *msg;
|
||||
int sev;
|
||||
|
||||
switch (appctx->st0) {
|
||||
case CLI_ST_PROMPT:
|
||||
break;
|
||||
case CLI_ST_PRINT:
|
||||
if (cli_output_msg(res, appctx->ctx.cli.msg, appctx->ctx.cli.severity,
|
||||
cli_get_severity_output(appctx)) != -1)
|
||||
appctx->st0 = CLI_ST_PROMPT;
|
||||
else
|
||||
si_rx_room_blk(si);
|
||||
break;
|
||||
case CLI_ST_PRINT_FREE: {
|
||||
const char *msg = appctx->ctx.cli.err;
|
||||
case CLI_ST_PRINT: /* print const message in msg */
|
||||
case CLI_ST_PRINT_ERR: /* print const error in msg */
|
||||
case CLI_ST_PRINT_DYN: /* print dyn message in msg, free */
|
||||
case CLI_ST_PRINT_FREE: /* print dyn error in err, free */
|
||||
if (appctx->st0 == CLI_ST_PRINT || appctx->st0 == CLI_ST_PRINT_ERR) {
|
||||
sev = appctx->st0 == CLI_ST_PRINT_ERR ?
|
||||
LOG_ERR : appctx->ctx.cli.severity;
|
||||
msg = appctx->ctx.cli.msg;
|
||||
}
|
||||
else if (appctx->st0 == CLI_ST_PRINT_DYN || appctx->st0 == CLI_ST_PRINT_FREE) {
|
||||
sev = appctx->st0 == CLI_ST_PRINT_FREE ?
|
||||
LOG_ERR : appctx->ctx.cli.severity;
|
||||
msg = appctx->ctx.cli.err;
|
||||
if (!msg) {
|
||||
sev = LOG_ERR;
|
||||
msg = "Out of memory.\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
sev = LOG_ERR;
|
||||
msg = "Internal error.\n";
|
||||
}
|
||||
|
||||
if (!msg)
|
||||
msg = "Out of memory.\n";
|
||||
|
||||
if (cli_output_msg(res, msg, LOG_ERR, cli_get_severity_output(appctx)) != -1) {
|
||||
free(appctx->ctx.cli.err);
|
||||
if (cli_output_msg(res, msg, sev, cli_get_severity_output(appctx)) != -1) {
|
||||
if (appctx->st0 == CLI_ST_PRINT_FREE ||
|
||||
appctx->st0 == CLI_ST_PRINT_DYN) {
|
||||
free(appctx->ctx.cli.err);
|
||||
appctx->ctx.cli.err = NULL;
|
||||
}
|
||||
appctx->st0 = CLI_ST_PROMPT;
|
||||
}
|
||||
else
|
||||
si_rx_room_blk(si);
|
||||
break;
|
||||
}
|
||||
|
||||
case CLI_ST_CALLBACK: /* use custom pointer */
|
||||
if (appctx->io_handler)
|
||||
if (appctx->io_handler(appctx)) {
|
||||
@ -891,7 +908,7 @@ static void cli_release_handler(struct appctx *appctx)
|
||||
appctx->io_release(appctx);
|
||||
appctx->io_release = NULL;
|
||||
}
|
||||
else if (appctx->st0 == CLI_ST_PRINT_FREE) {
|
||||
else if (appctx->st0 == CLI_ST_PRINT_FREE || appctx->st0 == CLI_ST_PRINT_DYN) {
|
||||
free(appctx->ctx.cli.err);
|
||||
appctx->ctx.cli.err = NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user