mirror of
https://github.com/fluencelabs/redis
synced 2025-06-22 05:21:33 +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;
|
||||
int raw_output; /* output mode per command */
|
||||
sds mb_delim;
|
||||
char prompt[32];
|
||||
} config;
|
||||
|
||||
static void usage();
|
||||
@ -85,6 +86,13 @@ static long long mstime(void) {
|
||||
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
|
||||
*--------------------------------------------------------------------------- */
|
||||
@ -264,11 +272,9 @@ static int cliAuth() {
|
||||
/* Send SELECT dbnum to the server */
|
||||
static int cliSelect() {
|
||||
redisReply *reply;
|
||||
char dbnum[16];
|
||||
if (config.dbnum == 0) return REDIS_OK;
|
||||
|
||||
snprintf(dbnum,sizeof(dbnum),"%d",config.dbnum);
|
||||
reply = redisCommand(context,"SELECT %s",dbnum);
|
||||
reply = redisCommand(context,"SELECT %d",config.dbnum);
|
||||
if (reply != NULL) {
|
||||
freeReplyObject(reply);
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
|
||||
@ -616,7 +632,8 @@ static void repl() {
|
||||
config.interactive = 1;
|
||||
linenoiseSetCompletionCallback(completionCallback);
|
||||
|
||||
while((line = linenoise(context ? "redis> " : "not connected> ")) != NULL) {
|
||||
cliRefreshPrompt();
|
||||
while((line = linenoise(context ? config.prompt : "not connected> ")) != NULL) {
|
||||
if (line[0] != '\0') {
|
||||
argv = sdssplitargs(line,&argc);
|
||||
linenoiseHistoryAdd(line);
|
||||
|
38
src/redis.c
38
src/redis.c
@ -837,7 +837,7 @@ void initServer() {
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
setupSigSegvAction();
|
||||
setupSignalHandlers();
|
||||
|
||||
if (server.syslog_enabled) {
|
||||
openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,
|
||||
@ -1574,10 +1574,8 @@ int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ============================= Backtrace support ========================= */
|
||||
|
||||
#ifdef HAVE_BACKTRACE
|
||||
void *getMcontextEip(ucontext_t *uc) {
|
||||
static void *getMcontextEip(ucontext_t *uc) {
|
||||
#if defined(__FreeBSD__)
|
||||
return (void*) uc->uc_mcontext.mc_eip;
|
||||
#elif defined(__dietlibc__)
|
||||
@ -1605,7 +1603,7 @@ void *getMcontextEip(ucontext_t *uc) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void segvHandler(int sig, siginfo_t *info, void *secret) {
|
||||
static void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
||||
void *trace[100];
|
||||
char **messages = NULL;
|
||||
int i, trace_size = 0;
|
||||
@ -1644,37 +1642,35 @@ void segvHandler(int sig, siginfo_t *info, void *secret) {
|
||||
sigaction (sig, &act, NULL);
|
||||
kill(getpid(),sig);
|
||||
}
|
||||
#endif /* HAVE_BACKTRACE */
|
||||
|
||||
void sigtermHandler(int sig) {
|
||||
static void sigtermHandler(int sig) {
|
||||
REDIS_NOTUSED(sig);
|
||||
|
||||
redisLog(REDIS_WARNING,"SIGTERM received, scheduling shutting down...");
|
||||
redisLog(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
|
||||
server.shutdown_asap = 1;
|
||||
}
|
||||
|
||||
void setupSigSegvAction(void) {
|
||||
void setupSignalHandlers(void) {
|
||||
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);
|
||||
/* 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_sigaction = segvHandler;
|
||||
act.sa_sigaction = sigsegvHandler;
|
||||
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_handler = sigtermHandler;
|
||||
sigaction (SIGTERM, &act, NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#else /* HAVE_BACKTRACE */
|
||||
void setupSigSegvAction(void) {
|
||||
}
|
||||
#endif /* HAVE_BACKTRACE */
|
||||
|
||||
/* The End */
|
||||
|
@ -777,7 +777,7 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj);
|
||||
/* Core functions */
|
||||
void freeMemoryIfNeeded(void);
|
||||
int processCommand(redisClient *c);
|
||||
void setupSigSegvAction(void);
|
||||
void setupSignalHandlers(void);
|
||||
struct redisCommand *lookupCommand(sds name);
|
||||
struct redisCommand *lookupCommandByCString(char *s);
|
||||
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)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* 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
|
||||
@ -412,6 +418,37 @@ sds sdscatrepr(sds s, char *p, size_t len) {
|
||||
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
|
||||
* following programming-language REPL-alike form:
|
||||
*
|
||||
@ -441,7 +478,17 @@ sds *sdssplitargs(char *line, int *argc) {
|
||||
if (current == NULL) current = sdsempty();
|
||||
while(!done) {
|
||||
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;
|
||||
|
||||
p++;
|
||||
|
Reference in New Issue
Block a user