mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
Initialize help when using redis-cli help or redis-cli ? (#10382)
The following usage will output an empty newline: ``` > redis-cli help set empty line ``` The reason is that in interactive mode, we have called `cliInitHelp`, which initializes help. When using `redis-cli help xxx` or `redis-cli help ? xxx`, we can't match the command due to empty `helpEntries`, so we output an empty newline. In this commit, we will call `cliInitHelp` to init the help. Note that in this case, we need to call `cliInitHelp` (COMMAND DOCS) every time, which i think is acceptable. So now the output will look like: ``` [redis]# src/redis-cli help get GET key summary: Get the value of a key since: 1.0.0 group: string [redis]# ``` Fixes #10378 This PR also fix a redis-cli crash when using `--ldb --eval`: ``` [root]# src/redis-cli --ldb --eval test.lua test 1 Lua debugging session started, please use: quit -- End the session. restart -- Restart the script in debug mode again. help -- Show Lua script debugging commands. * Stopped at 1, stop reason = step over -> 1 local num = redis.call('GET', KEYS[1]); redis-cli: redis-cli.c:718: cliCountCommands: Assertion `commandTable->element[i]->type == 1' failed. Aborted ``` Because in ldb mode, `COMMAND DOCS` or `COMMAND` will return an array, only with one element, and the type is `REDIS_REPLY_STATUS`, the result is `<error> Unknown Redis Lua debugger command or wrong number of arguments`. So if we are in the ldb mode, and init the Redis HELP, we will get the wrong response and crash the redis-cli. In ldb mode we don't initialize HELP, help is only initialized after the lua debugging session ends. It was broken in #10043
This commit is contained in:
parent
11b071a22b
commit
1797330e2e
@ -282,7 +282,7 @@ static void usage(int err);
|
|||||||
static void slaveMode(void);
|
static void slaveMode(void);
|
||||||
char *redisGitSHA1(void);
|
char *redisGitSHA1(void);
|
||||||
char *redisGitDirty(void);
|
char *redisGitDirty(void);
|
||||||
static int cliConnect(int force);
|
static int cliConnect(int flags);
|
||||||
|
|
||||||
static char *getInfoField(char *info, char *field);
|
static char *getInfoField(char *info, char *field);
|
||||||
static long getLongInfoField(char *info, char *field);
|
static long getLongInfoField(char *info, char *field);
|
||||||
@ -800,7 +800,12 @@ static void cliInitHelp(void) {
|
|||||||
redisReply *commandTable;
|
redisReply *commandTable;
|
||||||
dict *groups;
|
dict *groups;
|
||||||
|
|
||||||
if (cliConnect(CC_QUIET) == REDIS_ERR) return;
|
if (cliConnect(CC_QUIET) == REDIS_ERR) {
|
||||||
|
/* Can not connect to the server, but we still want to provide
|
||||||
|
* help, generate it only from the old help.h data instead. */
|
||||||
|
cliOldInitHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
commandTable = redisCommand(context, "COMMAND DOCS");
|
commandTable = redisCommand(context, "COMMAND DOCS");
|
||||||
if (commandTable == NULL || commandTable->type == REDIS_REPLY_ERROR) {
|
if (commandTable == NULL || commandTable->type == REDIS_REPLY_ERROR) {
|
||||||
/* New COMMAND DOCS subcommand not supported - generate help from old help.h data instead. */
|
/* New COMMAND DOCS subcommand not supported - generate help from old help.h data instead. */
|
||||||
@ -870,6 +875,12 @@ static void cliOutputHelp(int argc, char **argv) {
|
|||||||
group = argv[0]+1;
|
group = argv[0]+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (helpEntries == NULL) {
|
||||||
|
/* Initialize the help using the results of the COMMAND command.
|
||||||
|
* In case we are using redis-cli help XXX, we need to init it. */
|
||||||
|
cliInitHelp();
|
||||||
|
}
|
||||||
|
|
||||||
assert(argc > 0);
|
assert(argc > 0);
|
||||||
for (i = 0; i < helpEntriesLen; i++) {
|
for (i = 0; i < helpEntriesLen; i++) {
|
||||||
entry = &helpEntries[i];
|
entry = &helpEntries[i];
|
||||||
@ -1713,12 +1724,6 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
|
|||||||
size_t *argvlen;
|
size_t *argvlen;
|
||||||
int j, output_raw;
|
int j, output_raw;
|
||||||
|
|
||||||
if (!config.eval_ldb && /* In debugging mode, let's pass "help" to Redis. */
|
|
||||||
(!strcasecmp(command,"help") || !strcasecmp(command,"?"))) {
|
|
||||||
cliOutputHelp(--argc, ++argv);
|
|
||||||
return REDIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context == NULL) return REDIS_ERR;
|
if (context == NULL) return REDIS_ERR;
|
||||||
|
|
||||||
output_raw = 0;
|
output_raw = 0;
|
||||||
@ -2420,6 +2425,17 @@ static int confirmWithYes(char *msg, int ignore_force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int issueCommandRepeat(int argc, char **argv, long repeat) {
|
static int issueCommandRepeat(int argc, char **argv, long repeat) {
|
||||||
|
/* In Lua debugging mode, we want to pass the "help" to Redis to get
|
||||||
|
* it's own HELP message, rather than handle it by the CLI, see ldbRepl.
|
||||||
|
*
|
||||||
|
* For the normal Redis HELP, we can process it without a connection. */
|
||||||
|
if (!config.eval_ldb &&
|
||||||
|
(!strcasecmp(argv[0],"help") || !strcasecmp(argv[0],"?")))
|
||||||
|
{
|
||||||
|
cliOutputHelp(--argc, ++argv);
|
||||||
|
return REDIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (config.cluster_reissue_command || context == NULL ||
|
if (config.cluster_reissue_command || context == NULL ||
|
||||||
context->err == REDIS_ERR_IO || context->err == REDIS_ERR_EOF)
|
context->err == REDIS_ERR_IO || context->err == REDIS_ERR_EOF)
|
||||||
@ -2439,6 +2455,8 @@ static int issueCommandRepeat(int argc, char **argv, long repeat) {
|
|||||||
}
|
}
|
||||||
if (cliSendCommand(argc,argv,repeat) != REDIS_OK) {
|
if (cliSendCommand(argc,argv,repeat) != REDIS_OK) {
|
||||||
cliPrintContextError();
|
cliPrintContextError();
|
||||||
|
redisFree(context);
|
||||||
|
context = NULL;
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2576,8 +2594,13 @@ static void repl(void) {
|
|||||||
int argc;
|
int argc;
|
||||||
sds *argv;
|
sds *argv;
|
||||||
|
|
||||||
|
/* There is no need to initialize redis HELP when we are in lua debugger mode.
|
||||||
|
* It has its own HELP and commands (COMMAND or COMMAND DOCS will fail and got nothing).
|
||||||
|
* We will initialize the redis HELP after the Lua debugging session ended.*/
|
||||||
|
if (!config.eval_ldb) {
|
||||||
/* Initialize the help using the results of the COMMAND command. */
|
/* Initialize the help using the results of the COMMAND command. */
|
||||||
cliInitHelp();
|
cliInitHelp();
|
||||||
|
}
|
||||||
|
|
||||||
config.interactive = 1;
|
config.interactive = 1;
|
||||||
linenoiseSetMultiLine(1);
|
linenoiseSetMultiLine(1);
|
||||||
@ -2679,6 +2702,7 @@ static void repl(void) {
|
|||||||
printf("\n(Lua debugging session ended%s)\n\n",
|
printf("\n(Lua debugging session ended%s)\n\n",
|
||||||
config.eval_ldb_sync ? "" :
|
config.eval_ldb_sync ? "" :
|
||||||
" -- dataset changes rolled back");
|
" -- dataset changes rolled back");
|
||||||
|
cliInitHelp();
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed = mstime()-start_time;
|
elapsed = mstime()-start_time;
|
||||||
@ -9005,10 +9029,11 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, we have some arguments to execute */
|
/* Otherwise, we have some arguments to execute */
|
||||||
if (cliConnect(0) != REDIS_OK) exit(1);
|
|
||||||
if (config.eval) {
|
if (config.eval) {
|
||||||
|
if (cliConnect(0) != REDIS_OK) exit(1);
|
||||||
return evalMode(argc,argv);
|
return evalMode(argc,argv);
|
||||||
} else {
|
} else {
|
||||||
|
cliConnect(CC_QUIET);
|
||||||
return noninteractive(argc,argv);
|
return noninteractive(argc,argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user