From 62c8054dbe5d590a7f2d36e4e5176996215e9aa7 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Sun, 19 Sep 2010 19:01:31 +0200 Subject: [PATCH] Clean up when there is an I/O error --- hiredis.c | 12 +++++++++--- test.c | 23 +++++++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/hiredis.c b/hiredis.c index 96a35f3..fcda779 100644 --- a/hiredis.c +++ b/hiredis.c @@ -73,7 +73,7 @@ redisReply *redisConnect(int *fd, const char *ip, int port) { /* Create a reply object */ static redisReply *createReplyObject(int type, sds reply) { - redisReply *r = malloc(sizeof(*r)); + redisReply *r = calloc(sizeof(*r),1); if (!r) redisOOM(); r->type = type; @@ -94,7 +94,8 @@ void freeReplyObject(redisReply *r) { free(r->element); break; default: - sdsfree(r->reply); + if (r->reply != NULL) + sdsfree(r->reply); break; } free(r); @@ -303,8 +304,13 @@ static redisReply *redisReadReply(int fd) { } /* read from socket into buffer */ - if ((bytes = read(fd,r.buf+r.avail,READ_BUFFER_SIZE)) <= 0) + if ((bytes = read(fd,r.buf+r.avail,READ_BUFFER_SIZE)) <= 0) { + /* rlist[0] is the "root" reply object */ + freeReplyObject(r.rlist[0]); + free(r.buf); + free(r.rlist); return redisIOError(); + } r.avail += bytes; r.buf[r.avail] = '\0'; diff --git a/test.c b/test.c index cec8ada..2824159 100644 --- a/test.c +++ b/test.c @@ -15,20 +15,31 @@ long long usec(void) { return (((long long)tv.tv_sec)*1000000)+tv.tv_usec; } +void connect(int *fd) { + redisReply *reply = redisConnect(fd, "127.0.0.1", 6379); + if (reply != NULL) { + printf("Connection error: %s", reply->reply); + exit(1); + } +} + int main(void) { int fd; int i, fails = 0; long long t1, t2; redisReply *reply; + connect(&fd); - reply = redisConnect(&fd, "127.0.0.1", 6379); - if (reply != NULL) { - printf("Connection error: %s", reply->reply); - exit(1); - } + /* test 0 */ + printf("#0 Returns I/O error when the connection is lost: "); + reply = redisCommand(fd,"QUIT"); + test_cond(reply->type == REDIS_REPLY_ERROR && + strcasecmp(reply->reply,"i/o error") == 0); + freeReplyObject(reply); + connect(&fd); /* reconnect */ /* test 1 */ - printf("\n#1 Is able to deliver commands: "); + printf("#1 Is able to deliver commands: "); reply = redisCommand(fd,"PING"); test_cond(reply->type == REDIS_REPLY_STRING && strcasecmp(reply->reply,"pong") == 0)