From 046b4f66ef93a30abdc70ceba4681d1b71247587 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 14 Jun 2011 17:28:01 +0200 Subject: [PATCH] redis-cli updated to the same version as the 2.4 branch --- src/redis-cli.c | 110 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 35 deletions(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index f0c712e74..b76e2849e 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -55,6 +55,7 @@ static struct config { int hostport; char *hostsocket; long repeat; + long interval; int dbnum; int interactive; int shutdown; @@ -62,7 +63,6 @@ static struct config { int pubsub_mode; int stdinarg; /* get last arg from stdin. (-x option) */ char *auth; - char *historyfile; int raw_output; /* output mode per command */ sds mb_delim; char prompt[32]; @@ -88,9 +88,11 @@ static long long mstime(void) { static void cliRefreshPrompt(void) { if (config.dbnum == 0) - snprintf(config.prompt,sizeof(config.prompt),"redis> "); + snprintf(config.prompt,sizeof(config.prompt),"redis %s:%d> ", + config.hostip, config.hostport); else - snprintf(config.prompt,sizeof(config.prompt),"redis:%d> ",config.dbnum); + snprintf(config.prompt,sizeof(config.prompt),"redis %s:%d[%d]> ", + config.hostip, config.hostport, config.dbnum); } /*------------------------------------------------------------------------------ @@ -315,10 +317,9 @@ static int cliConnect(int force) { return REDIS_OK; } -static void cliPrintContextErrorAndExit() { +static void cliPrintContextError() { if (context == NULL) return; fprintf(stderr,"Error: %s\n",context->errstr); - exit(1); } static sds cliFormatReplyTTY(redisReply *r, char *prefix) { @@ -395,15 +396,18 @@ static sds cliFormatReplyRaw(redisReply *r) { switch (r->type) { case REDIS_REPLY_NIL: /* Nothing... */ - break; + break; case REDIS_REPLY_ERROR: + out = sdscatlen(out,r->str,r->len); + out = sdscatlen(out,"\n",1); + break; case REDIS_REPLY_STATUS: case REDIS_REPLY_STRING: out = sdscatlen(out,r->str,r->len); - break; + break; case REDIS_REPLY_INTEGER: out = sdscatprintf(out,"%lld",r->integer); - break; + break; case REDIS_REPLY_ARRAY: for (i = 0; i < r->elements; i++) { if (i > 0) out = sdscat(out,config.mb_delim); @@ -411,7 +415,7 @@ static sds cliFormatReplyRaw(redisReply *r) { out = sdscatlen(out,tmp,sdslen(tmp)); sdsfree(tmp); } - break; + break; default: fprintf(stderr,"Unknown reply type: %d\n", r->type); exit(1); @@ -434,7 +438,8 @@ static int cliReadReply(int output_raw_strings) { if (context->err == REDIS_ERR_EOF) return REDIS_ERR; } - cliPrintContextErrorAndExit(); + cliPrintContextError(); + exit(1); return REDIS_ERR; /* avoid compiler warning */ } @@ -460,12 +465,17 @@ static int cliSendCommand(int argc, char **argv, int repeat) { size_t *argvlen; int j, output_raw; - if (context == NULL) { - printf("Not connected, please use: connect \n"); - return REDIS_OK; + if (context == NULL) return REDIS_ERR; + + output_raw = 0; + if (!strcasecmp(command,"info") || + (argc == 2 && !strcasecmp(command,"client") && + !strcasecmp(argv[1],"list"))) + + { + output_raw = 1; } - output_raw = !strcasecmp(command,"info"); if (!strcasecmp(command,"help") || !strcasecmp(command,"?")) { cliOutputHelp(--argc, ++argv); return REDIS_OK; @@ -505,6 +515,8 @@ static int cliSendCommand(int argc, char **argv, int repeat) { cliRefreshPrompt(); } } + if (config.interval) usleep(config.interval); + fflush(stdout); /* Make it grep friendly */ } free(argvlen); @@ -540,6 +552,10 @@ static int parseOptions(int argc, char **argv) { } else if (!strcmp(argv[i],"-r") && !lastarg) { config.repeat = strtoll(argv[i+1],NULL,10); i++; + } else if (!strcmp(argv[i],"-i") && !lastarg) { + double seconds = atof(argv[i+1]); + config.interval = seconds*1000000; + i++; } else if (!strcmp(argv[i],"-n") && !lastarg) { config.dbnum = atoi(argv[i+1]); i++; @@ -592,6 +608,8 @@ static void usage() { " -s Server socket (overrides hostname and port)\n" " -a Password to use when connecting to the server\n" " -r Execute specified command N times\n" +" -i When -r is used, waits seconds per command.\n" +" It is possible to specify sub-second times like -i 0.1.\n" " -n Database number\n" " -x Read last argument from STDIN\n" " -d Multi-bulk delimiter in for raw formatting (default: \\n)\n" @@ -603,6 +621,7 @@ static void usage() { " cat /etc/passwd | redis-cli -x set mypasswd\n" " redis-cli get mypasswd\n" " redis-cli -r 100 lpush mylist x\n" +" redis-cli -r 100 -i 1 info | grep used_memory_human:\n" "\n" "When no command is given, redis-cli starts in interactive mode.\n" "Type \"help\" in interactive mode for information on available commands.\n" @@ -625,19 +644,32 @@ static char **convertToSds(int count, char** args) { #define LINE_BUFLEN 4096 static void repl() { - int argc, j; + sds historyfile = NULL; + int history = 0; char *line; + int argc; sds *argv; config.interactive = 1; linenoiseSetCompletionCallback(completionCallback); + /* Only use history when stdin is a tty. */ + if (isatty(fileno(stdin))) { + history = 1; + + if (getenv("HOME") != NULL) { + historyfile = sdscatprintf(sdsempty(),"%s/.rediscli_history",getenv("HOME")); + linenoiseHistoryLoad(historyfile); + } + } + cliRefreshPrompt(); while((line = linenoise(context ? config.prompt : "not connected> ")) != NULL) { if (line[0] != '\0') { argv = sdssplitargs(line,&argc); - linenoiseHistoryAdd(line); - if (config.historyfile) linenoiseHistorySave(config.historyfile); + if (history) linenoiseHistoryAdd(line); + if (historyfile) linenoiseHistorySave(historyfile); + if (argv == NULL) { printf("Invalid argument(s)\n"); continue; @@ -655,14 +687,25 @@ static void repl() { linenoiseClearScreen(); } else { long long start_time = mstime(), elapsed; + int repeat, skipargs = 0; - if (cliSendCommand(argc,argv,1) != REDIS_OK) { + repeat = atoi(argv[0]); + if (repeat) { + skipargs = 1; + } else { + repeat = 1; + } + + if (cliSendCommand(argc-skipargs,argv+skipargs,repeat) + != REDIS_OK) + { cliConnect(1); - /* If we still cannot send the command, - * print error and abort. */ - if (cliSendCommand(argc,argv,1) != REDIS_OK) - cliPrintContextErrorAndExit(); + /* If we still cannot send the command print error. + * We'll try to reconnect the next time. */ + if (cliSendCommand(argc-skipargs,argv+skipargs,repeat) + != REDIS_OK) + cliPrintContextError(); } elapsed = mstime()-start_time; if (elapsed >= 500) { @@ -671,8 +714,7 @@ static void repl() { } } /* Free the argument vector */ - for (j = 0; j < argc; j++) - sdsfree(argv[j]); + while(argc--) sdsfree(argv[argc]); zfree(argv); } /* linenoise() returns malloc-ed lines like readline() */ @@ -701,6 +743,7 @@ int main(int argc, char **argv) { config.hostport = 6379; config.hostsocket = NULL; config.repeat = 1; + config.interval = 0; config.dbnum = 0; config.interactive = 0; config.shutdown = 0; @@ -708,26 +751,23 @@ int main(int argc, char **argv) { config.pubsub_mode = 0; config.stdinarg = 0; config.auth = NULL; - config.historyfile = NULL; config.raw_output = !isatty(fileno(stdout)) && (getenv("FAKETTY") == NULL); config.mb_delim = sdsnew("\n"); cliInitHelp(); - if (getenv("HOME") != NULL) { - config.historyfile = malloc(256); - snprintf(config.historyfile,256,"%s/.rediscli_history",getenv("HOME")); - linenoiseHistoryLoad(config.historyfile); - } - firstarg = parseOptions(argc,argv); argc -= firstarg; argv += firstarg; - /* Try to connect */ - if (cliConnect(0) != REDIS_OK) exit(1); - /* Start interactive mode when no command is provided */ - if (argc == 0) repl(); + if (argc == 0) { + /* Note that in repl mode we don't abort on connection error. + * A new attempt will be performed for every command send. */ + cliConnect(0); + repl(); + } + /* Otherwise, we have some arguments to execute */ + if (cliConnect(0) != REDIS_OK) exit(1); return noninteractive(argc,convertToSds(argc,argv)); } -- GitLab