Merge branch '2.2' of github.com:antirez/redis into 2.2

This commit is contained in:
antirez
2011-03-31 16:45:27 +02:00
4 changed files with 92 additions and 32 deletions

View File

@ -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);

View File

@ -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;
sigemptyset (&act.sa_mask); /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used.
/* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction * Otherwise, sa_handler is used. */
* is used. Otherwise, sa_handler is used */ sigemptyset(&act.sa_mask);
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
act.sa_sigaction = segvHandler;
sigaction (SIGSEGV, &act, NULL);
sigaction (SIGBUS, &act, NULL);
sigaction (SIGFPE, &act, NULL);
sigaction (SIGILL, &act, NULL);
sigaction (SIGBUS, &act, NULL);
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
act.sa_handler = sigtermHandler; act.sa_handler = sigtermHandler;
sigaction (SIGTERM, &act, NULL); sigaction(SIGTERM, &act, NULL);
#ifdef HAVE_BACKTRACE
sigemptyset(&act.sa_mask);
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
act.sa_sigaction = sigsegvHandler;
sigaction(SIGSEGV, &act, NULL);
sigaction(SIGBUS, &act, NULL);
sigaction(SIGFPE, &act, NULL);
sigaction(SIGILL, &act, NULL);
#endif
return; return;
} }
#else /* HAVE_BACKTRACE */
void setupSigSegvAction(void) {
}
#endif /* HAVE_BACKTRACE */
/* The End */ /* The End */

View File

@ -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);

View File

@ -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++;