Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
eff09a7b
Commit
eff09a7b
authored
Sep 03, 2010
by
antirez
Browse files
redis-cli completely replaced with the version in Redis master
parent
efc8a6be
Changes
5
Hide whitespace changes
Inline
Side-by-side
linenoise.c
View file @
eff09a7b
...
@@ -70,6 +70,7 @@
...
@@ -70,6 +70,7 @@
*/
*/
#include "fmacros.h"
#include "fmacros.h"
#include <termios.h>
#include <termios.h>
#include <unistd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdlib.h>
...
@@ -81,13 +82,14 @@
...
@@ -81,13 +82,14 @@
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <unistd.h>
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
#define LINENOISE_MAX_LINE 4096
#define LINENOISE_MAX_LINE 4096
static
char
*
unsupported_term
[]
=
{
"dumb"
,
"cons25"
,
NULL
};
static
char
*
unsupported_term
[]
=
{
"dumb"
,
"cons25"
,
NULL
};
static
struct
termios
orig_termios
;
/* in order to restore at exit */
static
struct
termios
orig_termios
;
/* in order to restore at exit */
static
int
rawmode
=
0
;
/* for atexit() function to check if restore is needed*/
static
int
rawmode
=
0
;
/* for atexit() function to check if restore is needed*/
static
int
atexit_registered
=
0
;
/* register atexit just 1 time */
static
int
atexit_registered
=
0
;
/* register atexit just 1 time */
static
int
history_max_len
=
100
;
static
int
history_max_len
=
LINENOISE_DEFAULT_HISTORY_MAX_LEN
;
static
int
history_len
=
0
;
static
int
history_len
=
0
;
char
**
history
=
NULL
;
char
**
history
=
NULL
;
...
@@ -219,11 +221,10 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt)
...
@@ -219,11 +221,10 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt)
if
(
nread
<=
0
)
return
len
;
if
(
nread
<=
0
)
return
len
;
switch
(
c
)
{
switch
(
c
)
{
case
13
:
/* enter */
case
13
:
/* enter */
history_len
--
;
return
len
;
case
4
:
/* ctrl-d */
case
4
:
/* ctrl-d */
history_len
--
;
history_len
--
;
return
(
len
==
0
)
?
-
1
:
(
int
)
len
;
free
(
history
[
history_len
]);
return
(
len
==
0
&&
c
==
4
)
?
-
1
:
(
int
)
len
;
case
3
:
/* ctrl-c */
case
3
:
/* ctrl-c */
errno
=
EAGAIN
;
errno
=
EAGAIN
;
return
-
1
;
return
-
1
;
...
@@ -396,7 +397,7 @@ int linenoiseHistoryAdd(const char *line) {
...
@@ -396,7 +397,7 @@ int linenoiseHistoryAdd(const char *line) {
char
*
linecopy
;
char
*
linecopy
;
if
(
history_max_len
==
0
)
return
0
;
if
(
history_max_len
==
0
)
return
0
;
if
(
history
==
0
)
{
if
(
history
==
NULL
)
{
history
=
malloc
(
sizeof
(
char
*
)
*
history_max_len
);
history
=
malloc
(
sizeof
(
char
*
)
*
history_max_len
);
if
(
history
==
NULL
)
return
0
;
if
(
history
==
NULL
)
return
0
;
memset
(
history
,
0
,(
sizeof
(
char
*
)
*
history_max_len
));
memset
(
history
,
0
,(
sizeof
(
char
*
)
*
history_max_len
));
...
@@ -404,6 +405,7 @@ int linenoiseHistoryAdd(const char *line) {
...
@@ -404,6 +405,7 @@ int linenoiseHistoryAdd(const char *line) {
linecopy
=
strdup
(
line
);
linecopy
=
strdup
(
line
);
if
(
!
linecopy
)
return
0
;
if
(
!
linecopy
)
return
0
;
if
(
history_len
==
history_max_len
)
{
if
(
history_len
==
history_max_len
)
{
free
(
history
[
0
]);
memmove
(
history
,
history
+
1
,
sizeof
(
char
*
)
*
(
history_max_len
-
1
));
memmove
(
history
,
history
+
1
,
sizeof
(
char
*
)
*
(
history_max_len
-
1
));
history_len
--
;
history_len
--
;
}
}
...
@@ -431,3 +433,39 @@ int linenoiseHistorySetMaxLen(int len) {
...
@@ -431,3 +433,39 @@ int linenoiseHistorySetMaxLen(int len) {
history_len
=
history_max_len
;
history_len
=
history_max_len
;
return
1
;
return
1
;
}
}
/* Save the history in the specified file. On success 0 is returned
* otherwise -1 is returned. */
int
linenoiseHistorySave
(
char
*
filename
)
{
FILE
*
fp
=
fopen
(
filename
,
"w"
);
int
j
;
if
(
fp
==
NULL
)
return
-
1
;
for
(
j
=
0
;
j
<
history_len
;
j
++
)
fprintf
(
fp
,
"%s
\n
"
,
history
[
j
]);
fclose
(
fp
);
return
0
;
}
/* Load the history from the specified file. If the file does not exist
* zero is returned and no operation is performed.
*
* If the file exists and the operation succeeded 0 is returned, otherwise
* on error -1 is returned. */
int
linenoiseHistoryLoad
(
char
*
filename
)
{
FILE
*
fp
=
fopen
(
filename
,
"r"
);
char
buf
[
LINENOISE_MAX_LINE
];
if
(
fp
==
NULL
)
return
-
1
;
while
(
fgets
(
buf
,
LINENOISE_MAX_LINE
,
fp
)
!=
NULL
)
{
char
*
p
;
p
=
strchr
(
buf
,
'\r'
);
if
(
!
p
)
p
=
strchr
(
buf
,
'\n'
);
if
(
p
)
*
p
=
'\0'
;
linenoiseHistoryAdd
(
buf
);
}
fclose
(
fp
);
return
0
;
}
linenoise.h
View file @
eff09a7b
...
@@ -35,7 +35,9 @@
...
@@ -35,7 +35,9 @@
#define __LINENOISE_H
#define __LINENOISE_H
char
*
linenoise
(
const
char
*
prompt
);
char
*
linenoise
(
const
char
*
prompt
);
int
linenoiseHistoryAdd
(
char
*
line
);
int
linenoiseHistoryAdd
(
const
char
*
line
);
int
linenoiseHistorySetMaxLen
(
int
len
);
int
linenoiseHistorySetMaxLen
(
int
len
);
int
linenoiseHistorySave
(
char
*
filename
);
int
linenoiseHistoryLoad
(
char
*
filename
);
#endif
/* __LINENOISE_H */
#endif
/* __LINENOISE_H */
redis-cli.c
View file @
eff09a7b
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <unistd.h>
#include <ctype.h>
#include <ctype.h>
#include <errno.h>
#include <errno.h>
#include <sys/stat.h>
#include "anet.h"
#include "anet.h"
#include "sds.h"
#include "sds.h"
...
@@ -54,13 +55,15 @@ static struct config {
...
@@ -54,13 +55,15 @@ static struct config {
int
hostport
;
int
hostport
;
long
repeat
;
long
repeat
;
int
dbnum
;
int
dbnum
;
int
argn_from_stdin
;
int
interactive
;
int
interactive
;
int
shutdown
;
int
shutdown
;
int
monitor_mode
;
int
monitor_mode
;
int
pubsub_mode
;
int
pubsub_mode
;
int
raw_output
;
int
raw_output
;
/* output mode per command */
int
tty
;
/* flag for default output format */
char
mb_sep
;
char
*
auth
;
char
*
auth
;
char
*
historyfile
;
}
config
;
}
config
;
static
int
cliReadReply
(
int
fd
);
static
int
cliReadReply
(
int
fd
);
...
@@ -92,7 +95,7 @@ static sds cliReadLine(int fd) {
...
@@ -92,7 +95,7 @@ static sds cliReadLine(int fd) {
ssize_t
ret
;
ssize_t
ret
;
ret
=
read
(
fd
,
&
c
,
1
);
ret
=
read
(
fd
,
&
c
,
1
);
if
(
ret
=
=
-
1
)
{
if
(
ret
<
=
0
)
{
sdsfree
(
line
);
sdsfree
(
line
);
return
NULL
;
return
NULL
;
}
else
if
((
ret
==
0
)
||
(
c
==
'\n'
))
{
}
else
if
((
ret
==
0
)
||
(
c
==
'\n'
))
{
...
@@ -109,7 +112,7 @@ static int cliReadSingleLineReply(int fd, int quiet) {
...
@@ -109,7 +112,7 @@ static int cliReadSingleLineReply(int fd, int quiet) {
if
(
reply
==
NULL
)
return
1
;
if
(
reply
==
NULL
)
return
1
;
if
(
!
quiet
)
if
(
!
quiet
)
printf
(
"%s
\n
"
,
reply
);
printf
(
"%s"
,
reply
);
sdsfree
(
reply
);
sdsfree
(
reply
);
return
0
;
return
0
;
}
}
...
@@ -136,7 +139,7 @@ static void printStringRepr(char *s, int len) {
...
@@ -136,7 +139,7 @@ static void printStringRepr(char *s, int len) {
}
}
s
++
;
s
++
;
}
}
printf
(
"
\"
\n
"
);
printf
(
"
\"
"
);
}
}
static
int
cliReadBulkReply
(
int
fd
)
{
static
int
cliReadBulkReply
(
int
fd
)
{
...
@@ -154,7 +157,7 @@ static int cliReadBulkReply(int fd) {
...
@@ -154,7 +157,7 @@ static int cliReadBulkReply(int fd) {
reply
=
zmalloc
(
bulklen
);
reply
=
zmalloc
(
bulklen
);
anetRead
(
fd
,
reply
,
bulklen
);
anetRead
(
fd
,
reply
,
bulklen
);
anetRead
(
fd
,
crlf
,
2
);
anetRead
(
fd
,
crlf
,
2
);
if
(
config
.
raw_output
||
!
isatty
(
fileno
(
stdout
))
)
{
if
(
config
.
raw_output
||
!
config
.
tty
)
{
if
(
bulklen
&&
fwrite
(
reply
,
bulklen
,
1
,
stdout
)
==
0
)
{
if
(
bulklen
&&
fwrite
(
reply
,
bulklen
,
1
,
stdout
)
==
0
)
{
zfree
(
reply
);
zfree
(
reply
);
return
1
;
return
1
;
...
@@ -171,6 +174,7 @@ static int cliReadBulkReply(int fd) {
...
@@ -171,6 +174,7 @@ static int cliReadBulkReply(int fd) {
static
int
cliReadMultiBulkReply
(
int
fd
)
{
static
int
cliReadMultiBulkReply
(
int
fd
)
{
sds
replylen
=
cliReadLine
(
fd
);
sds
replylen
=
cliReadLine
(
fd
);
int
elements
,
c
=
1
;
int
elements
,
c
=
1
;
int
retval
=
0
;
if
(
replylen
==
NULL
)
return
1
;
if
(
replylen
==
NULL
)
return
1
;
elements
=
atoi
(
replylen
);
elements
=
atoi
(
replylen
);
...
@@ -183,11 +187,12 @@ static int cliReadMultiBulkReply(int fd) {
...
@@ -183,11 +187,12 @@ static int cliReadMultiBulkReply(int fd) {
printf
(
"(empty list or set)
\n
"
);
printf
(
"(empty list or set)
\n
"
);
}
}
while
(
elements
--
)
{
while
(
elements
--
)
{
printf
(
"%d. "
,
c
);
if
(
config
.
tty
)
printf
(
"%d. "
,
c
);
if
(
cliReadReply
(
fd
))
return
1
;
if
(
cliReadReply
(
fd
))
retval
=
1
;
if
(
elements
)
printf
(
"%c"
,
config
.
mb_sep
);
c
++
;
c
++
;
}
}
return
0
;
return
retval
;
}
}
static
int
cliReadReply
(
int
fd
)
{
static
int
cliReadReply
(
int
fd
)
{
...
@@ -207,20 +212,20 @@ static int cliReadReply(int fd) {
...
@@ -207,20 +212,20 @@ static int cliReadReply(int fd) {
}
}
switch
(
type
)
{
switch
(
type
)
{
case
'-'
:
case
'-'
:
printf
(
"(error) "
);
if
(
config
.
tty
)
printf
(
"(error) "
);
cliReadSingleLineReply
(
fd
,
0
);
cliReadSingleLineReply
(
fd
,
0
);
return
1
;
return
1
;
case
'+'
:
case
'+'
:
return
cliReadSingleLineReply
(
fd
,
0
);
return
cliReadSingleLineReply
(
fd
,
0
);
case
':'
:
case
':'
:
printf
(
"(integer) "
);
if
(
config
.
tty
)
printf
(
"(integer) "
);
return
cliReadSingleLineReply
(
fd
,
0
);
return
cliReadSingleLineReply
(
fd
,
0
);
case
'$'
:
case
'$'
:
return
cliReadBulkReply
(
fd
);
return
cliReadBulkReply
(
fd
);
case
'*'
:
case
'*'
:
return
cliReadMultiBulkReply
(
fd
);
return
cliReadMultiBulkReply
(
fd
);
default:
default:
printf
(
"protocol error, got '%c' as reply type byte
\n
"
,
type
);
printf
(
"protocol error, got '%c' as reply type byte"
,
type
);
return
1
;
return
1
;
}
}
}
}
...
@@ -245,12 +250,32 @@ static int selectDb(int fd) {
...
@@ -245,12 +250,32 @@ static int selectDb(int fd) {
return
0
;
return
0
;
}
}
static
void
showInteractiveHelp
(
void
)
{
printf
(
"
\n
"
"Welcome to redis-cli 2.0.0!
\n
"
"Just type any valid Redis command to see a pretty printed output.
\n
"
"
\n
"
"It is possible to quote strings, like in:
\n
"
" set
\"
my key
\"
\"
some string
\\
xff
\\
n
\"\n
"
"
\n
"
"You can find a list of valid Redis commands at
\n
"
" http://code.google.com/p/redis/wiki/CommandReference
\n
"
"
\n
"
"Note: redis-cli supports line editing, use up/down arrows for history."
"
\n\n
"
);
}
static
int
cliSendCommand
(
int
argc
,
char
**
argv
,
int
repeat
)
{
static
int
cliSendCommand
(
int
argc
,
char
**
argv
,
int
repeat
)
{
char
*
command
=
argv
[
0
];
char
*
command
=
argv
[
0
];
int
fd
,
j
,
retval
=
0
;
int
fd
,
j
,
retval
=
0
;
sds
cmd
;
sds
cmd
;
config
.
raw_output
=
!
strcasecmp
(
command
,
"info"
);
config
.
raw_output
=
!
strcasecmp
(
command
,
"info"
);
if
(
!
strcasecmp
(
command
,
"help"
))
{
showInteractiveHelp
();
return
0
;
}
if
(
!
strcasecmp
(
command
,
"shutdown"
))
config
.
shutdown
=
1
;
if
(
!
strcasecmp
(
command
,
"shutdown"
))
config
.
shutdown
=
1
;
if
(
!
strcasecmp
(
command
,
"monitor"
))
config
.
monitor_mode
=
1
;
if
(
!
strcasecmp
(
command
,
"monitor"
))
config
.
monitor_mode
=
1
;
if
(
!
strcasecmp
(
command
,
"subscribe"
)
||
if
(
!
strcasecmp
(
command
,
"subscribe"
)
||
...
@@ -276,21 +301,21 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
...
@@ -276,21 +301,21 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
while
(
repeat
--
)
{
while
(
repeat
--
)
{
anetWrite
(
fd
,
cmd
,
sdslen
(
cmd
));
anetWrite
(
fd
,
cmd
,
sdslen
(
cmd
));
while
(
config
.
monitor_mode
)
{
while
(
config
.
monitor_mode
)
{
cliReadSingleLineReply
(
fd
,
0
);
if
(
cliReadSingleLineReply
(
fd
,
0
))
exit
(
1
);
printf
(
"
\n
"
);
}
}
if
(
config
.
pubsub_mode
)
{
if
(
config
.
pubsub_mode
)
{
printf
(
"Reading messages... (press Ctrl-c to quit)
\n
"
);
printf
(
"Reading messages... (press Ctrl-c to quit)
\n
"
);
while
(
1
)
{
while
(
1
)
{
cliReadReply
(
fd
);
cliReadReply
(
fd
);
printf
(
"
\n
"
);
printf
(
"
\n
\n
"
);
}
}
}
}
retval
=
cliReadReply
(
fd
);
retval
=
cliReadReply
(
fd
);
if
(
retval
)
{
if
(
!
config
.
raw_output
&&
config
.
tty
)
printf
(
"
\n
"
);
return
retval
;
if
(
retval
)
return
retval
;
}
}
}
return
0
;
return
0
;
}
}
...
@@ -324,9 +349,19 @@ static int parseOptions(int argc, char **argv) {
...
@@ -324,9 +349,19 @@ static int parseOptions(int argc, char **argv) {
config
.
auth
=
argv
[
i
+
1
];
config
.
auth
=
argv
[
i
+
1
];
i
++
;
i
++
;
}
else
if
(
!
strcmp
(
argv
[
i
],
"-i"
))
{
}
else
if
(
!
strcmp
(
argv
[
i
],
"-i"
))
{
config
.
interactive
=
1
;
fprintf
(
stderr
,
"Starting interactive mode using -i is deprecated. Interactive mode is started
\n
"
"by default when redis-cli is executed without a command to execute.
\n
"
);
}
else
if
(
!
strcmp
(
argv
[
i
],
"-c"
))
{
}
else
if
(
!
strcmp
(
argv
[
i
],
"-c"
))
{
config
.
argn_from_stdin
=
1
;
fprintf
(
stderr
,
"Reading last argument from standard input using -c is deprecated.
\n
"
"When standard input is connected to a pipe or regular file, it is
\n
"
"automatically used as last argument.
\n
"
);
}
else
if
(
!
strcmp
(
argv
[
i
],
"-v"
))
{
printf
(
"redis-cli shipped with Redis verison %s
\n
"
,
"2.0.0"
);
exit
(
0
);
}
else
{
}
else
{
break
;
break
;
}
}
...
@@ -352,8 +387,8 @@ static sds readArgFromStdin(void) {
...
@@ -352,8 +387,8 @@ static sds readArgFromStdin(void) {
}
}
static
void
usage
()
{
static
void
usage
()
{
fprintf
(
stderr
,
"usage: redis-cli [-h host] [-p port] [-a authpw] [-r repeat_times] [-n db_num]
[-i]
cmd arg1 arg2 arg3 ... argN
\n
"
);
fprintf
(
stderr
,
"usage: redis-cli
[-iv]
[-h host] [-p port] [-a authpw] [-r repeat_times] [-n db_num] cmd arg1 arg2 arg3 ... argN
\n
"
);
fprintf
(
stderr
,
"usage: echo
\"
argN
\"
| redis-cli
-c
[-h host] [-p port] [-a authpw] [-r repeat_times] [-n db_num] cmd arg1 arg2 ... arg(N-1)
\n
"
);
fprintf
(
stderr
,
"usage: echo
\"
argN
\"
| redis-cli [-h host] [-p port] [-a authpw] [-r repeat_times] [-n db_num] cmd arg1 arg2 ... arg(N-1)
\n
"
);
fprintf
(
stderr
,
"
\n
If a pipe from standard input is detected this data is used as last argument.
\n\n
"
);
fprintf
(
stderr
,
"
\n
If a pipe from standard input is detected this data is used as last argument.
\n\n
"
);
fprintf
(
stderr
,
"example: cat /etc/passwd | redis-cli set my_passwd
\n
"
);
fprintf
(
stderr
,
"example: cat /etc/passwd | redis-cli set my_passwd
\n
"
);
fprintf
(
stderr
,
"example: redis-cli get my_passwd
\n
"
);
fprintf
(
stderr
,
"example: redis-cli get my_passwd
\n
"
);
...
@@ -373,81 +408,22 @@ static char **convertToSds(int count, char** args) {
...
@@ -373,81 +408,22 @@ static char **convertToSds(int count, char** args) {
return
sds
;
return
sds
;
}
}
static
char
**
splitArguments
(
char
*
line
,
int
*
argc
)
{
char
*
p
=
line
;
char
*
current
=
NULL
;
char
**
vector
=
NULL
;
*
argc
=
0
;
while
(
1
)
{
/* skip blanks */
while
(
*
p
&&
isspace
(
*
p
))
p
++
;
if
(
*
p
)
{
/* get a token */
int
inq
=
0
;
/* set to 1 if we are in "quotes" */
int
done
=
0
;
if
(
current
==
NULL
)
current
=
sdsempty
();
while
(
!
done
)
{
if
(
inq
)
{
if
(
*
p
==
'\\'
&&
*
(
p
+
1
))
{
char
c
;
p
++
;
switch
(
*
p
)
{
case
'n'
:
c
=
'\n'
;
break
;
case
'r'
:
c
=
'\r'
;
break
;
case
't'
:
c
=
'\t'
;
break
;
case
'b'
:
c
=
'\b'
;
break
;
case
'a'
:
c
=
'\a'
;
break
;
default:
c
=
*
p
;
break
;
}
current
=
sdscatlen
(
current
,
&
c
,
1
);
}
else
if
(
*
p
==
'"'
)
{
done
=
1
;
}
else
{
current
=
sdscatlen
(
current
,
p
,
1
);
}
}
else
{
switch
(
*
p
)
{
case
' '
:
case
'\n'
:
case
'\r'
:
case
'\t'
:
case
'\0'
:
done
=
1
;
break
;
case
'"'
:
inq
=
1
;
break
;
default:
current
=
sdscatlen
(
current
,
p
,
1
);
break
;
}
}
if
(
*
p
)
p
++
;
}
/* add the token to the vector */
vector
=
zrealloc
(
vector
,((
*
argc
)
+
1
)
*
sizeof
(
char
*
));
vector
[
*
argc
]
=
current
;
(
*
argc
)
++
;
current
=
NULL
;
}
else
{
return
vector
;
}
}
}
#define LINE_BUFLEN 4096
#define LINE_BUFLEN 4096
static
void
repl
()
{
static
void
repl
()
{
int
argc
,
j
;
int
argc
,
j
;
char
*
line
,
**
argv
;
char
*
line
;
sds
*
argv
;
config
.
interactive
=
1
;
while
((
line
=
linenoise
(
"redis> "
))
!=
NULL
)
{
while
((
line
=
linenoise
(
"redis> "
))
!=
NULL
)
{
if
(
line
[
0
]
!=
'\0'
)
{
if
(
line
[
0
]
!=
'\0'
)
{
argv
=
split
A
rg
ument
s
(
line
,
&
argc
);
argv
=
sds
split
a
rgs
(
line
,
&
argc
);
linenoiseHistoryAdd
(
line
);
linenoiseHistoryAdd
(
line
);
if
(
argc
>
0
)
{
if
(
config
.
historyfile
)
linenoiseHistorySave
(
config
.
historyfile
);
if
(
argv
==
NULL
)
{
printf
(
"Invalid argument(s)
\n
"
);
continue
;
}
else
if
(
argc
>
0
)
{
if
(
strcasecmp
(
argv
[
0
],
"quit"
)
==
0
||
if
(
strcasecmp
(
argv
[
0
],
"quit"
)
==
0
||
strcasecmp
(
argv
[
0
],
"exit"
)
==
0
)
strcasecmp
(
argv
[
0
],
"exit"
)
==
0
)
{
{
...
@@ -477,21 +453,43 @@ static void repl() {
...
@@ -477,21 +453,43 @@ static void repl() {
exit
(
0
);
exit
(
0
);
}
}
static
int
noninteractive
(
int
argc
,
char
**
argv
)
{
int
retval
=
0
;
struct
stat
s
;
fstat
(
fileno
(
stdin
),
&
s
);
if
(
S_ISFIFO
(
s
.
st_mode
)
||
S_ISREG
(
s
.
st_mode
))
{
/* pipe, regular file */
argv
=
zrealloc
(
argv
,
(
argc
+
1
)
*
sizeof
(
char
*
));
argv
[
argc
]
=
readArgFromStdin
();
retval
=
cliSendCommand
(
argc
+
1
,
argv
,
config
.
repeat
);
}
else
{
/* stdin is probably a tty, can be tested with S_ISCHR(s.st_mode) */
retval
=
cliSendCommand
(
argc
,
argv
,
config
.
repeat
);
}
return
retval
;
}
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
int
firstarg
;
int
firstarg
;
char
**
argvcopy
;
config
.
hostip
=
"127.0.0.1"
;
config
.
hostip
=
"127.0.0.1"
;
config
.
hostport
=
6379
;
config
.
hostport
=
6379
;
config
.
repeat
=
1
;
config
.
repeat
=
1
;
config
.
dbnum
=
0
;
config
.
dbnum
=
0
;
config
.
argn_from_stdin
=
0
;
config
.
shutdown
=
0
;
config
.
interactive
=
0
;
config
.
interactive
=
0
;
config
.
shutdown
=
0
;
config
.
monitor_mode
=
0
;
config
.
monitor_mode
=
0
;
config
.
pubsub_mode
=
0
;
config
.
pubsub_mode
=
0
;
config
.
raw_output
=
0
;
config
.
raw_output
=
0
;
config
.
auth
=
NULL
;
config
.
auth
=
NULL
;
config
.
historyfile
=
NULL
;
config
.
tty
=
isatty
(
fileno
(
stdout
))
||
(
getenv
(
"FAKETTY"
)
!=
NULL
);
config
.
mb_sep
=
'\n'
;
if
(
getenv
(
"HOME"
)
!=
NULL
)
{
config
.
historyfile
=
malloc
(
256
);
snprintf
(
config
.
historyfile
,
256
,
"%s/.rediscli_history"
,
getenv
(
"HOME"
));
linenoiseHistoryLoad
(
config
.
historyfile
);
}
firstarg
=
parseOptions
(
argc
,
argv
);
firstarg
=
parseOptions
(
argc
,
argv
);
argc
-=
firstarg
;
argc
-=
firstarg
;
...
@@ -499,20 +497,20 @@ int main(int argc, char **argv) {
...
@@ -499,20 +497,20 @@ int main(int argc, char **argv) {
if
(
config
.
auth
!=
NULL
)
{
if
(
config
.
auth
!=
NULL
)
{
char
*
authargv
[
2
];
char
*
authargv
[
2
];
int
dbnum
=
config
.
dbnum
;
/* We need to save the real configured database number and set it to
* zero here, otherwise cliSendCommand() will try to perform the
* SELECT command before the authentication, and it will fail. */
config
.
dbnum
=
0
;
authargv
[
0
]
=
"AUTH"
;
authargv
[
0
]
=
"AUTH"
;
authargv
[
1
]
=
config
.
auth
;
authargv
[
1
]
=
config
.
auth
;
cliSendCommand
(
2
,
convertToSds
(
2
,
authargv
),
1
);
cliSendCommand
(
2
,
convertToSds
(
2
,
authargv
),
1
);
config
.
dbnum
=
dbnum
;
/* restore the right DB number */
}
}
if
(
argc
==
0
)
config
.
interactive
=
1
;
/* Start interactive mode when no command is provided */
if
(
config
.
interactive
)
repl
();
if
(
argc
==
0
)
repl
();
/* Otherwise, we have some arguments to execute */
argvcopy
=
convertToSds
(
argc
+
1
,
argv
);
return
noninteractive
(
argc
,
convertToSds
(
argc
,
argv
));
if
(
config
.
argn_from_stdin
)
{
sds
lastarg
=
readArgFromStdin
();
argvcopy
[
argc
]
=
lastarg
;
argc
++
;
}
return
cliSendCommand
(
argc
,
argvcopy
,
config
.
repeat
);
}
}
sds.c
View file @
eff09a7b
...
@@ -357,3 +357,92 @@ sds sdsfromlonglong(long long value) {
...
@@ -357,3 +357,92 @@ sds sdsfromlonglong(long long value) {
p
++
;
p
++
;
return
sdsnewlen
(
p
,
32
-
(
p
-
buf
));
return
sdsnewlen
(
p
,
32
-
(
p
-
buf
));
}
}
/* Split a line into arguments, where every argument can be in the
* following programming-language REPL-alike form:
*
* foo bar "newline are supported\n" and "\xff\x00otherstuff"
*
* The number of arguments is stored into *argc, and an array
* of sds is returned. The caller should sdsfree() all the returned
* strings and finally zfree() the array itself.
*
* Note that sdscatrepr() is able to convert back a string into
* a quoted string in the same format sdssplitargs() is able to parse.
*/
sds
*
sdssplitargs
(
char
*
line
,
int
*
argc
)
{
char
*
p
=
line
;
char
*
current
=
NULL
;
char
**
vector
=
NULL
;
*
argc
=
0
;
while
(
1
)
{
/* skip blanks */
while
(
*
p
&&
isspace
(
*
p
))
p
++
;
if
(
*
p
)
{
/* get a token */
int
inq
=
0
;
/* set to 1 if we are in "quotes" */
int
done
=
0
;
if
(
current
==
NULL
)
current
=
sdsempty
();
while
(
!
done
)
{
if
(
inq
)
{
if
(
*
p
==
'\\'
&&
*
(
p
+
1
))
{
char
c
;
p
++
;
switch
(
*
p
)
{
case
'n'
:
c
=
'\n'
;
break
;
case
'r'
:
c
=
'\r'
;
break
;
case
't'
:
c
=
'\t'
;
break
;
case
'b'
:
c
=
'\b'
;
break
;
case
'a'
:
c
=
'\a'
;
break
;
default:
c
=
*
p
;
break
;
}
current
=
sdscatlen
(
current
,
&
c
,
1
);
}
else
if
(
*
p
==
'"'
)
{
/* closing quote must be followed by a space */
if
(
*
(
p
+
1
)
&&
!
isspace
(
*
(
p
+
1
)))
goto
err
;
done
=
1
;
}
else
if
(
!*
p
)
{
/* unterminated quotes */
goto
err
;
}
else
{
current
=
sdscatlen
(
current
,
p
,
1
);
}
}
else
{
switch
(
*
p
)
{
case
' '
:
case
'\n'
:
case
'\r'
:
case
'\t'
:
case
'\0'
:
done
=
1
;
break
;
case
'"'
:
inq
=
1
;
break
;
default:
current
=
sdscatlen
(
current
,
p
,
1
);
break
;
}
}
if
(
*
p
)
p
++
;
}
/* add the token to the vector */
vector
=
zrealloc
(
vector
,((
*
argc
)
+
1
)
*
sizeof
(
char
*
));
vector
[
*
argc
]
=
current
;
(
*
argc
)
++
;
current
=
NULL
;
}
else
{
return
vector
;
}
}
err:
while
((
*
argc
)
--
)
sdsfree
(
vector
[
*
argc
]);
zfree
(
vector
);
if
(
current
)
sdsfree
(
current
);
return
NULL
;
}
sds.h
View file @
eff09a7b
...
@@ -69,5 +69,6 @@ void sdsfreesplitres(sds *tokens, int count);
...
@@ -69,5 +69,6 @@ void sdsfreesplitres(sds *tokens, int count);
void
sdstolower
(
sds
s
);
void
sdstolower
(
sds
s
);
void
sdstoupper
(
sds
s
);
void
sdstoupper
(
sds
s
);
sds
sdsfromlonglong
(
long
long
value
);
sds
sdsfromlonglong
(
long
long
value
);
sds
*
sdssplitargs
(
char
*
line
,
int
*
argc
);
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment