示例#1
0
/**
 * Task triggered whenever we receive a SIGCHLD (child
 * process died).
 *
 * @param cls closure, NULL if we need to self-restart
 * @param tc context
 */
static void
child_death_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  const struct GNUNET_DISK_FileHandle *pr;
  char c[16];

  pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
  child_death_task_id = NULL;
  if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
  {
    child_death_task_id =
	GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
					pr, &child_death_task, NULL);
    return;
  }
  /* consume the signal */
  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
  LOG_DEBUG ("Child died\n");
  GNUNET_SCHEDULER_cancel (terminate_task_id);
  terminate_task_id = NULL;
  GNUNET_assert (GNUNET_OK == GNUNET_OS_process_status (child, &child_status,
                                                        &child_exit_code));
  GNUNET_OS_process_destroy (child);
  child = NULL;
  shutdown_task_id = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
}
static void
read_call (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  int bytes;

  bytes = GNUNET_DISK_file_read (rc.stdout_read_handle, &rc.buf[rc.buf_offset], \
      sizeof (rc.buf) - rc.buf_offset);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "bytes is %d\n", bytes);

  if (bytes < 1)
  {
    GNUNET_break (0);
    ok = 1;
    GNUNET_SCHEDULER_cancel (die_task);
    GNUNET_SCHEDULER_add_now (&end_task, NULL);
    return;
  }

  ok = strncmp (rc.buf, test_phrase, strlen (test_phrase));
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "read %s\n", &rc.buf[rc.buf_offset]);
  rc.buf_offset += bytes;

  if (0 == ok)
  {
    GNUNET_SCHEDULER_cancel (die_task);
    GNUNET_SCHEDULER_add_now (&end_task, NULL);
    return;
  }

  GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                  rc.stdout_read_handle, &read_call,
                                  NULL);

}
static void
run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  char *fn;
  const struct GNUNET_DISK_FileHandle *stdout_read_handle;
  const struct GNUNET_DISK_FileHandle *wh;

#if !WINDOWS
  GNUNET_asprintf (&fn, "cat");
#else
  GNUNET_asprintf (&fn, "w32cat");
#endif

  hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
  hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);

  if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL))
  {
    GNUNET_break (0);
    ok = 1;
    GNUNET_free (fn);
    return;
  }

  proc =
      GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, hello_pipe_stdin, hello_pipe_stdout, fn,
                               "test_gnunet_echo_hello", "-", NULL);
  GNUNET_free (fn);

  /* Close the write end of the read pipe */
  GNUNET_DISK_pipe_close_end (hello_pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);
  /* Close the read end of the write pipe */
  GNUNET_DISK_pipe_close_end (hello_pipe_stdin, GNUNET_DISK_PIPE_END_READ);

  wh = GNUNET_DISK_pipe_handle (hello_pipe_stdin, GNUNET_DISK_PIPE_END_WRITE);

  /* Write the test_phrase to the cat process */
  if (GNUNET_DISK_file_write (wh, test_phrase, strlen (test_phrase) + 1) !=
      strlen (test_phrase) + 1)
  {
    GNUNET_break (0);
    ok = 1;
    return;
  }

  /* Close the write end to end the cycle! */
  GNUNET_DISK_pipe_close_end (hello_pipe_stdin, GNUNET_DISK_PIPE_END_WRITE);

  stdout_read_handle =
      GNUNET_DISK_pipe_handle (hello_pipe_stdout, GNUNET_DISK_PIPE_END_READ);

  die_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                    (GNUNET_TIME_UNIT_MINUTES, 1), &end_task,
                                    NULL);

  GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                  stdout_read_handle, &read_call,
                                  (void *) stdout_read_handle);
}
示例#4
0
/**
 * Main function that will be run by the scheduler.
 *
 * @param cls closure
 * @param args remaining command-line arguments
 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
 * @param cfg configuration
 */
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  const char *uri;
  const char *slash;
  char *subsystem;
  char *program;
  struct GNUNET_SCHEDULER_Task * rt;

  if (NULL == (uri = args[0]))
  {
    fprintf (stderr,
	     _("No URI specified on command line\n"));
    return;
  }
  if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://")))
  {
    fprintf (stderr,
	     _("Invalid URI: does not start with `%s'\n"),
	     "gnunet://");
    return;
  }
  uri += strlen ("gnunet://");
  if (NULL == (slash = strchr (uri, '/')))
  {
    fprintf (stderr, _("Invalid URI: fails to specify subsystem\n"));
    return;
  }
  subsystem = GNUNET_strndup (uri, slash - uri);
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_string (cfg,
					     "uri",
					     subsystem,
					     &program))
  {
    fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem);
    GNUNET_free (subsystem);
    return;
  }
  GNUNET_free (subsystem);
  rt = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
				       GNUNET_DISK_pipe_handle (sigpipe,
								GNUNET_DISK_PIPE_END_READ),
				       &maint_child_death, NULL);
  p = GNUNET_OS_start_process (GNUNET_NO, 0,
			       NULL, NULL, NULL,
			       program,
			       program,
			       args[0],
			       NULL);
  GNUNET_free (program);
  if (NULL == p)
    GNUNET_SCHEDULER_cancel (rt);
}
示例#5
0
文件: helper.c 项目: GNUnet/gnunet
/**
 * Start the helper process.
 *
 * @param h handle to the helper process
 */
