c->reqtype = 0;
c->argc = 0;
c->argv = NULL;
+ c->cmd = NULL;
c->multibulklen = 0;
c->bulklen = -1;
c->sentlen = 0;
for (j = 0; j < c->argc; j++)
decrRefCount(c->argv[j]);
c->argc = 0;
+ c->cmd = NULL;
}
void freeClient(redisClient *c) {
}
}
if (totwritten > 0) c->lastinteraction = time(NULL);
- if (listLength(c->reply) == 0) {
+ if (c->bufpos == 0 && listLength(c->reply) == 0) {
c->sentlen = 0;
aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE);
void processInputBuffer(redisClient *c) {
/* Keep processing while there is something in the input buffer */
while(sdslen(c->querybuf)) {
+ /* Immediately abort if the client is in the middle of something. */
+ if (c->flags & REDIS_BLOCKED) return;
+
/* REDIS_CLOSE_AFTER_REPLY closes the connection once the reply is
* written to the client. Make sure to not let the reply grow after
* this flag has been set (i.e. don't process more commands). */
}
}
+/* Rewrite the command vector of the client. All the new objects ref count
+ * is incremented. The old command vector is freed, and the old objects
+ * ref count is decremented. */
void rewriteClientCommandVector(redisClient *c, int argc, ...) {
va_list ap;
int j;
/* Replace argv and argc with our new versions. */
c->argv = argv;
c->argc = argc;
+ c->cmd = lookupCommand(c->argv[0]->ptr);
+ redisAssert(c->cmd != NULL);
va_end(ap);
}
+
+/* Rewrite a single item in the command vector.
+ * The new val ref count is incremented, and the old decremented. */
+void rewriteClientCommandArgument(redisClient *c, int i, robj *newval) {
+ robj *oldval;
+
+ redisAssert(i < c->argc);
+ oldval = c->argv[i];
+ c->argv[i] = newval;
+ incrRefCount(newval);
+ decrRefCount(oldval);
+
+ /* If this is the command name make sure to fix c->cmd. */
+ if (i == 0) {
+ c->cmd = lookupCommand(c->argv[0]->ptr);
+ redisAssert(c->cmd != NULL);
+ }
+}