-doxygen
[oweals/gnunet.git] / src / util / helper.c
index c47b201c575832cb33bfd62a2ba72affaa27c473..43ec23a88278e00cc65928eba3e7b69eb80a2e3a 100644 (file)
@@ -152,8 +152,8 @@ stop_helper (struct GNUNET_HELPER_Handle *h)
 
   if (NULL != h->helper_proc)
   {
-    GNUNET_OS_process_kill (h->helper_proc, SIGKILL);
-    GNUNET_OS_process_wait (h->helper_proc);
+    GNUNET_break (0 == GNUNET_OS_process_kill (h->helper_proc, SIGTERM));
+    GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (h->helper_proc));
     GNUNET_OS_process_close (h->helper_proc);
     h->helper_proc = NULL;
   }
@@ -189,11 +189,12 @@ stop_helper (struct GNUNET_HELPER_Handle *h)
     GNUNET_CONTAINER_DLL_remove (h->mq_head,
                                 h->mq_tail,
                                 qe);
-    qe->cont (qe->cont_cls, GNUNET_NO);
+    if (NULL != qe->cont)
+      qe->cont (qe->cont_cls, GNUNET_NO);
     GNUNET_free (qe);
   }
   /* purge MST buffer */
-  GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO);
+  (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO);
 }
 
 
@@ -216,14 +217,14 @@ restart_task (void *cls,
  */
 static void
 helper_read (void *cls,
-            const struct GNUNET_SCHEDULER_TaskContext *tsdkctx)
+            const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  struct GNUNET_HELPER_Handle*h = cls;
+  struct GNUNET_HELPER_Handle *h = cls;
   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE];
   ssize_t t;
 
   h->read_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
   {
     /* try again */
     h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -231,7 +232,7 @@ helper_read (void *cls,
     return;
   }
   t = GNUNET_DISK_file_read (h->fh_from_helper, &buf, sizeof (buf));
-  if (t <= 0)
+  if (t < 0)
   {
     /* On read-error, restart the helper */
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -245,6 +246,26 @@ helper_read (void *cls,
                                    &restart_task, h);
     return;
   }
+  if (0 == t)
+  {
+    /* this happens if the helper is shut down via a 
+       signal, so it is not a "hard" error */
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
+               _("Got 0 bytes from helper `%s' (EOF)\n"),
+               h->binary_name);
+    stop_helper (h);
+    /* Restart the helper */
+    h->restart_task =
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+                                   &restart_task, h);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
+             _("Got %u bytes from helper `%s'\n"),
+             (unsigned int) t,
+             h->binary_name);
+  h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                                h->fh_from_helper, &helper_read, h);
   if (GNUNET_SYSERR ==
       GNUNET_SERVER_mst_receive (h->mst, NULL, buf, t, GNUNET_NO, GNUNET_NO))
   {
@@ -257,10 +278,7 @@ helper_read (void *cls,
         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                       &restart_task, h);
     return;
-
   }
-  h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                h->fh_from_helper, &helper_read, h);
 }
 
 
@@ -272,8 +290,8 @@ helper_read (void *cls,
 static void
 start_helper (struct GNUNET_HELPER_Handle *h)
 {
-  h->helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
-  h->helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
+  h->helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
+  h->helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
   if ( (h->helper_in == NULL) || (h->helper_out == NULL))
   {
     /* out of file descriptors? try again later... */
@@ -285,12 +303,11 @@ start_helper (struct GNUNET_HELPER_Handle *h)
   }
   h->fh_from_helper =
       GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ);
-  GNUNET_DISK_pipe_close_end (h->helper_out, GNUNET_DISK_PIPE_END_WRITE);
   h->fh_to_helper =
       GNUNET_DISK_pipe_handle (h->helper_in, GNUNET_DISK_PIPE_END_WRITE);
-  GNUNET_DISK_pipe_close_end (h->helper_in, GNUNET_DISK_PIPE_END_READ);
   h->helper_proc =
-      GNUNET_OS_start_process_vap (h->helper_in, h->helper_out,
+      GNUNET_OS_start_process_vap (GNUNET_NO,
+                                  h->helper_in, h->helper_out,
                                   h->binary_name,
                                   h->binary_argv);
   if (NULL == h->helper_proc)
@@ -302,6 +319,8 @@ start_helper (struct GNUNET_HELPER_Handle *h)
                                    &restart_task, h);    
     return;
   }
+  GNUNET_DISK_pipe_close_end (h->helper_out, GNUNET_DISK_PIPE_END_WRITE);
+  GNUNET_DISK_pipe_close_end (h->helper_in, GNUNET_DISK_PIPE_END_READ);
   h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                                 h->fh_from_helper, 
                                                 &helper_read, 
@@ -369,7 +388,8 @@ GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h)
     GNUNET_CONTAINER_DLL_remove (h->mq_head,
                                 h->mq_tail,
                                 qe);
-    qe->cont (qe->cont_cls, GNUNET_SYSERR);
+    if (NULL != qe->cont)
+      qe->cont (qe->cont_cls, GNUNET_SYSERR);
     GNUNET_free (qe);
   }
   stop_helper (h);
@@ -386,7 +406,7 @@ GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h)
  */
 static void
 helper_write (void *cls,
-            const struct GNUNET_SCHEDULER_TaskContext *tsdkctx)
+            const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_HELPER_Handle *h = cls;
   struct HelperMessageQueueEntry *qe;
@@ -394,7 +414,7 @@ helper_write (void *cls,
   ssize_t t;
 
   h->write_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
   {
     /* try again */
     h->write_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -459,6 +479,8 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h,
   struct HelperMessageQueueEntry *qe;
   uint16_t mlen;
 
+  if (NULL == h->fh_to_helper)
+    return GNUNET_NO;
   if ( (GNUNET_YES == can_drop) &&
        (h->mq_head != NULL) )
     return GNUNET_NO;