Skip to content

Commit

Permalink
Support for command line configuration options for redis-server.
Browse files Browse the repository at this point in the history
  • Loading branch information
antirez committed Dec 1, 2011
1 parent 4c8bd90 commit 67c6f0f
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 38 deletions.
86 changes: 53 additions & 33 deletions src/config.c
Expand Up @@ -23,39 +23,25 @@ void resetServerSaveParams() {
server.saveparamslen = 0;
}

/* I agree, this is a very rudimental way to load a configuration...
will improve later if the config gets more complex */
void loadServerConfig(char *filename) {
FILE *fp;
char buf[REDIS_CONFIGLINE_MAX+1], *err = NULL;
int linenum = 0;
sds line = NULL;

if (filename[0] == '-' && filename[1] == '\0')
fp = stdin;
else {
if ((fp = fopen(filename,"r")) == NULL) {
redisLog(REDIS_WARNING, "Fatal error, can't open config file '%s'", filename);
exit(1);
}
}
void loadServerConfigFromString(char *config) {
char *err = NULL;
int linenum = 0, totlines, i;
sds *lines;

lines = sdssplitlen(config,strlen(config),"\n",1,&totlines);

while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL) {
for (i = 0; i < totlines; i++) {
sds *argv;
int argc, j;
int argc;

linenum++;
line = sdsnew(buf);
line = sdstrim(line," \t\r\n");
linenum = i+1;
lines[i] = sdstrim(lines[i]," \t\r\n");

/* Skip comments and blank lines*/
if (line[0] == '#' || line[0] == '\0') {
sdsfree(line);
continue;
}
if (lines[i][0] == '#' || lines[i][0] == '\0') continue;

/* Split into arguments */
argv = sdssplitargs(line,&argc);
argv = sdssplitargs(lines[i],&argc);
sdstolower(argv[0]);

/* Execute config directives */
Expand Down Expand Up @@ -162,7 +148,7 @@ void loadServerConfig(char *filename) {
err = "Invalid number of databases"; goto loaderr;
}
} else if (!strcasecmp(argv[0],"include") && argc == 2) {
loadServerConfig(argv[1]);
loadServerConfig(argv[1],NULL);
} else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
server.maxclients = atoi(argv[1]);
} else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) {
Expand Down Expand Up @@ -325,22 +311,56 @@ void loadServerConfig(char *filename) {
} else {
err = "Bad directive or wrong number of arguments"; goto loaderr;
}
for (j = 0; j < argc; j++)
sdsfree(argv[j]);
zfree(argv);
sdsfree(line);
sdsfreesplitres(argv,argc);
}
if (fp != stdin) fclose(fp);
sdsfreesplitres(lines,totlines);
return;

loaderr:
fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR ***\n");
fprintf(stderr, "Reading the configuration file, at line %d\n", linenum);
fprintf(stderr, ">>> '%s'\n", line);
fprintf(stderr, ">>> '%s'\n", lines[i]);
fprintf(stderr, "%s\n", err);
exit(1);
}

/* Load the server configuration from the specified filename.
* The function appends the additional configuration directives stored
* in the 'options' string to the config file before loading.
*
* Both filename and options can be NULL, in such a case are considered
* emtpy. This way loadServerConfig can be used to just load a file or
* just load a string. */
void loadServerConfig(char *filename, char *options) {
sds config = sdsempty();
char buf[REDIS_CONFIGLINE_MAX+1];

/* Load the file content */
if (filename) {
FILE *fp;

if (filename[0] == '-' && filename[1] == '\0') {
fp = stdin;
} else {
if ((fp = fopen(filename,"r")) == NULL) {
redisLog(REDIS_WARNING,
"Fatal error, can't open config file '%s'", filename);
exit(1);
}
}
while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL)
config = sdscat(config,buf);
if (fp != stdin) fclose(fp);
}
/* Append the additional options */
if (options) {
config = sdscat(config,"\n");
config = sdscat(config,options);
}
loadServerConfigFromString(config);
sdsfree(config);
}

/*-----------------------------------------------------------------------------
* CONFIG command for remote configuration
*----------------------------------------------------------------------------*/
Expand Down
32 changes: 28 additions & 4 deletions src/redis.c
Expand Up @@ -2008,15 +2008,39 @@ int main(int argc, char **argv) {

zmalloc_enable_thread_safeness();
initServerConfig();
if (argc == 2) {
if (argc >= 2) {
int j = 1; /* First option to parse in argv[] */
sds options = sdsempty();
char *configfile = NULL;

/* Handle special options --help and --version */
if (strcmp(argv[1], "-v") == 0 ||
strcmp(argv[1], "--version") == 0) version();
if (strcmp(argv[1], "--help") == 0 ||
strcmp(argv[1], "-h") == 0) usage();
/* First argument is the config file name? */
if (argv[j][0] != '-' || argv[j][1] != '-')
configfile = argv[j++];
/* All the other options are parsed and conceptually appended to the
* configuration file. For instance --port 6380 will generate the
* string "port 6380\n" to be parsed after the actual file name
* is parsed, if any. */
while(j != argc) {
if (argv[j][0] == '-' && argv[j][1] == '-') {
/* Option name */
if (sdslen(options)) options = sdscat(options,"\n");
options = sdscat(options,argv[j]+2);
options = sdscat(options," ");
} else {
/* Option argument */
options = sdscatrepr(options,argv[j],strlen(argv[j]));
options = sdscat(options," ");
}
j++;
}
resetServerSaveParams();
loadServerConfig(argv[1]);
} else if ((argc > 2)) {
usage();
loadServerConfig(configfile,options);
sdsfree(options);
} else {
redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
}
Expand Down
2 changes: 1 addition & 1 deletion src/redis.h
Expand Up @@ -954,7 +954,7 @@ int listMatchPubsubPattern(void *a, void *b);
int pubsubPublishMessage(robj *channel, robj *message);

/* Configuration */
void loadServerConfig(char *filename);
void loadServerConfig(char *filename, char *options);
void appendServerSaveParams(time_t seconds, int changes);
void resetServerSaveParams();

Expand Down

0 comments on commit 67c6f0f

Please sign in to comment.