CLIENT LIST implemented

This commit is contained in:
antirez 2011-04-21 15:38:02 +02:00
parent 17b24ff30d
commit 3cd12b5687
6 changed files with 64 additions and 2 deletions

View File

@ -345,3 +345,13 @@ int anetUnixAccept(char *err, int s) {
return fd;
}
int anetPeerToString(int fd, char *ip, int *port) {
struct sockaddr_in sa;
socklen_t salen = sizeof(sa);
if (getpeername(fd,(struct sockaddr*)&sa,&salen) == -1) return -1;
if (ip) strcpy(ip,inet_ntoa(sa.sin_addr));
if (port) *port = ntohs(sa.sin_port);
return 0;
}

View File

@ -53,5 +53,6 @@ int anetWrite(int fd, char *buf, int count);
int anetNonBlock(char *err, int fd);
int anetTcpNoDelay(char *err, int fd);
int anetTcpKeepAlive(char *err, int fd);
int anetPeerToString(int fd, char *ip, int *port);
#endif

View File

@ -869,3 +869,49 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
*biggest_input_buffer = bib;
}
void clientCommand(redisClient *c) {
if (!strcasecmp(c->argv[1]->ptr,"list") && c->argc == 2) {
listNode *ln;
listIter li;
sds o = sdsempty();
time_t now = time(NULL);
listRewind(server.clients,&li);
while ((ln = listNext(&li)) != NULL) {
redisClient *client;
char ip[32], flags[16], *p;
int port;
client = listNodeValue(ln);
if (anetPeerToString(client->fd,ip,&port) == -1) continue;
p = flags;
if (client->flags & REDIS_SLAVE) {
if (client->flags & REDIS_MONITOR)
*p++ = 'O';
else
*p++ = 'S';
}
if (client->flags & REDIS_MASTER) *p++ = 'M';
if (p == flags) *p++ = 'N';
if (client->flags & REDIS_MULTI) *p++ = 'x';
if (client->flags & REDIS_BLOCKED) *p++ = 'b';
if (client->flags & REDIS_IO_WAIT) *p++ = 'i';
if (client->flags & REDIS_DIRTY_CAS) *p++ = 'd';
if (client->flags & REDIS_CLOSE_AFTER_REPLY) *p++ = 'c';
if (client->flags & REDIS_UNBLOCKED) *p++ = 'u';
*p++ = '\0';
o = sdscatprintf(o,
"addr=%s:%d fd=%d idle=%ld flags=%s db=%d sub=%d psub=%d\n",
ip,port,client->fd,
(long)(now - client->lastinteraction),
flags,
client->db->id,
(int) dictSize(client->pubsub_channels),
(int) listLength(client->pubsub_patterns));
}
addReplyBulkCBuffer(c,o,sdslen(o));
sdsfree(o);
} else {
addReplyError(c, "Syntax error, try CLIENT (LIST | KILL ip:port)");
}
}

View File

@ -471,7 +471,10 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
if (!strcasecmp(command,"info") ||
(argc == 2 && !strcasecmp(command,"cluster") &&
(!strcasecmp(argv[1],"nodes") ||
!strcasecmp(argv[1],"info"))))
!strcasecmp(argv[1],"info"))) ||
(argc == 2 && !strcasecmp(command,"client") &&
!strcasecmp(argv[1],"list")))
{
output_raw = 1;
}

View File

@ -192,7 +192,8 @@ struct redisCommand redisCommandTable[] = {
{"restore",restoreCommand,4,0,NULL,0,0,0,0,0},
{"migrate",migrateCommand,6,0,NULL,0,0,0,0,0},
{"dump",dumpCommand,2,0,NULL,0,0,0,0,0},
{"object",objectCommand,-2,0,NULL,0,0,0,0,0}
{"object",objectCommand,-2,0,NULL,0,0,0,0,0},
{"client",clientCommand,-2,0,NULL,0,0,0,0,0}
};
/*============================ Utility functions ============================ */

View File

@ -1200,6 +1200,7 @@ void restoreCommand(redisClient *c);
void migrateCommand(redisClient *c);
void dumpCommand(redisClient *c);
void objectCommand(redisClient *c);
void clientCommand(redisClient *c);
#if defined(__GNUC__)
void *calloc(size_t count, size_t size) __attribute__ ((deprecated));