cleaning up arm wrt processing options and prefixes
authorChristian Grothoff <christian@grothoff.org>
Wed, 10 Mar 2010 16:01:09 +0000 (16:01 +0000)
committerChristian Grothoff <christian@grothoff.org>
Wed, 10 Mar 2010 16:01:09 +0000 (16:01 +0000)
src/arm/Makefile.am
src/arm/arm_api.c
src/arm/do_start_process.c [new file with mode: 0644]
src/arm/gnunet-service-arm.c
src/arm/test_arm_api_data.conf
src/arm/test_exponential_backoff.c

index 8cd9cc0dbad0bfb1e3a761c98ca0000a26371ef6..f9c2a3289ee4481932b15300e8d246bfea1dbe8b 100644 (file)
@@ -68,4 +68,5 @@ test_exponential_backoff_LDADD = \
   $(top_builddir)/src/util/libgnunetutil.la
 
 EXTRA_DIST = \
-  test_arm_api_data.conf
+  test_arm_api_data.conf \
+  do_start_process.c
index 847d838cd0a93589d51f2bc59223a054d06677af..138c95df472b3f89c54d7882a85ac46c37152144 100644 (file)
@@ -143,6 +143,8 @@ struct RequestContext
 
 };
 
+#include "do_start_process.c"
+
 
 /**
  * A client specifically requested starting of ARM itself.
@@ -161,6 +163,8 @@ arm_service_report (void *cls,
   pid_t pid;
   char *binary;
   char *config;
+  char *loprefix;
+  char *lopostfix;
 
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
     {
@@ -181,9 +185,15 @@ arm_service_report (void *cls,
              "gnunet-service-arm");
 #endif
   /* FIXME: should we check that HOSTNAME for 'arm' is localhost? */