static void
start_helper (struct GNUNET_HELPER_Handle *h)
{
  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... */
    stop_helper (h, GNUNET_NO);
    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,
	      "Starting HELPER process `%s'\n",
	      h->binary_name);
  h->fh_from_helper =
      GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ);
  h->fh_to_helper =
      GNUNET_DISK_pipe_handle (h->helper_in, GNUNET_DISK_PIPE_END_WRITE);
  h->helper_proc =
    GNUNET_OS_start_process_vap (h->with_control_pipe, GNUNET_OS_INHERIT_STD_ERR,
				 h->helper_in, h->helper_out, NULL,
				 h->binary_name,
				 h->binary_argv);
  if (NULL == h->helper_proc)
  {
    /* failed to start process? try again later... */
    stop_helper (h, GNUNET_NO);
    h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
										  h->retry_back_off),
						    &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);
  if (NULL != h->mst)
    h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
						   h->fh_from_helper,
						   &helper_read,
						   h);
}
示例#6
0
/**
 * Read the output of `external-ip` into `buf`.  When complete, parse
 * the address and call our callback.
 *
 * @param cls the `struct GNUNET_NAT_ExternalHandle`
 */
static void
read_external_ipv4 (void *cls)
{
  struct GNUNET_NAT_ExternalHandle *eh = cls;
  ssize_t ret;
  struct in_addr addr;

  eh->task = NULL;
  ret = GNUNET_DISK_file_read (eh->r,
			       &eh->buf[eh->off],
                               sizeof (eh->buf) - eh->off);
  if (ret > 0)
  {
    /* try to read more */
    eh->off += ret;
    eh->task 
      = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
					eh->r,
                                        &read_external_ipv4,
					eh);
    return;
  }
  eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID;
  if ( (eh->off > 7) &&
       (eh->buf[eh->off - 1] == '\n') )
  {
    eh->buf[eh->off - 1] = '\0';
    if (1 == inet_pton (AF_INET,
			eh->buf,
			&addr))
    {
      if (0 == addr.s_addr)
        eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID;       /* got 0.0.0.0 */
      else
        eh->ret = GNUNET_NAT_ERROR_SUCCESS;
    }
  }
  eh->cb (eh->cb_cls,
          (GNUNET_NAT_ERROR_SUCCESS == eh->ret) ? &addr : NULL,
          eh->ret);
  GNUNET_NAT_mini_get_external_ipv4_cancel_ (eh);
}
static void
read_call (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_DISK_FileHandle *stdout_read_handle = cls;
  char buf[16];

  memset (&buf, 0, sizeof (buf));
  int bytes;

  bytes = GNUNET_DISK_file_read (stdout_read_handle, &buf, sizeof (buf));

#if VERBOSE
  FPRINTF (stderr, "bytes is %d\n", bytes);
#endif

  if (bytes < 1)
  {
    GNUNET_break (0);
    ok = 1;
    GNUNET_SCHEDULER_cancel (die_task);
    GNUNET_SCHEDULER_add_now (&end_task, NULL);
    return;
  }

  ok = strncmp (&buf[0], test_phrase, strlen (test_phrase));
#if VERBOSE
  FPRINTF (stderr, "read %s\n", &buf[0]);
#endif
  if (ok == 0)
  {
    GNUNET_SCHEDULER_cancel (die_task);
    GNUNET_SCHEDULER_add_now (&end_task, NULL);
    return;
  }

  GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                  stdout_read_handle, &read_call,
                                  stdout_read_handle);

}
示例#8
0
/**
 * The main scheduler run task
 *
 * @param cls NULL
 * @param tc scheduler task context
 */
