[tor-commits] [tor/master] Add a return type for the parsed commandline.

nickm at torproject.org nickm at torproject.org
Thu Oct 17 16:01:55 UTC 2019


commit 9826fb19815794507cbc55358439758fbf700291
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Oct 8 11:47:43 2019 -0400

    Add a return type for the parsed commandline.
    
    Previously it was stored in two outvars, but this is more
    elegant. I'm going to be expanding this struct in later commits.
---
 src/app/config/config.c | 89 ++++++++++++++++++++++++++-----------------------
 src/app/config/config.h | 17 ++++++++--
 src/app/main/main.c     | 14 ++++----
 3 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/src/app/config/config.c b/src/app/config/config.c
index 1abe1e13a..74cd70ad3 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -885,12 +885,8 @@ static or_options_t *global_default_options = NULL;
 static char *torrc_fname = NULL;
 /** Name of the most recently read torrc-defaults file.*/
 static char *torrc_defaults_fname = NULL;
-/** Configuration options set by command line. */
-static config_line_t *global_cmdline_options = NULL;
-/** Non-configuration options set by the command line */
-static config_line_t *global_cmdline_only_options = NULL;
-/** Boolean: Have we parsed the command line? */
-static int have_parsed_cmdline = 0;
+/** Result of parsing the command line. */
+static parsed_cmdline_t *global_cmdline = NULL;
 /** Contents of most recently read DirPortFrontPage file. */
 static char *global_dirfrontpagecontents = NULL;
 /** List of port_cfg_t for all configured ports. */
@@ -1064,11 +1060,7 @@ config_free_all(void)
   or_options_free(global_default_options);
   global_default_options = NULL;
 
