summaryrefslogtreecommitdiff
path: root/src/networking.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/networking.c')
-rw-r--r--src/networking.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/networking.c b/src/networking.c
index 7319bd908..a4eee4643 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -14,14 +14,20 @@ redisClient *createClient(int fd) {
redisClient *c = zmalloc(sizeof(redisClient));
c->bufpos = 0;
- anetNonBlock(NULL,fd);
- anetTcpNoDelay(NULL,fd);
- if (aeCreateFileEvent(server.el,fd,AE_READABLE,
- readQueryFromClient, c) == AE_ERR)
- {
- close(fd);
- zfree(c);
- return NULL;
+ /* passing -1 as fd it is possible to create a non connected client.
+ * This is useful since all the Redis commands needs to be executed
+ * in the context of a client. When commands are executed in other
+ * contexts (for instance a Lua script) we need a non connected client. */
+ if (fd != -1) {
+ anetNonBlock(NULL,fd);
+ anetTcpNoDelay(NULL,fd);
+ if (aeCreateFileEvent(server.el,fd,AE_READABLE,
+ readQueryFromClient, c) == AE_ERR)
+ {
+ close(fd);
+ zfree(c);
+ return NULL;
+ }
}
selectDb(c,0);
@@ -52,7 +58,7 @@ redisClient *createClient(int fd) {
c->pubsub_patterns = listCreate();
listSetFreeMethod(c->pubsub_patterns,decrRefCount);
listSetMatchMethod(c->pubsub_patterns,listMatchObjects);
- listAddNodeTail(server.clients,c);
+ if (fd != -1) listAddNodeTail(server.clients,c);
initClientMultiState(c);
return c;
}
@@ -60,6 +66,7 @@ redisClient *createClient(int fd) {
/* Set the event loop to listen for write events on the client's socket.
* Typically gets called every time a reply is built. */
int _installWriteEvent(redisClient *c) {
+ if (c->flags & REDIS_LUA_CLIENT) return REDIS_OK;
if (c->fd <= 0) return REDIS_ERR;
if (c->bufpos == 0 && listLength(c->reply) == 0 &&
(c->replstate == REDIS_REPL_NONE ||
@@ -240,10 +247,17 @@ void addReplyError(redisClient *c, char *err) {
}
void addReplyErrorFormat(redisClient *c, const char *fmt, ...) {
+ size_t l, j;
va_list ap;
va_start(ap,fmt);
sds s = sdscatvprintf(sdsempty(),fmt,ap);
va_end(ap);
+ /* Make sure there are no newlines in the string, otherwise invalid protocol
+ * is emitted. */
+ l = sdslen(s);
+ for (j = 0; j < l; j++) {
+ if (s[j] == '\r' || s[j] == '\n') s[j] = ' ';
+ }
_addReplyError(c,s,sdslen(s));
sdsfree(s);
}