static void
run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_TESTBED_Host **hosts;
  const struct GNUNET_CONFIGURATION_Handle *null_cfg;
  char *tmpdir;
  char *hostname;
  size_t hostname_len;
  unsigned int nhosts;

  null_cfg = GNUNET_CONFIGURATION_create ();
  nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler (null_cfg, &hosts);
  if (0 == nhosts)
  {
    GNUNET_break (0);
    ret = GNUNET_SYSERR;
    return;
  }
  hostname_len = GNUNET_OS_get_hostname_max_length ();
  hostname = GNUNET_malloc (hostname_len);
  if (0 != gethostname (hostname, hostname_len))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot get hostname.  Exiting\n");
    GNUNET_free (hostname);
    destroy_hosts (hosts, nhosts);
    ret = GNUNET_SYSERR;
    return;
  }
  if (NULL == strstr (GNUNET_TESTBED_host_get_hostname (hosts[0]), hostname))
  {
    LOG_DEBUG ("Exiting as `%s' is not the lowest host\n", hostname);
    GNUNET_free (hostname);
    ret = GNUNET_OK;
    return;
  }
  LOG_DEBUG ("Will be executing `%s' on host `%s'\n", argv2[0], hostname);
  GNUNET_free (hostname);
  destroy_hosts (hosts, nhosts);
  tmpdir = getenv ("TMPDIR");
  if (NULL == tmpdir)
    tmpdir = getenv ("TMP");
  if (NULL == tmpdir)
    tmpdir = getenv ("TEMP");
  if (NULL == tmpdir)
    tmpdir = "/tmp";
  (void) GNUNET_asprintf (&fn, "%s/gnunet-testbed-spawn.lock", tmpdir);
  /* Open the unique file; we can create it then we can spawn the child process
     else we exit */
  fh = open (fn, O_CREAT | O_EXCL | O_CLOEXEC,
             S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
  if (-1 == fh)
  {
    if (EEXIST == errno)
    {
      LOG_DEBUG ("Lock file already created by other process.  Exiting\n");
      ret = GNUNET_OK;
      return;
    }
    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "open");
    ret = GNUNET_SYSERR;
    return;
  }
  /* Spawn the new process here */
  LOG (GNUNET_ERROR_TYPE_INFO, _("Spawning process `%s'\n"), argv2[0]);
  child = GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL,
                                       NULL, NULL,
                                       argv2[0], argv2);
  if (NULL == child)
  {
    GNUNET_break (0);
    ret = GNUNET_SYSERR;
    shutdown_task_id = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
    return;
  }
  ret = GNUNET_OK;
  terminate_task_id =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                    &terminate_task, NULL);
  child_death_task_id =
    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
				    GNUNET_DISK_pipe_handle (sigpipe,
							     GNUNET_DISK_PIPE_END_READ),
				    &child_death_task, NULL);
}
/**
 * Task triggered whenever we receive a SIGCHLD (child
 * process died).
 *
 * @param cls closure, NULL if we need to self-restart
 * @param tc context
 */
static void
maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct ServiceList *pos;
  struct ServiceList *next;
  struct ServiceListeningInfo *sli;
  const char *statstr;
  int statcode;
  int ret;
  char c[16];
  enum GNUNET_OS_ProcessStatusType statusType;
  unsigned long statusCode;
  const struct GNUNET_DISK_FileHandle *pr;

  pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
  child_death_task = GNUNET_SCHEDULER_NO_TASK;
  if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
    {
      /* shutdown scheduled us, ignore! */
      child_death_task =
	GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
					pr, &maint_child_death, NULL);
      return;
    }
  /* consume the signal */
  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));

  /* check for services that died (WAITPID) */
  next = running_head;
  while (NULL != (pos = next))
    {
      next = pos->next;

      if (pos->proc == NULL)
      {
	if (GNUNET_YES == in_shutdown)
	  free_service (pos);
	continue;
      }
      if ((GNUNET_SYSERR ==
	   (ret =
	    GNUNET_OS_process_status (pos->proc, &statusType, &statusCode)))
	  || ((ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED)
	      || (statusType == GNUNET_OS_PROCESS_RUNNING)))
	continue;
      if (statusType == GNUNET_OS_PROCESS_EXITED)
      {
	statstr = _( /* process termination method */ "exit");
	statcode = statusCode;
      }
      else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
      {
	statstr = _( /* process termination method */ "signal");
	statcode = statusCode;
      }
      else
      {
	statstr = _( /* process termination method */ "unknown");
	statcode = 0;
      }
      if (0 != pos->killed_at.abs_value)
      {
	GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		    _("Service `%s' took %llu ms to terminate\n"),
		    pos->name,
		    GNUNET_TIME_absolute_get_duration (pos->killed_at).rel_value);
      }
      GNUNET_OS_process_destroy (pos->proc);
      pos->proc = NULL;
      if (NULL != pos->killing_client)
	{
	  signal_result (pos->killing_client, pos->name,
			 GNUNET_ARM_PROCESS_DOWN);
	  GNUNET_SERVER_client_drop (pos->killing_client);
	  pos->killing_client = NULL;
	  /* process can still be re-started on-demand, ensure it is re-started if there is demand */
	  for (sli = pos->listen_head; NULL != sli; sli = sli->next)
	    {
	      GNUNET_break (GNUNET_SCHEDULER_NO_TASK == sli->accept_task);
	      sli->accept_task =
		GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
					       sli->listen_socket,
					       &accept_connection, sli);
	    }
	  continue;
	}
      if (GNUNET_YES != in_shutdown)
	{
	  if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0))
	    {
	      /* process terminated normally, allow restart at any time */
	      pos->restart_at.abs_value = 0;
	    }
          else
            {
	      if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
	        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
			    _
			    ("Service `%s' terminated with status %s/%d, will restart in %llu ms\n"),
			    pos->name, statstr, statcode, pos->backoff.rel_value);
	      /* schedule restart */
	      pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff);
	      pos->backoff =
	        GNUNET_TIME_relative_min (EXPONENTIAL_BACKOFF_THRESHOLD,
				          GNUNET_TIME_relative_multiply
				          (pos->backoff, 2));
            }
	  if (GNUNET_SCHEDULER_NO_TASK != child_restart_task)
	    GNUNET_SCHEDULER_cancel (child_restart_task);
	  child_restart_task =
	    GNUNET_SCHEDULER_add_with_priority
	    (GNUNET_SCHEDULER_PRIORITY_IDLE, 
	     &delayed_restart_task, NULL);
	}
      else
	{
	  free_service (pos);
	}
    }
  child_death_task =
    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
				    pr, &maint_child_death, NULL);
  if ((NULL == running_head) && (GNUNET_YES == in_shutdown))
    do_shutdown ();
}
/**
 * Process arm requests.
 *
 * @param cls closure
 * @param serv the initialized server
 * @param c configuration to use
 */
static void
run (void *cls, struct GNUNET_SERVER_Handle *serv,
     const struct GNUNET_CONFIGURATION_Handle *c)
{
  static const struct GNUNET_SERVER_MessageHandler handlers[] = {
    {&handle_start, NULL, GNUNET_MESSAGE_TYPE_ARM_START, 0},
    {&handle_stop, NULL, GNUNET_MESSAGE_TYPE_ARM_STOP, 0},
    {&handle_shutdown, NULL, GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN,
     sizeof (struct GNUNET_MessageHeader)},
    {&handle_list, NULL, GNUNET_MESSAGE_TYPE_ARM_LIST, 
     sizeof (struct GNUNET_MessageHeader)},
    {NULL, NULL, 0, 0}
  };
  char *defaultservices;
  const char *pos;
  struct ServiceList *sl;

  cfg = c;
  server = serv;
  GNUNET_assert (serv != NULL);
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
				NULL);
  child_death_task =
    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
				    GNUNET_DISK_pipe_handle (sigpipe,
							     GNUNET_DISK_PIPE_END_READ),
				    &maint_child_death, NULL);

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "GLOBAL_PREFIX",
					     &prefix_command))
    prefix_command = GNUNET_strdup ("");
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "GLOBAL_POSTFIX",
					     &final_option))
    final_option = GNUNET_strdup ("");

  GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL);

  /* start default services... */
  if (GNUNET_OK ==
      GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "DEFAULTSERVICES",
					     &defaultservices))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		  _("Starting default services `%s'\n"), defaultservices);
      if (0 < strlen (defaultservices))
	{
	  for (pos = strtok (defaultservices, " "); NULL != pos;
	       pos = strtok (NULL, " "))
	    {
	      sl = find_service (pos);
	      if (NULL == sl)
		{
		  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
			      _
			      ("Default service `%s' not configured correctly!\n"),
			      pos);
		  continue;
		}
	      sl->is_default = GNUNET_YES;
	      start_process (sl);
	    }
	}
      GNUNET_free (defaultservices);
    }
  else
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		  _
		  ("No default services configured, GNUnet will not really start right now.\n"));
    }

  /* process client requests */
  GNUNET_SERVER_add_handlers (server, handlers);
}
static void
runone ()
{
  const struct GNUNET_DISK_FileHandle *stdout_read_handle;

  pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);

  if (pipe_stdout == NULL)
  {
    GNUNET_break (0);
    ok = 2;
    return;
  }

  putenv ("GNUNET_LOG=");
  putenv ("GNUNET_FORCE_LOG=");
  putenv ("GNUNET_FORCE_LOGFILE=");
  switch (phase)
  {
  case 0:
    putenv ("GNUNET_LOG=;;;;ERROR");
    break;
  case 1:
    putenv ("GNUNET_LOG=;;;;WARNING");
    break;
  case 2:
    putenv ("GNUNET_LOG=;;;;INFO");
    break;
  case 3:
    putenv ("GNUNET_LOG=;;;;DEBUG");
    break;
  case 4:
    putenv ("GNUNET_FORCE_LOG=;;;;ERROR");
    break;
  case 5:
    putenv ("GNUNET_FORCE_LOG=;;;;WARNING");
    break;
  case 6:
    putenv ("GNUNET_FORCE_LOG=;;;;INFO");
    break;
  case 7:
    putenv ("GNUNET_FORCE_LOG=;;;;DEBUG");
    break;
  case 8:
    putenv ("GNUNET_LOG=blah;;;;ERROR");
    break;
  case 9:
    putenv ("GNUNET_FORCE_LOG=blah;;;;ERROR");
    break;
  }

  proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
                                  NULL, pipe_stdout, NULL,
#if MINGW
                                  "test_common_logging_dummy",
#else
                                  "./test_common_logging_dummy",
#endif
                                  "test_common_logging_dummy", NULL);
  GNUNET_assert (NULL != proc);
  putenv ("GNUNET_FORCE_LOG=");
  putenv ("GNUNET_LOG=");

  /* Close the write end of the read pipe */
  GNUNET_DISK_pipe_close_end (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);

  stdout_read_handle =
      GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_READ);

  die_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                    (GNUNET_TIME_UNIT_SECONDS, 10), &end_task,
                                    NULL);

  bytes = 0;
  buf_ptr = buf;
  memset (&buf, 0, sizeof (buf));

  read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
					      stdout_read_handle, &read_call,
					      (void*) stdout_read_handle);
}
static void
read_call (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  const struct GNUNET_DISK_FileHandle *stdout_read_handle = cls;
  char level[8];
  long delay;
  long delays[8];
  int rd;

  read_task = NULL;
  rd = GNUNET_DISK_file_read (stdout_read_handle, buf_ptr,
                              sizeof (buf) - bytes);
  if (rd > 0)
  {
    buf_ptr += rd;
    bytes += rd;
#if VERBOSE
    FPRINTF (stderr, "got %d bytes, reading more\n", rd);
#endif
    read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
						stdout_read_handle, &read_call,
						(void*) stdout_read_handle);
    return;
  }

#if VERBOSE
  FPRINTF (stderr, "bytes is %d:%s\n", bytes, buf);
