summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2010-09-19 19:01:31 +0200
committerPieter Noordhuis <pcnoordhuis@gmail.com>2010-09-19 19:01:31 +0200
commit62c8054dbe5d590a7f2d36e4e5176996215e9aa7 (patch)
tree2a194ad7bf812dbb300f3084614ae6a4bc7e0fef
parent457cdbf7c5f98c7ac5b4d727a1bad0c041f7cc66 (diff)
Clean up when there is an I/O error
-rw-r--r--hiredis.c12
-rw-r--r--test.c23
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)