Esempio n. 1
0
static gboolean
dispatch_input (gint fd,
                GIOCondition cond,
                gpointer user_data)
{
  CockpitPipe *self = (CockpitPipe *)user_data;
  gssize ret = 0;
  gsize len;
  gboolean eof;

  g_return_val_if_fail (self->priv->in_source, FALSE);
  len = self->priv->in_buffer->len;

  /*
   * Enable clean shutdown by not reading when we just get
   * G_IO_HUP. Note that when we get G_IO_ERR we do want to read
   * just so we can get the appropriate detailed error message.
   */
  if (cond != G_IO_HUP)
    {
      g_debug ("%s: reading input", self->priv->name);

      g_byte_array_set_size (self->priv->in_buffer, len + 1024);
      ret = read (self->priv->in_fd, self->priv->in_buffer->data + len, 1024);
      if (ret < 0)
        {
          g_byte_array_set_size (self->priv->in_buffer, len);
          if (errno != EAGAIN && errno != EINTR)
            {
              set_problem_from_errno (self, "couldn't read", errno);
              close_immediately (self, NULL); /* problem already set */
              return FALSE;
            }
          return TRUE;
        }
    }

  g_byte_array_set_size (self->priv->in_buffer, len + ret);

  if (ret == 0)
    {
      g_debug ("%s: end of input", self->priv->name);
      stop_input (self);
    }

  g_object_ref (self);

  eof = (self->priv->in_source == NULL);
  g_signal_emit (self, cockpit_pipe_sig_read, 0, self->priv->in_buffer, eof);

  if (eof)
    close_maybe (self);

  g_object_unref (self);
  return TRUE;
}
Esempio n. 2
0
static void
close_immediately (CockpitPipe *self,
                   const gchar *problem)
{
  if (self->priv->closed)
    return;

  if (problem)
    {
      g_free (self->priv->problem);
      self->priv->problem = g_strdup (problem);
    }

  self->priv->closed = TRUE;

  g_debug ("%s: closing pipe%s%s", self->priv->name,
           self->priv->problem ? ": " : "",
           self->priv->problem ? self->priv->problem : "");

  if (self->priv->in_source)
    stop_input (self);
  if (self->priv->out_source)
    stop_output (self);
  if (self->priv->err_source)
    stop_error (self);

  if (self->priv->in_fd != -1)
    {
      close (self->priv->in_fd);
      self->priv->in_fd = -1;
    }
  if (self->priv->out_fd != -1)
    {
      close (self->priv->out_fd);
      self->priv->out_fd = -1;
    }
  if (self->priv->err_fd != -1)
    {
      close (self->priv->err_fd);
      self->priv->err_fd = -1;
    }


  if (problem && self->priv->pid && !self->priv->exited)
    {
      g_debug ("%s: killing child: %d", self->priv->name, (int)self->priv->pid);
      kill (self->priv->pid, SIGTERM);
    }

  /* If not tracking a pid, then we are now closed. */
  if (!self->priv->child)
    {
      g_debug ("%s: no child process to wait for: closed", self->priv->name);
      g_signal_emit (self, cockpit_pipe_sig_close, 0, self->priv->problem);
    }
}
Esempio n. 3
0
static void
close_immediately (CockpitStream *self,
                   const gchar *problem)
{
  GError *error = NULL;
  GIOStream *io;

  if (self->priv->closed)
    return;

  if (problem)
    {
      g_free (self->priv->problem);
      self->priv->problem = g_strdup (problem);
    }

  if (self->priv->connecting)
    {
      cockpit_connectable_unref (self->priv->connecting);
      self->priv->connecting = NULL;
    }

  self->priv->closed = TRUE;

  g_debug ("%s: closing stream%s%s", self->priv->name,
           self->priv->problem ? ": " : "",
           self->priv->problem ? self->priv->problem : "");

  if (self->priv->in_source)
    stop_input (self);
  if (self->priv->out_source)
    stop_output (self);

  if (self->priv->io)
    {
      io = self->priv->io;
      self->priv->io = NULL;

      if (self->priv->sig_accept_cert)
        {
          g_signal_handler_disconnect (io, self->priv->sig_accept_cert);
          self->priv->sig_accept_cert = 0;
        }

      g_io_stream_close (io, NULL, &error);
      if (error)
        {
          g_message ("%s: close failed: %s", self->priv->name, error->message);
          g_clear_error (&error);
        }
      g_object_unref (io);
    }

  g_debug ("%s: closed", self->priv->name);
  g_signal_emit (self, cockpit_stream_sig_close, 0, self->priv->problem);
}
Esempio n. 4
0
static void
close_output (CockpitPipe *self)
{
  if (self->priv->out_fd != -1)
    {
      g_debug ("%s: end of output", self->priv->name);

      /* And if closing, then we need to shutdown the output fd */
      if (shutdown (self->priv->out_fd, SHUT_WR) < 0)
        {
          if (errno == ENOTSOCK)
            {
              g_debug ("%s: not a socket, closing entirely", self->priv->name);
              close (self->priv->out_fd);

              if (self->priv->in_fd == self->priv->out_fd)
                {
                  self->priv->in_fd = -1;
                  if (self->priv->in_source)
                    {
                      g_debug ("%s: and closing input because same fd", self->priv->name);
                      stop_input (self);
                    }
                }

              self->priv->out_fd = -1;
            }
          else
            {
              g_warning ("%s: couldn't shutdown fd: %s", self->priv->name, g_strerror (errno));
              close_immediately (self, "internal-error");
            }
        }
    }

  close_maybe (self);
}
Esempio n. 5
0
int main(int argc, char *argv[])
{
  int rc;
  gamut_opts opts;

  signal(SIGPIPE, SIG_IGN);

  memset(&opts, 0, sizeof(opts));

  /* Use line buffering for stdout */
  setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);

  rc = parse_opts(argc, argv, &opts);
  if(rc < 0) {
    s_log(G_EMERG, "Error parsing options.\n");
    exit(EXIT_FAILURE);
  }
  else if(!rc) {
    usage(argv[0]);
    exit(EXIT_FAILURE);
  }

  /*
   * In this order, perform these steps (if necessary)
   * 1. Redirect to a log file
   * 2. Restore benchmark data from a file
   * 3. Run the benchmarks
   * 4. Save the new benchmark data
   * 5. Quit after benchmarks
   * 6. Run calibration (if no benchmark data)
   * 7. Run a trace file and exit
   * 8. Accept commands from stdin
   */

  /*
   * 1. Redirect to a log file
   */
  if(redirect_stdout) {
    redirect_output();
  }

  /*
   * 2. Restore benchmark data from a file
   */
  if(load_benchmarks) {
    s_log(G_NOTICE, "Loading benchmark data ... ");
    load_benchmark_data();
    s_log(G_NOTICE, "done.\n");
  }

  /*
   * 3. Run the benchmarks
   */
  if(run_benchmarks) {
    s_log(G_NOTICE, "Running %u calibration trials.\n", DEF_BMARK_TRIALS);
    benchmark_delays(DEF_BMARK_TRIALS);
  }

  /*
   * 4. Save the new benchmark data
   */
  if(save_benchmarks) {
    s_log(G_NOTICE, "Saving benchmark data ... ");
    save_benchmark_data();
    s_log(G_NOTICE, "done.\n");

    /*
     * 5. Quit after benchmarks
     */
    if(quit_benchmarks)
      exit(EXIT_SUCCESS);
  }


  /*
   * 6. Run calibration (if no benchmark data is available yet)
   */
  if(!load_benchmarks && !run_benchmarks) {
    s_log(G_NOTICE, "Calibrating node attributes ... ");
    benchmark_delays(1);
    s_log(G_NOTICE, "done.\n");
  }

  init_opts(&opts);
  start_reaper(&opts);
  start_input(&opts);

  execute_gamut(&opts);

  stop_input(&opts);
  killall_workers(&opts);
  stop_reaper(&opts);

  return 0;
}
Esempio n. 6
0
static gboolean
dispatch_input (GPollableInputStream *is,
                gpointer user_data)
{
  CockpitStream *self = (CockpitStream *)user_data;
  GError *error = NULL;
  gboolean read = FALSE;
  gssize ret = 0;
  gsize len;
  gboolean eof;

  for (;;)
    {
      g_return_val_if_fail (self->priv->in_source, FALSE);
      len = self->priv->in_buffer->len;

      g_byte_array_set_size (self->priv->in_buffer, len + 1024);
      ret = g_pollable_input_stream_read_nonblocking (is, self->priv->in_buffer->data + len,
                                                      1024, NULL, &error);

      if (ret < 0)
        {
          g_byte_array_set_size (self->priv->in_buffer, len);
          if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
            {
              g_error_free (error);
              break;
            }
          else
            {
              set_problem_from_error (self, "couldn't read", error);
              g_error_free (error);
              close_immediately (self, NULL);
              return FALSE;
            }
        }

      g_byte_array_set_size (self->priv->in_buffer, len + ret);

      if (ret == 0)
        {
          g_debug ("%s: end of input", self->priv->name);
          stop_input (self);
          break;
        }
      else if (ret > 0)
        {
          g_debug ("%s: read %d bytes", self->priv->name, (int)ret);
          self->priv->received = TRUE;
          read = TRUE;
        }
    }

  g_object_ref (self);

  eof = (self->priv->in_source == NULL);
  if (eof || read)
    g_signal_emit (self, cockpit_stream_sig_read, 0, self->priv->in_buffer, eof);

  if (eof)
    close_maybe (self);

  g_object_unref (self);
  return TRUE;
}