#endif

  /* +------CHILD OUTPUT--
   * |      SOFT     HARD
   * |    E W I D  E W I D
   * | 0E *        * *
   * | 1W * *      * *
   * P 2I * * *    * *
   * H 3D * * * *  * *
   * A
   * S 4E *        *
   * E 5W * *      * *
   * | 6I * * *    * * *
   * | 7D * * * *  * * * *
   * | 8  * *      * *
   * | 9  * *      * *
   */
  char *p = buf;

  if (bytes == LOG_BUFFER_SIZE ||
      !(p =
        read_output_line (0, 3, 4, 9, 'L', "ERROR", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '1', "ERROR", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[0], level)) ||
      !(p =
        read_output_line (1, 3, 5, 9, 'L', "WARNING", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '1', "WARNING", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[1], level)) ||
      !(p =
        read_output_line (2, 3, 6, 7, 'L', "INFO", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '1', "INFO", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[2], level)) ||
      !(p =
        read_output_line (3, 3, 7, 7, 'L', "DEBUG", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '1', "DEBUG", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[3], level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, 'L', "ERROR", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '2', "ERROR", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[4], level)) ||
      !(p =
        read_output_line (0, 3, 5, 9, 'L', "WARNING", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '2', "WARNING", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[5], level)) ||
      !(p =
        read_output_line (-1, -1, 6, 7, 'L', "INFO", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '2', "INFO", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[6], level)) ||
      !(p =
        read_output_line (-1, -1, 7, 7, 'L', "DEBUG", -1,
                          1, phase, p,
                          &bytes, &delay, level)) ||
      !(p =
        read_output_line (0, 3, 4, 9, '2', "DEBUG", OUTPUT_DELAY,
                          MAX_SKIP_DELAY, phase, p,
                          &bytes, &delays[7], level)))
  {
    if (bytes == LOG_BUFFER_SIZE)
      FPRINTF (stderr, "%s",  "Ran out of buffer space!\n");
    GNUNET_break (0);
    ok = 2;
    GNUNET_SCHEDULER_cancel (die_task);
    GNUNET_SCHEDULER_add_now (&end_task, NULL);
    return;
  }

  GNUNET_SCHEDULER_cancel (die_task);
  GNUNET_SCHEDULER_add_now (&end_task, NULL);
}
示例#13
0
文件: helper.c 项目: GNUnet/gnunet
/**
 * 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;
  }
}
示例#14
0
/**
 * Try to get the external IPv4 address of this peer.
 *
 * @param cb function to call with result
 * @param cb_cls closure for @a cb
 * @return handle for cancellation (can only be used until @a cb is called), never NULL
 */
struct GNUNET_NAT_ExternalHandle *
GNUNET_NAT_mini_get_external_ipv4_ (GNUNET_NAT_IPCallback cb,
				    void *cb_cls)
{
  struct GNUNET_NAT_ExternalHandle *eh;

  eh = GNUNET_new (struct GNUNET_NAT_ExternalHandle);
  eh->cb = cb;
  eh->cb_cls = cb_cls;
  eh->ret = GNUNET_NAT_ERROR_SUCCESS;
  if (GNUNET_SYSERR ==
      GNUNET_OS_check_helper_binary ("external-ip",
				     GNUNET_NO,
				     NULL))
  {
    LOG (GNUNET_ERROR_TYPE_INFO,
	 _("`external-ip' command not found\n"));
    eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND;
    eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error,
                                         eh);
    return eh;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Running `external-ip' to determine our external IP\n");
  eh->opipe = GNUNET_DISK_pipe (GNUNET_YES,
				GNUNET_YES,
				GNUNET_NO,
				GNUNET_YES);
  if (NULL == eh->opipe)
  {
    eh->ret = GNUNET_NAT_ERROR_IPC_FAILURE;
    eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error,
                                         eh);
    return eh;
  }
  eh->eip =
      GNUNET_OS_start_process (GNUNET_NO,
			       0,
			       NULL,
			       eh->opipe,
			       NULL,
                               "external-ip",
			       "external-ip",
                               NULL);
  if (NULL == eh->eip)
  {
    GNUNET_DISK_pipe_close (eh->opipe);
    eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED;
    eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error,
                                         eh);
    return eh;
  }
  GNUNET_DISK_pipe_close_end (eh->opipe,
			      GNUNET_DISK_PIPE_END_WRITE);
  eh->r = GNUNET_DISK_pipe_handle (eh->opipe,
				   GNUNET_DISK_PIPE_END_READ);
  eh->task 
    = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                      eh->r,
                                      &read_external_ipv4,
				      eh);
  return eh;
}