-  config_free_lines(global_cmdline_options);
-  global_cmdline_options = NULL;
-
-  config_free_lines(global_cmdline_only_options);
-  global_cmdline_only_options = NULL;
+  parsed_cmdline_free(global_cmdline);
 
   if (configured_ports) {
     SMARTLIST_FOREACH(configured_ports,
@@ -1083,7 +1075,6 @@ config_free_all(void)
 
   cleanup_protocol_warning_severity_level();
 
-  have_parsed_cmdline = 0;
   libevent_initialized = 0;
 
   config_mgr_free(options_mgr);
@@ -2459,8 +2450,12 @@ typedef enum {
   ARGUMENT_OPTIONAL = 2
 } takes_argument_t;
 
+/** Table describing arguments that Tor accepts on the command line,
+ * other than those that are the same as in torrc. */
 static const struct {
+  /** The string that the user has to provide. */
   const char *name;
+  /** Does this option accept an argument? */
   takes_argument_t takes_argument;
 } CMDLINE_ONLY_OPTIONS[] = {
   { .name="-f",
@@ -2497,22 +2492,20 @@ static const struct {
 };
 
 /** Helper: Read a list of configuration options from the command line.  If
- * successful, or if ignore_errors is set, put them in *<b>result</b>, put the
- * commandline-only options in *<b>cmdline_result</b>, and return 0;
- * otherwise, return -1 and leave *<b>result</b> and <b>cmdline_result</b>
- * alone. */
-int
-config_parse_commandline(int argc, char **argv, int ignore_errors,
-                         config_line_t **result,
-                         config_line_t **cmdline_result)
+ * successful, return a newly allocated parsed_cmdline_t; otherwise return
+ * NULL.
+ *
+ * If <b>ignore_errors</b> is set, try to recover from all recoverable
+ * errors and return the best command line we can.
+ */
+parsed_cmdline_t *
+config_parse_commandline(int argc, char **argv, int ignore_errors)
 {
+  parsed_cmdline_t *result = tor_malloc_zero(sizeof(parsed_cmdline_t));
   config_line_t *param = NULL;
 
-  config_line_t *front = NULL;
-  config_line_t **new = &front;
-
-  config_line_t *front_cmdline = NULL;
-  config_line_t **new_cmdline = &front_cmdline;
+  config_line_t **new_cmdline = &result->cmdline_opts;
+  config_line_t **new = &result->other_opts;
 
   char *s, *arg;
   int i = 1;
@@ -2557,9 +2550,8 @@ config_parse_commandline(int argc, char **argv, int ignore_errors,
       } else {
         log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
             argv[i]);
-        config_free_lines(front);
-        config_free_lines(front_cmdline);
-        return -1;
+        parsed_cmdline_free(result);
+        return NULL;
       }
     } else if (want_arg == ARGUMENT_OPTIONAL && is_last) {
       arg = tor_strdup("");
@@ -2587,9 +2579,19 @@ config_parse_commandline(int argc, char **argv, int ignore_errors,
 
     i += want_arg ? 2 : 1;
   }
-  *cmdline_result = front_cmdline;
-  *result = front;
-  return 0;
+
+  return result;
+}
+
+/** Release all storage held by <b>cmdline</b>. */
+void
+parsed_cmdline_free_(parsed_cmdline_t *cmdline)
+{
+  if (!cmdline)
+    return;
+  config_free_lines(cmdline->cmdline_opts);
+  config_free_lines(cmdline->other_opts);
+  tor_free(cmdline);
 }
 
 /** Return true iff key is a valid configuration option. */
@@ -5199,24 +5201,20 @@ int
 options_init_from_torrc(int argc, char **argv)
 {
   char *cf=NULL, *cf_defaults=NULL;
-  int command;
   int retval = -1;
-  char *command_arg = NULL;
   char *errmsg=NULL;
-  config_line_t *p_index = NULL;
-  config_line_t *cmdline_only_options = NULL;
+  const config_line_t *cmdline_only_options;
 
   /* Go through command-line variables */
-  if (! have_parsed_cmdline) {
+  if (global_cmdline == NULL) {
     /* Or we could redo the list every time we pass this place.
      * It does not really matter */
-    if (config_parse_commandline(argc, argv, 0, &global_cmdline_options,
-                                 &global_cmdline_only_options) < 0) {
+    global_cmdline = config_parse_commandline(argc, argv, 0);
+    if (global_cmdline == NULL) {
       goto err;
     }
-    have_parsed_cmdline = 1;
   }
-  cmdline_only_options = global_cmdline_only_options;
+  cmdline_only_options = global_cmdline->cmdline_opts;
 
   if (config_line_find(cmdline_only_options, "-h") ||
       config_line_find(cmdline_only_options, "--help")) {
@@ -5465,8 +5463,15 @@ options_init_from_string(const char *cf_defaults, const char *cf,
   }
 
   /* Go through command-line variables too */
-  retval = config_assign(get_options_mgr(), newoptions,
-                         global_cmdline_options, CAL_WARN_DEPRECATIONS, msg);
+  {
+    config_line_t *other_opts = NULL;
+    if (global_cmdline) {
+      other_opts = global_cmdline->other_opts;
+    }
+    retval = config_assign(get_options_mgr(), newoptions,
+                           other_opts,
+                           CAL_WARN_DEPRECATIONS, msg);
+  }
   if (retval < 0) {
     err = SETOPT_ERR_PARSE;
     goto err;
diff --git a/src/app/config/config.h b/src/app/config/config.h
index 44f09e5ee..fe4e272d8 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -197,9 +197,20 @@ int init_cookie_authentication(const char *fname, const char *header,
 
 or_options_t *options_new(void);
 
-int config_parse_commandline(int argc, char **argv, int ignore_errors,
-                             struct config_line_t **result,
-                             struct config_line_t **cmdline_result);
+/** Options settings parsed from the command-line. */
+typedef struct {
+  /** List of options that can only be set from the command-line */
+  struct config_line_t *cmdline_opts;
+  /** List of other options, to be handled by the general Tor configuration
+      system. */
+  struct config_line_t *other_opts;
+} parsed_cmdline_t;
+
+parsed_cmdline_t *config_parse_commandline(int argc, char **argv,
+                                           int ignore_errors);
+void parsed_cmdline_free_(parsed_cmdline_t *cmdline);
+#define parsed_cmdline_free(c) \
+  FREE_AND_NULL(parsed_cmdline_t, parsed_cmdline_free_, (c))
 
 void config_register_addressmaps(const or_options_t *options);
 /* XXXX move to connection_edge.h */
diff --git a/src/app/main/main.c b/src/app/main/main.c
index 3bdf8f146..0edda66fd 100644
--- a/src/app/main/main.c
+++ b/src/app/main/main.c
@@ -549,10 +549,13 @@ tor_init(int argc, char *argv[])
   {
   /* We search for the "quiet" option first, since it decides whether we
    * will log anything at all to the command line. */
-    config_line_t *opts = NULL, *cmdline_opts = NULL;
-    const config_line_t *cl;
-    (void) config_parse_commandline(argc, argv, 1, &opts, &cmdline_opts);
-    for (cl = cmdline_opts; cl; cl = cl->next) {
+    parsed_cmdline_t *cmdline;
+    const config_line_t *cl = NULL;
+    cmdline = config_parse_commandline(argc, argv, 1);
+    if (cmdline != NULL) {
+      cl = cmdline->cmdline_opts;
+    }
+    for (; cl; cl = cl->next) {
       if (!strcmp(cl->key, "--hush"))
         quiet = 1;
       if (!strcmp(cl->key, "--quiet") ||
@@ -569,8 +572,7 @@ tor_init(int argc, char *argv[])
           quiet = 1;
       }
     }
-    config_free_lines(opts);
-    config_free_lines(cmdline_opts);
+    parsed_cmdline_free(cmdline);
   }
 
  /* give it somewhere to log to initially */





More information about the tor-commits mailing list