If this function gets called we already read a whole * command, arguments are in the client argv/argc fields. * processCommand() execute the command or prepare the * server for a bulk read from the client. * * If C_OK is returned the client is still alive and valid and * other operations can be performed by the caller. Otherwise * if C_ERR is returned the client was destroyed (i.e. after QU
| 4787 | * other operations can be performed by the caller. Otherwise |
| 4788 | * if C_ERR is returned the client was destroyed (i.e. after QUIT). */ |
| 4789 | int processCommand(client *c, int callFlags) { |
| 4790 | AssertCorrectThread(c); |
| 4791 | serverAssert((callFlags & CMD_CALL_ASYNC) || GlobalLocksAcquired()); |
| 4792 | if (!g_pserver->lua_timedout) { |
| 4793 | /* Both EXEC and EVAL call call() directly so there should be |
| 4794 | * no way in_exec or in_eval or propagate_in_transaction is 1. |
| 4795 | * That is unless lua_timedout, in which case client may run |
| 4796 | * some commands. Also possible that some other thread set |
| 4797 | * propagate_in_transaction if this is an async command. */ |
| 4798 | serverAssert(!serverTL->propagate_in_transaction); |
| 4799 | serverAssert(!serverTL->in_exec); |
| 4800 | serverAssert(!serverTL->in_eval); |
| 4801 | } |
| 4802 | |
| 4803 | if (moduleHasCommandFilters()) |
| 4804 | { |
| 4805 | moduleCallCommandFilters(c); |
| 4806 | } |
| 4807 | |
| 4808 | /* The QUIT command is handled separately. Normal command procs will |
| 4809 | * go through checking for replication and QUIT will cause trouble |
| 4810 | * when FORCE_REPLICATION is enabled and would be implemented in |
| 4811 | * a regular command proc. */ |
| 4812 | if (!strcasecmp((const char*)ptrFromObj(c->argv[0]),"quit")) { |
| 4813 | addReply(c,shared.ok); |
| 4814 | c->flags |= CLIENT_CLOSE_AFTER_REPLY; |
| 4815 | return C_ERR; |
| 4816 | } |
| 4817 | |
| 4818 | /* Now lookup the command and check ASAP about trivial error conditions |
| 4819 | * such as wrong arity, bad command name and so forth. */ |
| 4820 | c->cmd = c->lastcmd = lookupCommand((sds)ptrFromObj(c->argv[0])); |
| 4821 | if (!c->cmd) { |
| 4822 | sds args = sdsempty(); |
| 4823 | int i; |
| 4824 | for (i=1; i < c->argc && sdslen(args) < 128; i++) |
| 4825 | args = sdscatprintf(args, "`%.*s`, ", 128-(int)sdslen(args), (char*)ptrFromObj(c->argv[i])); |
| 4826 | rejectCommandFormat(c,"unknown command `%s`, with args beginning with: %s", |
| 4827 | (char*)ptrFromObj(c->argv[0]), args); |
| 4828 | sdsfree(args); |
| 4829 | return C_OK; |
| 4830 | } else if ((c->cmd->arity > 0 && c->cmd->arity != c->argc) || |
| 4831 | (c->argc < -c->cmd->arity)) { |
| 4832 | rejectCommandFormat(c,"wrong number of arguments for '%s' command", |
| 4833 | c->cmd->name); |
| 4834 | return C_OK; |
| 4835 | } |
| 4836 | |
| 4837 | int is_read_command = (c->cmd->flags & CMD_READONLY) || |
| 4838 | (c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_READONLY)); |
| 4839 | int is_write_command = (c->cmd->flags & CMD_WRITE) || |
| 4840 | (c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_WRITE)); |
| 4841 | int is_denyoom_command = (c->cmd->flags & CMD_DENYOOM) || |
| 4842 | (c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_DENYOOM)); |
| 4843 | int is_denystale_command = !(c->cmd->flags & CMD_STALE) || |
| 4844 | (c->cmd->proc == execCommand && (c->mstate.cmd_inv_flags & CMD_STALE)); |
| 4845 | int is_denyloading_command = !(c->cmd->flags & CMD_LOADING) || |
| 4846 | (c->cmd->proc == execCommand && (c->mstate.cmd_inv_flags & CMD_LOADING)); |
no test coverage detected