gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r22074 - gnunet/src/fs


From: gnunet
Subject: [GNUnet-SVN] r22074 - gnunet/src/fs
Date: Mon, 18 Jun 2012 12:06:40 +0200

Author: grothoff
Date: 2012-06-18 12:06:40 +0200 (Mon, 18 Jun 2012)
New Revision: 22074

Modified:
   gnunet/src/fs/gnunet-auto-share.c
Log:
-adding logic for starting gnunet-publish

Modified: gnunet/src/fs/gnunet-auto-share.c
===================================================================
--- gnunet/src/fs/gnunet-auto-share.c   2012-06-18 09:46:40 UTC (rev 22073)
+++ gnunet/src/fs/gnunet-auto-share.c   2012-06-18 10:06:40 UTC (rev 22074)
@@ -21,6 +21,9 @@
  * @file fs/gnunet-auto-share.c
  * @brief automatically publish files on GNUnet
  * @author Christian Grothoff
+ * 
+ * TODO:
+ * - support loading meta data / keywords from resource file
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
@@ -72,6 +75,11 @@
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 /**
+ * Name of the configuration file.
+ */
+static char *cfg_filename;
+
+/**
  * Disable extractor option to use for publishing.
  */
 static int disable_extractor;
@@ -139,8 +147,18 @@
  */
 static struct GNUNET_TIME_Absolute start_time;
 
+/**
+ * Pipe used to communicate 'gnunet-publish' completion (SIGCHLD) via signal.
+ */
+static struct GNUNET_DISK_PipeHandle *sigpipe;
 
 /**
+ * Handle to the 'gnunet-publish' process that we executed.
+ */
+static struct GNUNET_OS_Process *publish_proc;
+
+
+/**
  * Compute the name of the state database file we will use.
  */
 static char *
@@ -284,6 +302,11 @@
 {
   kill_task = GNUNET_SCHEDULER_NO_TASK;
   do_shutdown = GNUNET_YES;
+  if (NULL != publish_proc)
+  {
+    GNUNET_OS_process_kill (publish_proc, SIGKILL);
+    return;
+  }
   if (GNUNET_SCHEDULER_NO_TASK != run_task)
   {
     GNUNET_SCHEDULER_cancel (run_task);
@@ -300,25 +323,23 @@
 
 
 /**
- * Function called to process work items.
+ * Task triggered whenever we receive a SIGCHLD (child
+ * process died).
  *
- * @param cls closure, NULL
- * @param tc scheduler context (unused)
+ * @param cls the 'struct WorkItem' we were working on
+ * @param tc context
  */
 static void
-work (void *cls,
-      const struct GNUNET_SCHEDULER_TaskContext *tc)
+maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  struct WorkItem *wi;
+  struct WorkItem *wi = cls;
   struct GNUNET_HashCode key;
 
   run_task = GNUNET_SCHEDULER_NO_TASK;
-  wi = work_head;
-  GNUNET_CONTAINER_DLL_remove (work_head,
-                              work_tail,
-                              wi);
-  // FIXME: actually run 'publish' here!
-
+  GNUNET_break (GNUNET_OK ==
+               GNUNET_OS_process_wait (publish_proc));
+  GNUNET_OS_process_destroy (publish_proc);
+  publish_proc = NULL;
   GNUNET_CRYPTO_hash (wi->filename,
                      strlen (wi->filename),
                      &key);
@@ -332,6 +353,95 @@
 
 
 /**
+ * Signal handler called for SIGCHLD.  Triggers the
+ * respective handler by writing to the trigger pipe.
+ */
+static void
+sighandler_child_death ()
+{
+  static char c;
+  int old_errno = errno;       /* back-up errno */
+
+  GNUNET_break (1 ==
+               GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
+                                       (sigpipe, GNUNET_DISK_PIPE_END_WRITE),
+                                       &c, sizeof (c)));
+  errno = old_errno;           /* restore errno */
+}
+
+
+/**
+ * Function called to process work items.
+ *
+ * @param cls closure, NULL
+ * @param tc scheduler context (unused)
+ */
+static void
+work (void *cls,
+      const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  static char *argv[14];
+  static char anon_level[20];
+  static char content_prio[20];
+  static char repl_level[20];
+  struct WorkItem *wi;
+  const struct GNUNET_DISK_FileHandle *pr;  
+  int argc;
+
+  run_task = GNUNET_SCHEDULER_NO_TASK;
+  wi = work_head;
+  GNUNET_CONTAINER_DLL_remove (work_head,
+                              work_tail,
+                              wi);
+  argc = 0;
+  argv[argc++] = "gnunet-publish";
+  if (verbose)
+    argv[argc++] = "-V";
+  if (disable_extractor)
+    argv[argc++] = "-D";
+  if (do_disable_creation_time)
+    argv[argc++] = "-d";
+  argv[argc++] = "-c";
+  argv[argc++] = cfg_filename;
+  GNUNET_snprintf (anon_level, sizeof (anon_level),
+                  "%u", anonymity_level);
+  argv[argc++] = "-a";
+  argv[argc++] = anon_level;
+  GNUNET_snprintf (content_prio, sizeof (content_prio),
+                  "%u", content_priority);
+  argv[argc++] = "-p";
+  argv[argc++] = content_prio;
+  GNUNET_snprintf (repl_level, sizeof (repl_level),
+                  "%u", replication_level);
+  argv[argc++] = "-r";
+  argv[argc++] = repl_level;
+  argv[argc++] = wi->filename;
+  argv[argc] = NULL;
+  publish_proc = GNUNET_OS_start_process_vap (GNUNET_YES,
+                                             NULL, NULL,
+                                             "gnunet-publish",
+                                             argv);
+  if (NULL == publish_proc)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               _("Failed to run `%s'\n"),
+               "gnunet-publish");
+    GNUNET_CONTAINER_DLL_insert (work_head,
+                                work_tail,
+                                wi);
+    run_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
+                                            &work,
+                                            NULL);
+    return;
+  }
+  pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
+  run_task =
+    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                   pr, &maint_child_death, wi);
+}
+
+
+/**
  * Recursively scan the given file/directory structure to determine
  * a unique ID that represents the current state of the hierarchy.
  *
@@ -502,6 +612,7 @@
     ret = -1;
     return;
   }
+  cfg_filename = GNUNET_strdup (cfgfile);
   cfg = c;
   dir_name = args[0];
   work_finished = GNUNET_CONTAINER_multihashmap_create (1024);
@@ -569,9 +680,14 @@
   };
   struct WorkItem *wi;
   int ok;
+  struct GNUNET_SIGNAL_Context *shc_chld;
 
   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
     return 2;
+  sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
+  GNUNET_assert (sigpipe != NULL);
+  shc_chld =
+    GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
   ok = (GNUNET_OK ==
        GNUNET_PROGRAM_run (argc, argv, "gnunet-auto-share [OPTIONS] FILENAME",
                            gettext_noop
@@ -587,6 +703,12 @@
     GNUNET_free (wi->filename);
     GNUNET_free (wi);
   }
+  GNUNET_SIGNAL_handler_uninstall (shc_chld);
+  shc_chld = NULL;
+  GNUNET_DISK_pipe_close (sigpipe);
+  sigpipe = NULL;
+  GNUNET_free (cfg_filename);
+  cfg_filename = NULL;
   return ok;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]