2 * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
3 * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
4 * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
5 * Jan-Erik Rediger <janerik at fnordig dot com>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
12 * * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * * Neither the name of Redis nor the names of its contributors may be used
18 * to endorse or promote products derived from this software without
19 * specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
46 static redisReply *createReplyObject(int type);
47 static void *createStringObject(const redisReadTask *task, char *str, size_t len);
48 static void *createArrayObject(const redisReadTask *task, int elements);
49 static void *createIntegerObject(const redisReadTask *task, long long value);
50 static void *createNilObject(const redisReadTask *task);
52 /* Default set of functions to build the reply. Keep in mind that such a
53 * function returning NULL is interpreted as OOM. */
54 static redisReplyObjectFunctions defaultFunctions = {
62 /* Create a reply object */
63 static redisReply *createReplyObject(int type) {
64 redisReply *r = calloc(1,sizeof(*r));
73 /* Free a reply object */
74 void freeReplyObject(void *reply) {
75 redisReply *r = reply;
82 case REDIS_REPLY_INTEGER:
83 break; /* Nothing to free */
84 case REDIS_REPLY_ARRAY:
85 if (r->element != NULL) {
86 for (j = 0; j < r->elements; j++)
87 if (r->element[j] != NULL)
88 freeReplyObject(r->element[j]);
92 case REDIS_REPLY_ERROR:
93 case REDIS_REPLY_STATUS:
94 case REDIS_REPLY_STRING:
102 static void *createStringObject(const redisReadTask *task, char *str, size_t len) {
103 redisReply *r, *parent;
106 r = createReplyObject(task->type);
116 assert(task->type == REDIS_REPLY_ERROR ||
117 task->type == REDIS_REPLY_STATUS ||
118 task->type == REDIS_REPLY_STRING);
120 /* Copy string value */
127 parent = task->parent->obj;
128 assert(parent->type == REDIS_REPLY_ARRAY);
129 parent->element[task->idx] = r;
134 static void *createArrayObject(const redisReadTask *task, int elements) {
135 redisReply *r, *parent;
137 r = createReplyObject(REDIS_REPLY_ARRAY);
142 r->element = calloc(elements,sizeof(redisReply*));
143 if (r->element == NULL) {
149 r->elements = elements;
152 parent = task->parent->obj;
153 assert(parent->type == REDIS_REPLY_ARRAY);
154 parent->element[task->idx] = r;
159 static void *createIntegerObject(const redisReadTask *task, long long value) {
160 redisReply *r, *parent;
162 r = createReplyObject(REDIS_REPLY_INTEGER);
169 parent = task->parent->obj;
170 assert(parent->type == REDIS_REPLY_ARRAY);
171 parent->element[task->idx] = r;
176 static void *createNilObject(const redisReadTask *task) {
177 redisReply *r, *parent;
179 r = createReplyObject(REDIS_REPLY_NIL);
184 parent = task->parent->obj;
185 assert(parent->type == REDIS_REPLY_ARRAY);
186 parent->element[task->idx] = r;
191 /* Return the number of digits of 'v' when converted to string in radix 10.
192 * Implementation borrowed from link in redis/src/util.c:string2ll(). */
193 static uint32_t countDigits(uint64_t v) {
196 if (v < 10) return result;
197 if (v < 100) return result + 1;
198 if (v < 1000) return result + 2;
199 if (v < 10000) return result + 3;
205 /* Helper that calculates the bulk length given a certain string length. */
206 static size_t bulklen(size_t len) {
207 return 1+countDigits(len)+2+len+2;
210 int redisvFormatCommand(char **target, const char *format, va_list ap) {
211 const char *c = format;
212 char *cmd = NULL; /* final command */
213 int pos; /* position in final command */
214 sds curarg, newarg; /* current argument */
215 int touched = 0; /* was the current argument touched? */
216 char **curargv = NULL, **newargv = NULL;
219 int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */
222 /* Abort if there is not target to set */
226 /* Build the command string accordingly to protocol */
232 if (*c != '%' || c[1] == '\0') {
235 newargv = realloc(curargv,sizeof(char*)*(argc+1));
236 if (newargv == NULL) goto memory_err;
238 curargv[argc++] = curarg;
239 totlen += bulklen(sdslen(curarg));
241 /* curarg is put in argv so it can be overwritten. */
243 if (curarg == NULL) goto memory_err;
247 newarg = sdscatlen(curarg,c,1);
248 if (newarg == NULL) goto memory_err;
256 /* Set newarg so it can be checked even if it is not touched. */
261 arg = va_arg(ap,char*);
264 newarg = sdscatlen(curarg,arg,size);
267 arg = va_arg(ap,char*);
268 size = va_arg(ap,size_t);
270 newarg = sdscatlen(curarg,arg,size);
273 newarg = sdscat(curarg,"%");
276 /* Try to detect printf format */
278 static const char intfmts[] = "diouxX";
279 static const char flags[] = "#0-+ ";
281 const char *_p = c+1;
286 while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++;
289 while (*_p != '\0' && isdigit(*_p)) _p++;
294 while (*_p != '\0' && isdigit(*_p)) _p++;
297 /* Copy va_list before consuming with va_arg */
300 /* Integer conversion (without modifiers) */
301 if (strchr(intfmts,*_p) != NULL) {
306 /* Double conversion (without modifiers) */
307 if (strchr("eEfFgGaA",*_p) != NULL) {
313 if (_p[0] == 'h' && _p[1] == 'h') {
315 if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
316 va_arg(ap,int); /* char gets promoted to int */
325 if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
326 va_arg(ap,int); /* short gets promoted to int */
332 /* Size: long long */
333 if (_p[0] == 'l' && _p[1] == 'l') {
335 if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
336 va_arg(ap,long long);
345 if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
358 if (_l < sizeof(_format)-2) {
359 memcpy(_format,c,_l);
361 newarg = sdscatvprintf(curarg,_format,_cpy);
363 /* Update current position (note: outer blocks
364 * increment c twice so compensate here) */
373 if (newarg == NULL) goto memory_err;
382 /* Add the last argument if needed */
384 newargv = realloc(curargv,sizeof(char*)*(argc+1));
385 if (newargv == NULL) goto memory_err;
387 curargv[argc++] = curarg;
388 totlen += bulklen(sdslen(curarg));
393 /* Clear curarg because it was put in curargv or was free'd. */
396 /* Add bytes needed to hold multi bulk count */
397 totlen += 1+countDigits(argc)+2;
399 /* Build the command at protocol level */
400 cmd = malloc(totlen+1);
401 if (cmd == NULL) goto memory_err;
403 pos = sprintf(cmd,"*%d\r\n",argc);
404 for (j = 0; j < argc; j++) {
405 pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
406 memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
407 pos += sdslen(curargv[j]);
412 assert(pos == totlen);
430 sdsfree(curargv[argc]);
436 /* No need to check cmd since it is the last statement that can fail,
437 * but do it anyway to be as defensive as possible. */
444 /* Format a command according to the Redis protocol. This function
445 * takes a format similar to printf:
447 * %s represents a C null terminated string you want to interpolate
448 * %b represents a binary safe string
450 * When using %b you need to provide both the pointer to the string
451 * and the length in bytes as a size_t. Examples:
453 * len = redisFormatCommand(target, "GET %s", mykey);
454 * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen);
456 int redisFormatCommand(char **target, const char *format, ...) {
460 len = redisvFormatCommand(target,format,ap);
463 /* The API says "-1" means bad result, but we now also return "-2" in some
464 * cases. Force the return value to always be -1. */
471 /* Format a command according to the Redis protocol using an sds string and
472 * sdscatfmt for the processing of arguments. This function takes the
473 * number of arguments, an array with arguments and an array with their
474 * lengths. If the latter is set to NULL, strlen will be used to compute the
477 int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
478 const size_t *argvlen)
481 unsigned long long totlen;
485 /* Abort on a NULL target */
489 /* Calculate our total size */
490 totlen = 1+countDigits(argc)+2;
491 for (j = 0; j < argc; j++) {
492 len = argvlen ? argvlen[j] : strlen(argv[j]);
493 totlen += bulklen(len);
496 /* Use an SDS string for command construction */
501 /* We already know how much storage we need */
502 cmd = sdsMakeRoomFor(cmd, totlen);
506 /* Construct command */
507 cmd = sdscatfmt(cmd, "*%i\r\n", argc);
508 for (j=0; j < argc; j++) {
509 len = argvlen ? argvlen[j] : strlen(argv[j]);
510 cmd = sdscatfmt(cmd, "$%T\r\n", len);
511 cmd = sdscatlen(cmd, argv[j], len);
512 cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
515 assert(sdslen(cmd)==totlen);
521 void redisFreeSdsCommand(sds cmd) {
525 /* Format a command according to the Redis protocol. This function takes the
526 * number of arguments, an array with arguments and an array with their
527 * lengths. If the latter is set to NULL, strlen will be used to compute the
530 int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
531 char *cmd = NULL; /* final command */
532 int pos; /* position in final command */
536 /* Abort on a NULL target */
540 /* Calculate number of bytes needed for the command */
541 totlen = 1+countDigits(argc)+2;
542 for (j = 0; j < argc; j++) {
543 len = argvlen ? argvlen[j] : strlen(argv[j]);
544 totlen += bulklen(len);
547 /* Build the command at protocol level */
548 cmd = malloc(totlen+1);
552 pos = sprintf(cmd,"*%d\r\n",argc);
553 for (j = 0; j < argc; j++) {
554 len = argvlen ? argvlen[j] : strlen(argv[j]);
555 pos += sprintf(cmd+pos,"$%zu\r\n",len);
556 memcpy(cmd+pos,argv[j],len);
561 assert(pos == totlen);
568 void redisFreeCommand(char *cmd) {
572 void __redisSetError(redisContext *c, int type, const char *str) {
578 len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1);
579 memcpy(c->errstr,str,len);
580 c->errstr[len] = '\0';
582 /* Only REDIS_ERR_IO may lack a description! */
583 assert(type == REDIS_ERR_IO);
584 __redis_strerror_r(errno, c->errstr, sizeof(c->errstr));
588 redisReader *redisReaderCreate(void) {
589 return redisReaderCreateWithFunctions(&defaultFunctions);
592 static redisContext *redisContextInit(void) {
595 c = calloc(1,sizeof(redisContext));
601 c->obuf = sdsempty();
602 c->reader = redisReaderCreate();
604 c->tcp.source_addr = NULL;
605 c->unix_sock.path = NULL;
608 if (c->obuf == NULL || c->reader == NULL) {
616 void redisFree(redisContext *c) {
623 if (c->reader != NULL)
624 redisReaderFree(c->reader);
627 if (c->tcp.source_addr)
628 free(c->tcp.source_addr);
629 if (c->unix_sock.path)
630 free(c->unix_sock.path);
636 int redisFreeKeepFd(redisContext *c) {
643 int redisReconnect(redisContext *c) {
645 memset(c->errstr, '\0', strlen(c->errstr));
652 redisReaderFree(c->reader);
654 c->obuf = sdsempty();
655 c->reader = redisReaderCreate();
657 if (c->connection_type == REDIS_CONN_TCP) {
658 return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port,
659 c->timeout, c->tcp.source_addr);
660 } else if (c->connection_type == REDIS_CONN_UNIX) {
661 return redisContextConnectUnix(c, c->unix_sock.path, c->timeout);
663 /* Something bad happened here and shouldn't have. There isn't
664 enough information in the context to reconnect. */
665 __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect");
671 /* Connect to a Redis instance. On error the field error in the returned
672 * context will be set to the return value of the error function.
673 * When no set of reply functions is given, the default set will be used. */
674 redisContext *redisConnect(const char *ip, int port) {
677 c = redisContextInit();
681 c->flags |= REDIS_BLOCK;
682 redisContextConnectTcp(c,ip,port,NULL);
686 redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {
689 c = redisContextInit();
693 c->flags |= REDIS_BLOCK;
694 redisContextConnectTcp(c,ip,port,&tv);
698 redisContext *redisConnectNonBlock(const char *ip, int port) {
701 c = redisContextInit();
705 c->flags &= ~REDIS_BLOCK;
706 redisContextConnectTcp(c,ip,port,NULL);
710 redisContext *redisConnectBindNonBlock(const char *ip, int port,
711 const char *source_addr) {
712 redisContext *c = redisContextInit();
713 c->flags &= ~REDIS_BLOCK;
714 redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
718 redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
719 const char *source_addr) {
720 redisContext *c = redisContextInit();
721 c->flags &= ~REDIS_BLOCK;
722 c->flags |= REDIS_REUSEADDR;
723 redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
727 redisContext *redisConnectUnix(const char *path) {
730 c = redisContextInit();
734 c->flags |= REDIS_BLOCK;
735 redisContextConnectUnix(c,path,NULL);
739 redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) {
742 c = redisContextInit();
746 c->flags |= REDIS_BLOCK;
747 redisContextConnectUnix(c,path,&tv);
751 redisContext *redisConnectUnixNonBlock(const char *path) {
754 c = redisContextInit();
758 c->flags &= ~REDIS_BLOCK;
759 redisContextConnectUnix(c,path,NULL);
763 redisContext *redisConnectFd(int fd) {
766 c = redisContextInit();
771 c->flags |= REDIS_BLOCK | REDIS_CONNECTED;
775 /* Set read/write timeout on a blocking socket. */
776 int redisSetTimeout(redisContext *c, const struct timeval tv) {
777 if (c->flags & REDIS_BLOCK)
778 return redisContextSetTimeout(c,tv);
782 /* Enable connection KeepAlive. */
783 int redisEnableKeepAlive(redisContext *c) {
784 if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK)
789 /* Use this function to handle a read event on the descriptor. It will try
790 * and read some bytes from the socket and feed them to the reply parser.
792 * After this function is called, you may use redisContextReadReply to
793 * see if there is a reply available. */
794 int redisBufferRead(redisContext *c) {
798 /* Return early when the context has seen an error. */
802 nread = read(c->fd,buf,sizeof(buf));
804 if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
805 /* Try again later */
807 __redisSetError(c,REDIS_ERR_IO,NULL);
810 } else if (nread == 0) {
811 __redisSetError(c,REDIS_ERR_EOF,"Server closed the connection");
814 if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) {
815 __redisSetError(c,c->reader->err,c->reader->errstr);
822 /* Write the output buffer to the socket.
824 * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
825 * succesfully written to the socket. When the buffer is empty after the
826 * write operation, "done" is set to 1 (if given).
828 * Returns REDIS_ERR if an error occured trying to write and sets
829 * c->errstr to hold the appropriate error string.
831 int redisBufferWrite(redisContext *c, int *done) {
834 /* Return early when the context has seen an error. */
838 if (sdslen(c->obuf) > 0) {
839 nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
840 if (nwritten == -1) {
841 if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
842 /* Try again later */
844 __redisSetError(c,REDIS_ERR_IO,NULL);
847 } else if (nwritten > 0) {
848 if (nwritten == (signed)sdslen(c->obuf)) {
850 c->obuf = sdsempty();
852 sdsrange(c->obuf,nwritten,-1);
856 if (done != NULL) *done = (sdslen(c->obuf) == 0);
860 /* Internal helper function to try and get a reply from the reader,
861 * or set an error in the context otherwise. */
862 int redisGetReplyFromReader(redisContext *c, void **reply) {
863 if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) {
864 __redisSetError(c,c->reader->err,c->reader->errstr);
870 int redisGetReply(redisContext *c, void **reply) {
874 /* Try to read pending replies */
875 if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
878 /* For the blocking context, flush output buffer and read reply */
879 if (aux == NULL && c->flags & REDIS_BLOCK) {
880 /* Write until done */
882 if (redisBufferWrite(c,&wdone) == REDIS_ERR)
886 /* Read until there is a reply */
888 if (redisBufferRead(c) == REDIS_ERR)
890 if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
892 } while (aux == NULL);
895 /* Set reply object */
896 if (reply != NULL) *reply = aux;
901 /* Helper function for the redisAppendCommand* family of functions.
903 * Write a formatted command to the output buffer. When this family
904 * is used, you need to call redisGetReply yourself to retrieve
905 * the reply (or replies in pub/sub).
907 int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) {
910 newbuf = sdscatlen(c->obuf,cmd,len);
911 if (newbuf == NULL) {
912 __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
920 int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) {
922 if (__redisAppendCommand(c, cmd, len) != REDIS_OK) {
929 int redisvAppendCommand(redisContext *c, const char *format, va_list ap) {
933 len = redisvFormatCommand(&cmd,format,ap);
935 __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
937 } else if (len == -2) {
938 __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string");
942 if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
951 int redisAppendCommand(redisContext *c, const char *format, ...) {
956 ret = redisvAppendCommand(c,format,ap);
961 int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
965 len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
967 __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
971 if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
980 /* Helper function for the redisCommand* family of functions.
982 * Write a formatted command to the output buffer. If the given context is
983 * blocking, immediately read the reply into the "reply" pointer. When the
984 * context is non-blocking, the "reply" pointer will not be used and the
985 * command is simply appended to the write buffer.
987 * Returns the reply when a reply was succesfully retrieved. Returns NULL
988 * otherwise. When NULL is returned in a blocking context, the error field
989 * in the context will be set.
991 static void *__redisBlockForReply(redisContext *c) {
994 if (c->flags & REDIS_BLOCK) {
995 if (redisGetReply(c,&reply) != REDIS_OK)
1002 void *redisvCommand(redisContext *c, const char *format, va_list ap) {
1003 if (redisvAppendCommand(c,format,ap) != REDIS_OK)
1005 return __redisBlockForReply(c);
1008 void *redisCommand(redisContext *c, const char *format, ...) {
1011 va_start(ap,format);
1012 reply = redisvCommand(c,format,ap);
1017 void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
1018 if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK)
1020 return __redisBlockForReply(c);