Skip to content

Commit

Permalink
redis-cli reads specified number of replies for UNSUBSCRIBE/PUNSUBSCR…
Browse files Browse the repository at this point in the history
…IBE/SUNSUBSCRIBE (redis#11047)

In unsubscribe related commands, we need to read the specified
number of replies according to the number of parameters.

These commands may return multiple RESP replies, and currently
redis-cli only tries to read only one reply.

Fixes redis#11046, this redis-cli bug seems to be there forever.
Note that the [UN]SUBSCRIBE command response is a bit awkward
see: redis/redis-doc#2327
  • Loading branch information
enjoy-binbin committed Jul 31, 2023
1 parent f538726 commit 39cded5
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/redis-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -1739,6 +1739,7 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
char *command = argv[0];
size_t *argvlen;
int j, output_raw;
int is_unsubscribe_command = 0; /* Is it an unsubscribe related command? */

if (context == NULL) return REDIS_ERR;

Expand Down Expand Up @@ -1777,6 +1778,9 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
if (!strcasecmp(command,"subscribe") ||
!strcasecmp(command,"psubscribe") ||
!strcasecmp(command,"ssubscribe")) config.pubsub_mode = 1;
if (!strcasecmp(command,"unsubscribe") ||
!strcasecmp(command,"punsubscribe") ||
!strcasecmp(command,"sunsubscribe")) is_unsubscribe_command = 1;
if (!strcasecmp(command,"sync") ||
!strcasecmp(command,"psync")) config.slave_mode = 1;

Expand Down Expand Up @@ -1807,6 +1811,22 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
works well with the interval option. */
while(repeat < 0 || repeat-- > 0) {
redisAppendCommandArgv(context,argc,(const char**)argv,argvlen);

if (is_unsubscribe_command) {
/* In unsubscribe related commands, we need to read the specified
* number of replies according to the number of parameters. */
argc--; /* Skip the command */
do {
if (cliReadReply(output_raw) != REDIS_OK) {
cliPrintContextError();
exit(1);
}
fflush(stdout);
} while(--argc);
zfree(argvlen);
continue;
}

if (config.monitor_mode) {
do {
if (cliReadReply(output_raw) != REDIS_OK) {
Expand Down

0 comments on commit 39cded5

Please sign in to comment.