mirror of
https://github.com/fluencelabs/redis
synced 2025-06-22 13:31:32 +00:00
Merge branch '2.2' of github.com:antirez/redis into 2.2
This commit is contained in:
@ -65,6 +65,7 @@ static struct config {
|
|||||||
char *historyfile;
|
char *historyfile;
|
||||||
int raw_output; /* output mode per command */
|
int raw_output; /* output mode per command */
|
||||||
sds mb_delim;
|
sds mb_delim;
|
||||||
|
char prompt[32];
|
||||||
} config;
|
} config;
|
||||||
|
|
||||||
static void usage();
|
static void usage();
|
||||||
@ -85,6 +86,13 @@ static long long mstime(void) {
|
|||||||
return mst;
|
return mst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cliRefreshPrompt(void) {
|
||||||
|
if (config.dbnum == 0)
|
||||||
|
snprintf(config.prompt,sizeof(config.prompt),"redis> ");
|
||||||
|
else
|
||||||
|
snprintf(config.prompt,sizeof(config.prompt),"redis:%d> ",config.dbnum);
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Help functions
|
* Help functions
|
||||||
*--------------------------------------------------------------------------- */
|
*--------------------------------------------------------------------------- */
|
||||||
@ -264,11 +272,9 @@ static int cliAuth() {
|
|||||||
/* Send SELECT dbnum to the server */
|
/* Send SELECT dbnum to the server */
|
||||||
static int cliSelect() {
|
static int cliSelect() {
|
||||||
redisReply *reply;
|
redisReply *reply;
|
||||||
char dbnum[16];
|
|
||||||
if (config.dbnum == 0) return REDIS_OK;
|
if (config.dbnum == 0) return REDIS_OK;
|
||||||
|
|
||||||
snprintf(dbnum,sizeof(dbnum),"%d",config.dbnum);
|
reply = redisCommand(context,"SELECT %d",config.dbnum);
|
||||||
reply = redisCommand(context,"SELECT %s",dbnum);
|
|
||||||
if (reply != NULL) {
|
if (reply != NULL) {
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
@ -489,9 +495,19 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cliReadReply(output_raw) != REDIS_OK)
|
if (cliReadReply(output_raw) != REDIS_OK) {
|
||||||
|
free(argvlen);
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
} else {
|
||||||
|
/* Store database number when SELECT was successfully executed. */
|
||||||
|
if (!strcasecmp(command,"select") && argc == 2) {
|
||||||
|
config.dbnum = atoi(argv[1]);
|
||||||
|
cliRefreshPrompt();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(argvlen);
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,7 +632,8 @@ static void repl() {
|
|||||||
config.interactive = 1;
|
config.interactive = 1;
|
||||||
linenoiseSetCompletionCallback(completionCallback);
|
linenoiseSetCompletionCallback(completionCallback);
|
||||||
|
|
||||||
while((line = linenoise(context ? "redis> " : "not connected> ")) != NULL) {
|
cliRefreshPrompt();
|
||||||
|
while((line = linenoise(context ? config.prompt : "not connected> ")) != NULL) {
|
||||||
if (line[0] != '\0') {
|
if (line[0] != '\0') {
|
||||||
argv = sdssplitargs(line,&argc);
|
argv = sdssplitargs(line,&argc);
|
||||||
linenoiseHistoryAdd(line);
|
linenoiseHistoryAdd(line);
|
||||||
|
38
src/redis.c
38
src/redis.c
@ -837,7 +837,7 @@ void initServer() {
|
|||||||
|
|
||||||
signal(SIGHUP, SIG_IGN);
|
signal(SIGHUP, SIG_IGN);
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
setupSigSegvAction();
|
setupSignalHandlers();
|
||||||
|
|
||||||
if (server.syslog_enabled) {
|
if (server.syslog_enabled) {
|
||||||
openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,
|
openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,
|
||||||
@ -1574,10 +1574,8 @@ int main(int argc, char **argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= Backtrace support ========================= */
|
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE
|
||||||
void *getMcontextEip(ucontext_t *uc) {
|
static void *getMcontextEip(ucontext_t *uc) {
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
return (void*) uc->uc_mcontext.mc_eip;
|
return (void*) uc->uc_mcontext.mc_eip;
|
||||||
#elif defined(__dietlibc__)
|
#elif defined(__dietlibc__)
|
||||||
@ -1605,7 +1603,7 @@ void *getMcontextEip(ucontext_t *uc) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void segvHandler(int sig, siginfo_t *info, void *secret) {
|
static void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
||||||
void *trace[100];
|
void *trace[100];
|
||||||
char **messages = NULL;
|
char **messages = NULL;
|
||||||
int i, trace_size = 0;
|
int i, trace_size = 0;
|
||||||
@ -1644,37 +1642,35 @@ void segvHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
sigaction (sig, &act, NULL);
|
sigaction (sig, &act, NULL);
|
||||||
kill(getpid(),sig);
|
kill(getpid(),sig);
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_BACKTRACE */
|
||||||
|
|
||||||
void sigtermHandler(int sig) {
|
static void sigtermHandler(int sig) {
|
||||||
REDIS_NOTUSED(sig);
|
REDIS_NOTUSED(sig);
|
||||||
|
|
||||||
redisLog(REDIS_WARNING,"SIGTERM received, scheduling shutting down...");
|
redisLog(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
|
||||||
server.shutdown_asap = 1;
|
server.shutdown_asap = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSigSegvAction(void) {
|
void setupSignalHandlers(void) {
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
|
/* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used.
|
||||||
|
* Otherwise, sa_handler is used. */
|
||||||
|
sigemptyset(&act.sa_mask);
|
||||||
|
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
|
||||||
|
act.sa_handler = sigtermHandler;
|
||||||
|
sigaction(SIGTERM, &act, NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_BACKTRACE
|
||||||
sigemptyset(&act.sa_mask);
|
sigemptyset(&act.sa_mask);
|
||||||
/* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction
|
|
||||||
* is used. Otherwise, sa_handler is used */
|
|
||||||
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
|
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
|
||||||
act.sa_sigaction = segvHandler;
|
act.sa_sigaction = sigsegvHandler;
|
||||||
sigaction(SIGSEGV, &act, NULL);
|
sigaction(SIGSEGV, &act, NULL);
|
||||||
sigaction(SIGBUS, &act, NULL);
|
sigaction(SIGBUS, &act, NULL);
|
||||||
sigaction(SIGFPE, &act, NULL);
|
sigaction(SIGFPE, &act, NULL);
|
||||||
sigaction(SIGILL, &act, NULL);
|
sigaction(SIGILL, &act, NULL);
|
||||||
sigaction (SIGBUS, &act, NULL);
|
#endif
|
||||||
|
|
||||||
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
|
|
||||||
act.sa_handler = sigtermHandler;
|
|
||||||
sigaction (SIGTERM, &act, NULL);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_BACKTRACE */
|
|
||||||
void setupSigSegvAction(void) {
|
|
||||||
}
|
|
||||||
#endif /* HAVE_BACKTRACE */
|
|
||||||
|
|
||||||
/* The End */
|
/* The End */
|
||||||
|
@ -777,7 +777,7 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj);
|
|||||||
/* Core functions */
|
/* Core functions */
|
||||||
void freeMemoryIfNeeded(void);
|
void freeMemoryIfNeeded(void);
|
||||||
int processCommand(redisClient *c);
|
int processCommand(redisClient *c);
|
||||||
void setupSigSegvAction(void);
|
void setupSignalHandlers(void);
|
||||||
struct redisCommand *lookupCommand(sds name);
|
struct redisCommand *lookupCommand(sds name);
|
||||||
struct redisCommand *lookupCommandByCString(char *s);
|
struct redisCommand *lookupCommandByCString(char *s);
|
||||||
void call(redisClient *c, struct redisCommand *cmd);
|
void call(redisClient *c, struct redisCommand *cmd);
|
||||||
|
49
src/sds.c
49
src/sds.c
@ -26,6 +26,12 @@
|
|||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* History:
|
||||||
|
*
|
||||||
|
* - 22 March 2011: History section created on top of sds.c
|
||||||
|
* - 22 March 2011: Fixed a problem with "\xab" escapes convertion in
|
||||||
|
* function sdssplitargs().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SDS_ABORT_ON_OOM
|
#define SDS_ABORT_ON_OOM
|
||||||
@ -412,6 +418,37 @@ sds sdscatrepr(sds s, char *p, size_t len) {
|
|||||||
return sdscatlen(s,"\"",1);
|
return sdscatlen(s,"\"",1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper function for sdssplitargs() that returns non zero if 'c'
|
||||||
|
* is a valid hex digit. */
|
||||||
|
int is_hex_digit(char c) {
|
||||||
|
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
|
||||||
|
(c >= 'A' && c <= 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper function for sdssplitargs() that converts an hex digit into an
|
||||||
|
* integer from 0 to 15 */
|
||||||
|
int hex_digit_to_int(char c) {
|
||||||
|
switch(c) {
|
||||||
|
case '0': return 0;
|
||||||
|
case '1': return 1;
|
||||||
|
case '2': return 2;
|
||||||
|
case '3': return 3;
|
||||||
|
case '4': return 4;
|
||||||
|
case '5': return 5;
|
||||||
|
case '6': return 6;
|
||||||
|
case '7': return 7;
|
||||||
|
case '8': return 8;
|
||||||
|
case '9': return 9;
|
||||||
|
case 'a': case 'A': return 10;
|
||||||
|
case 'b': case 'B': return 11;
|
||||||
|
case 'c': case 'C': return 12;
|
||||||
|
case 'd': case 'D': return 13;
|
||||||
|
case 'e': case 'E': return 14;
|
||||||
|
case 'f': case 'F': return 15;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Split a line into arguments, where every argument can be in the
|
/* Split a line into arguments, where every argument can be in the
|
||||||
* following programming-language REPL-alike form:
|
* following programming-language REPL-alike form:
|
||||||
*
|
*
|
||||||
@ -441,7 +478,17 @@ sds *sdssplitargs(char *line, int *argc) {
|
|||||||
if (current == NULL) current = sdsempty();
|
if (current == NULL) current = sdsempty();
|
||||||
while(!done) {
|
while(!done) {
|
||||||
if (inq) {
|
if (inq) {
|
||||||
if (*p == '\\' && *(p+1)) {
|
if (*p == '\\' && *(p+1) == 'x' &&
|
||||||
|
is_hex_digit(*(p+2)) &&
|
||||||
|
is_hex_digit(*(p+3)))
|
||||||
|
{
|
||||||
|
unsigned char byte;
|
||||||
|
|
||||||
|
byte = (hex_digit_to_int(*(p+2))*16)+
|
||||||
|
hex_digit_to_int(*(p+3));
|
||||||
|
current = sdscatlen(current,(char*)&byte,1);
|
||||||
|
p += 3;
|
||||||
|
} else if (*p == '\\' && *(p+1)) {
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
|
Reference in New Issue
Block a user