]> git.saurik.com Git - redis.git/commitdiff
Support for command line configuration options for redis-server.
authorantirez <antirez@gmail.com>
Thu, 1 Dec 2011 12:44:53 +0000 (13:44 +0100)
committerantirez <antirez@gmail.com>
Thu, 1 Dec 2011 12:44:53 +0000 (13:44 +0100)
src/config.c
src/redis.c
src/redis.h

index 9f71aaf6396ab215eb9a0ef2454c254785b7c888..acda67bb74c98870f228f6c290897c53c5f5aca0 100644 (file)
@@ -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 */
@@ -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) {
@@ -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
  *----------------------------------------------------------------------------*/
index 3c287756dbfc967b5ef95fec67c2792f38a4e652..30ba1bce85c7f0af3c3b0d2085fae9f1bcae2a47 100644 (file)
@@ -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'");
     }
index 431eeb1404b16487a35631ac54381c333ed2b1ec..c425691edc4b5e04dcd31fe3fd301ff9f99ae865 100644 (file)
@@ -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();