/** * Task run last to shut everything down. * * @param cls the 'struct GNUNET_FS_DirScanner' */ static void finish_scan (void *cls) { struct GNUNET_FS_DirScanner *ds = cls; ds->stop_task = NULL; if (NULL != ds->helper) { GNUNET_HELPER_stop (ds->helper, GNUNET_NO); ds->helper = NULL; } ds->progress_callback (ds->progress_callback_cls, NULL, GNUNET_SYSERR, GNUNET_FS_DIRSCANNER_FINISHED); }
/** * Abort the scan. Must not be called from within the progress_callback * function. * * @param ds directory scanner structure */ void GNUNET_FS_directory_scan_abort (struct GNUNET_FS_DirScanner *ds) { /* terminate helper */ if (NULL != ds->helper) GNUNET_HELPER_stop (ds->helper); /* free resources */ if (NULL != ds->toplevel) GNUNET_FS_share_tree_free (ds->toplevel); if (GNUNET_SCHEDULER_NO_TASK != ds->stop_task) GNUNET_SCHEDULER_cancel (ds->stop_task); GNUNET_free_non_null (ds->ex_arg); GNUNET_free (ds->filename_expanded); GNUNET_free (ds); }
/** * Task run last to shut everything down. * * @param cls the 'struct GNUNET_FS_DirScanner' * @param tc unused */ static void finish_scan (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_DirScanner *ds = cls; ds->stop_task = GNUNET_SCHEDULER_NO_TASK; if (NULL != ds->helper) { GNUNET_HELPER_stop (ds->helper); ds->helper = NULL; } ds->progress_callback (ds->progress_callback_cls, NULL, GNUNET_SYSERR, GNUNET_FS_DIRSCANNER_FINISHED); }
/** * Write to the helper-process * * @param cls handle to the helper process */ static void helper_write (void *cls) { struct GNUNET_HELPER_Handle *h = cls; struct GNUNET_HELPER_SendHandle *sh; const char *buf; ssize_t t; h->write_task = NULL; if (NULL == (sh = h->sh_head)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Helper write had no work!\n"); return; /* how did this happen? */ } buf = (const char*) sh->msg; t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[sh->wpos], ntohs (sh->msg->size) - sh->wpos); if (-1 == t) { /* On write-error, restart the helper */ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Error writing to `%s': %s\n"), h->binary_name, STRERROR (errno)); if (NULL != h->exp_cb) { h->exp_cb (h->cb_cls); GNUNET_HELPER_stop (h, GNUNET_NO); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping and restarting helper task!\n"); stop_helper (h, GNUNET_NO); /* Restart the helper */ h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, h->retry_back_off), &restart_task, h); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted %u bytes to %s\n", (unsigned int) t, h->binary_name); sh->wpos += t; if (sh->wpos == ntohs (sh->msg->size)) { GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); if (NULL != sh->cont) sh->cont (sh->cont_cls, GNUNET_YES); GNUNET_free (sh); } if (NULL != h->sh_head) h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, h->fh_to_helper, &helper_write, h); }
/** * Read from the helper-process * * @param cls handle to the helper process */ static void helper_read (void *cls) { struct GNUNET_HELPER_Handle *h = cls; char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE] GNUNET_ALIGN; ssize_t t; h->read_task = NULL; t = GNUNET_DISK_file_read (h->fh_from_helper, &buf, sizeof (buf)); if (t < 0) { /* On read-error, restart the helper */ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Error reading from `%s': %s\n"), h->binary_name, STRERROR (errno)); if (NULL != h->exp_cb) { h->exp_cb (h->cb_cls); GNUNET_HELPER_stop (h, GNUNET_NO); return; } stop_helper (h, GNUNET_NO); /* Restart the helper */ h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, h->retry_back_off), &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_DEBUG, "Got 0 bytes from helper `%s' (EOF)\n", h->binary_name); if (NULL != h->exp_cb) { h->exp_cb (h->cb_cls); GNUNET_HELPER_stop (h, GNUNET_NO); return; } stop_helper (h, GNUNET_NO); /* Restart the helper */ h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, h->retry_back_off), &restart_task, h); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "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)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to parse inbound message from helper `%s'\n"), h->binary_name); if (NULL != h->exp_cb) { h->exp_cb (h->cb_cls); GNUNET_HELPER_stop (h, GNUNET_NO); return; } stop_helper (h, GNUNET_NO); /* Restart the helper */ h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, h->retry_back_off), &restart_task, h); return; } }