-  /* FIXME: interpret 'PREFIX' and 'OPTIONS' configuration options
-     (as done by 'gnunet-service-arm.c::start_process') */
-  /* start service */
+
+ if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (pos->h->cfg,
+                                            "arm", "PREFIX", &loprefix))
+    loprefix = GNUNET_strdup ("");
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (pos->h->cfg,
+                                            "arm", "OPTIONS", &lopostfix))
+    lopostfix = GNUNET_strdup ("");
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (pos->h->cfg,
                                             "arm",
@@ -197,6 +207,8 @@ arm_service_report (void *cls,
       if (pos->callback != NULL)
         pos->callback (pos->cls, GNUNET_SYSERR);
       GNUNET_free (pos);
+      GNUNET_free (loprefix);
+      GNUNET_free (lopostfix);
       return;
     }
   if (GNUNET_OK !=
@@ -211,15 +223,23 @@ arm_service_report (void *cls,
         pos->callback (pos->cls, GNUNET_SYSERR);
       GNUNET_free (binary);
       GNUNET_free (pos);
+      GNUNET_free (loprefix);
+      GNUNET_free (lopostfix);
       return;
     }
-  pid = GNUNET_OS_start_process (NULL, NULL, binary, binary, "-d", "-c", config,
+  pid = do_start_process (loprefix,
+                         binary, 
+                         "-c", config, 
 #if DEBUG_ARM
-                                 "-L", "DEBUG",
+                         "-L", "DEBUG",
 #endif
-                                 NULL);
+                         "-d",
+                         lopostfix,
+                         NULL);
   GNUNET_free (binary);
   GNUNET_free (config);
+  GNUNET_free (loprefix);
+  GNUNET_free (lopostfix);
   if (pid == -1)
     {
       if (pos->callback != NULL)
diff --git a/src/arm/do_start_process.c b/src/arm/do_start_process.c
new file mode 100644 (file)
index 0000000..357d399
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * Actually start a process.  All of the arguments given to this
+ * function are strings that are used for the "argv" array.  However,
+ * if those strings contain spaces, the given argument is split into
+ * multiple argv entries without spaces.  Similarly, if an argument is
+ * the empty string, it is skipped.  This function has the inherent
+ * limitation that it does NOT allow passing command line arguments
+ * with spaces to the new process.
+ *
+ * @param first_arg first argument for argv (may be an empty string)
+ * @param ... more arguments, NULL terminated
+ * @return PID of the started process, -1 on error
+ */
+static pid_t
+do_start_process (const char *first_arg, ...)
+{
+  va_list ap;
+  char **argv;
+  unsigned int argv_size;
+  const char *arg;
+  const char *rpos;
+  char *pos;
+  char *cp;
+  const char *last;
+  pid_t pid;
+
+  argv_size = 1;
+  va_start (ap, first_arg);
+  arg = first_arg;
+  last = NULL;
+  do
+    {
+      rpos = arg;
+      while ('\0' != *rpos)
+       {
+         if (' ' == *rpos)
+           {
+             if (last != NULL)
+               argv_size++;
+             last = NULL;
+             while (' ' == *rpos)
+               rpos++;
+           } 
+         if ( (last == NULL) && (*rpos != '\0') )
+           last = rpos;
+         if (*rpos != '\0')
+           rpos++;
+       }      
+      if (last != NULL)
+       argv_size++;
+    }
+  while (NULL != (arg = (va_arg (ap, const char*))));
+  va_end (ap);
+
+  argv = GNUNET_malloc (argv_size * sizeof (char *));
+  argv_size = 0;
+  va_start (ap, first_arg);
+  arg = first_arg;
+  last = NULL;
+  do
+    {
+      cp = GNUNET_strdup (arg);
+      pos = cp;
+      while ('\0' != *pos)
+       {
+         if (' ' == *pos)
+           {
+             *pos = '\0';
+             if (last != NULL)
+               argv[argv_size++] = GNUNET_strdup (last);
+             last = NULL;
+             pos++;
+             while (' ' == *pos)
+               pos++;
+           }
+         if ( (last == NULL) && (*pos != '\0') ) 
+           last = pos;
+         if (*pos != '\0')
+           pos++;
+       }
+      if (last != NULL)
+       argv[argv_size++] = GNUNET_strdup (last);
+      last = NULL;
+      GNUNET_free (cp);
+    }
+  while (NULL != (arg = (va_arg (ap, const char*))));
+  va_end (ap);
+  argv[argv_size] = NULL;
+  pid = GNUNET_OS_start_process_v (argv[0], argv);
+  while (argv_size > 0)
+    GNUNET_free (argv[--argv_size]);
+  GNUNET_free (argv);
+  return pid;
+}
index acef4a1e1be0ae2eb474b0864d841e374ef2f8c2..e5f97498b4fc603d13959e3d9d4ae0d81e7de2a7 100644 (file)
@@ -344,6 +344,7 @@ free_entry (struct ServiceList *pos)
   GNUNET_free (pos);
 }
 
+#include "do_start_process.c"
 
 /**
  * Actually start the process for the given service.
@@ -354,13 +355,8 @@ static void
 start_process (struct ServiceList *sl)
 {
   char *loprefix;
-  char *lopostfix;
   char *options;
-  char **argv;
-  unsigned int argv_size;
-  char *lopos;
   char *optpos;
-  const char *firstarg;
   int use_debug;
 
   /* start service */
@@ -372,7 +368,7 @@ start_process (struct ServiceList *sl)
       GNUNET_CONFIGURATION_get_value_string (cfg,
                                             sl->name, "OPTIONS", &options))
     {      
-      options = GNUNET_strdup (lopostfix);
+      options = GNUNET_strdup (final_option);
       /* replace '{}' with service name */
       if (NULL == strstr (options, "%"))
        {
@@ -396,75 +392,22 @@ start_process (struct ServiceList *sl)
              "Starting service `%s' using binary `%s' and configuration `%s'\n",
              sl->name, sl->binary, sl->config);
 #endif
-  argv_size = 6;
-  if (use_debug)
-    argv_size += 2;
-  lopos = loprefix;
-  while ('\0' != *lopos)
-    {
-      if (*lopos == ' ')
-       argv_size++;
-      lopos++;
-    }
-  optpos = options;
-  while ('\0' != *optpos)
-    {
-      if (*optpos == ' ')
-       argv_size++;
-      optpos++;
-    }
-  firstarg = NULL;
-  argv = GNUNET_malloc (argv_size * sizeof (char *));
-  argv_size = 0;
-  lopos = loprefix;
-
-  while ('\0' != *lopos)
-    {
-      while (*lopos == ' ')
-       lopos++;
-      if (*lopos == '\0')
-       continue;
-      if (argv_size == 0)
-       firstarg = lopos;
-      argv[argv_size++] = lopos;
-      while (('\0' != *lopos) && (' ' != *lopos))
-       lopos++;
-      if ('\0' == *lopos)
-       continue;
-      *lopos = '\0';
-      lopos++;
-    }
-  if (argv_size == 0)
-    firstarg = sl->binary;
-  argv[argv_size++] = sl->binary;
-  argv[argv_size++] = "-c";
-  argv[argv_size++] = sl->config;
   if (GNUNET_YES == use_debug)
-    {
-      argv[argv_size++] = "-L";
-      argv[argv_size++] = "DEBUG";
-    }
-  optpos = options;
-  while ('\0' != *optpos)
-    {
-      while (*optpos == ' ')
-       optpos++;
-      if (*optpos == '\0')
-       continue;
-      argv[argv_size++] = optpos;
-      while (('\0' != *optpos) && (' ' != *optpos))
-       optpos++;
-      if ('\0' == *optpos)
-       continue;
-      *optpos = '\0';
-      optpos++;
-    }
-  argv[argv_size] = NULL;
-  sl->pid = GNUNET_OS_start_process_v (firstarg, argv);
-  /* FIXME: should check sl->pid */
-  GNUNET_free (argv);
+    sl->pid = do_start_process (loprefix,
+                               sl->binary,
+                               "-c", sl->config,
+                               "-L", "DEBUG",
+                               options,
+                               NULL);
+  else
+    sl->pid = do_start_process (loprefix,
+                               sl->binary,
+                               "-c", sl->config,
+                               options,
+                               NULL);
   GNUNET_free (loprefix);
   GNUNET_free (options);
+  /* FIXME: should check sl->pid */
 }
 
 
index bdacfd4761c18dd4490e7f6c06de3e047bde1b70..17a8ac613e4265b84848c922731a55f152761b24 100644 (file)
@@ -11,6 +11,7 @@ OPTIONS = -L ERROR
 
 [resolver]
 #DEBUG = YES
+PORT = 23355
 
 [do-nothing]
 #DEBUG = YES
index a3dcd9c99707a2541fdc25db4c7c2b9b462a3d04..425e6bd8d0f9e8c067f62f89ca7728791a62e8d5 100644 (file)
@@ -248,8 +248,6 @@ main (int argc, char *argv[])
 {
   int ret;
 
-  fprintf (stdout,
-          "This test will print some warnings about 'do-nothing' being terminated.  That's expected!\n");
   GNUNET_log_setup ("test-exponential-backoff",
 #if VERBOSE
                     "DEBUG",