summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2010-10-18 15:49:52 +0200
committerPieter Noordhuis <pcnoordhuis@gmail.com>2010-10-18 15:49:52 +0200
commite332a32b3514d8a5603610e9e9febd5f6ddaae3c (patch)
treeecc484828ea5fc7ca996cad837bc70b600f4e734
parenta68cb9686e4431951897e30d87b42ebb6a8faae5 (diff)
Change redisWriteBuffer to return OK on an empty buffer
-rw-r--r--hiredis.c46
-rw-r--r--test.c22
2 files changed, 50 insertions, 18 deletions
diff --git a/hiredis.c b/hiredis.c
index 45a932a..585dfe8 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -714,25 +714,35 @@ int redisProcessCallbacks(redisContext *c) {
return REDIS_OK;
}
-/* Use this function to try and write the entire output buffer to the
- * descriptor. Returns 1 when the entire buffer was written, 0 otherwise. */
+/* Write the output buffer to the socket.
+ *
+ * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
+ * succesfully written to the socket. When the buffer is empty after the
+ * write operation, "wdone" is set to 1 (if given).
+ *
+ * Returns REDIS_ERR if an error occured trying to write and sets
+ * c->error to hold the appropriate error string.
+ */
int redisBufferWrite(redisContext *c, int *done) {
- int nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
- if (nwritten == -1) {
- if (errno == EAGAIN) {
- /* Try again later */
- } else {
- /* Set error in context */
- c->error = sdscatprintf(sdsempty(),
- "write: %s", strerror(errno));
- return REDIS_ERR;
- }
- } else if (nwritten > 0) {
- if (nwritten == (signed)sdslen(c->obuf)) {
- sdsfree(c->obuf);
- c->obuf = sdsempty();
- } else {
- c->obuf = sdsrange(c->obuf,nwritten,-1);
+ int nwritten;
+ if (sdslen(c->obuf) > 0) {
+ nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
+ if (nwritten == -1) {
+ if (errno == EAGAIN) {
+ /* Try again later */
+ } else {
+ /* Set error in context */
+ c->error = sdscatprintf(sdsempty(),
+ "write: %s", strerror(errno));
+ return REDIS_ERR;
+ }
+ } else if (nwritten > 0) {
+ if (nwritten == (signed)sdslen(c->obuf)) {
+ sdsfree(c->obuf);
+ c->obuf = sdsempty();
+ } else {
+ c->obuf = sdsrange(c->obuf,nwritten,-1);
+ }
}
}
if (done != NULL) *done = (sdslen(c->obuf) == 0);
diff --git a/test.c b/test.c
index 09bc32d..2800616 100644
--- a/test.c
+++ b/test.c
@@ -4,6 +4,7 @@
#include <strings.h>
#include <sys/time.h>
#include <assert.h>
+#include <unistd.h>
#include "hiredis.h"
@@ -203,6 +204,7 @@ static void __test_callback(redisContext *c, const void *privdata) {
static void test_nonblocking_connection() {
redisContext *c;
+ int wdone = 0;
__test_callback_flags = 0;
test("Calls command callback when command is issued: ");
@@ -227,6 +229,26 @@ static void test_nonblocking_connection() {
redisSetFreeCallback(c,__test_callback,(const void*)4);
redisFree(c);
test_cond(__test_callback_flags == ((2 << 8) | 4));
+
+ test("redisBufferWrite against empty write buffer: ");
+ c = redisConnectNonBlock("127.0.0.1", 6379, NULL);
+ test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
+ redisFree(c);
+
+ test("redisBufferWrite against not yet connected fd: ");
+ c = redisConnectNonBlock("127.0.0.1", 6379, NULL);
+ redisCommand(c,"PING");
+ test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
+ strncmp(c->error,"write:",6) == 0);
+ redisFree(c);
+
+ test("redisBufferWrite against closed fd: ");
+ c = redisConnectNonBlock("127.0.0.1", 6379, NULL);
+ redisCommand(c,"PING");
+ redisDisconnect(c);
+ test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
+ strncmp(c->error,"write:",6) == 0);
+ redisFree(c);
}
int main(void) {