Esempio n. 1
0
static void
on_address_next (GObject *object,
                 GAsyncResult *result,
                 gpointer user_data)
{
  CockpitStream *self = user_data;
  GSocketConnection *connection;
  GSocketAddress *address;
  GError *error = NULL;
  GSocket *sock;

  address = g_socket_address_enumerator_next_finish (G_SOCKET_ADDRESS_ENUMERATOR (object),
                                                     result, &error);

  if (error)
    {
      set_problem_from_error (self, "couldn't resolve", error);
      g_error_free (error);
      close_immediately (self, NULL);
    }
  else if (address)
    {
      sock = g_socket_new (g_socket_address_get_family (address), G_SOCKET_TYPE_STREAM, 0, &error);
      if (sock)
        {
          g_socket_set_blocking (sock, FALSE);

          connection = g_socket_connection_factory_create_connection (sock);
          g_object_unref (sock);

          g_socket_connection_connect_async (connection, address, NULL,
                                             on_socket_connect, g_object_ref (self));
        }

      if (error)
        {
          g_debug ("%s: couldn't open socket: %s", self->priv->name, error->message);
          g_clear_error (&self->priv->connect_error);
          self->priv->connect_error = error;
        }
      g_object_unref (address);
    }
  else
    {
      if (self->priv->connect_error)
        {
          set_problem_from_error (self, "couldn't connect", self->priv->connect_error);
          close_immediately (self, NULL);
        }
      else
        {
          g_message ("%s: no addresses found", self->priv->name);
          close_immediately (self, "not-found");
        }
    }

  g_object_unref (self);
}
Esempio n. 2
0
static void
on_connect_stream (GObject *object,
                   GAsyncResult *result,
                   gpointer user_data)
{
  CockpitStream *self = COCKPIT_STREAM (user_data);
  GError *error = NULL;
  GIOStream *io;

  io = cockpit_connect_stream_finish (result, &error);
  if (error)
    {
      set_problem_from_error (self, "couldn't connect", error);
      close_immediately (self, NULL);
      g_error_free (error);
    }
  else if (!self->priv->closed)
    {
      self->priv->io = g_object_ref (io);
      initialize_io (self);
    }

  g_clear_object (&io);
  g_object_unref (self);
}
Esempio n. 3
0
static gboolean
dispatch_output (GPollableOutputStream *os,
                 gpointer user_data)
{
  CockpitStream *self = (CockpitStream *)user_data;
  GError *error = NULL;
  const gint8 *data;
  gsize len;
  gssize ret;

  g_return_val_if_fail (self->priv->out_source, FALSE);
  while (self->priv->out_queue->head)
    {
      data = g_bytes_get_data (self->priv->out_queue->head->data, &len);
      g_assert (self->priv->out_partial <= len);

      ret = g_pollable_output_stream_write_nonblocking (os, data + self->priv->out_partial,
                                                        len - self->priv->out_partial, NULL, &error);

      if (ret < 0)
        {
          if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
            {
              g_debug ("%s: output would block", self->priv->name);
              g_error_free (error);
              return TRUE;
            }
          else
            {
              set_problem_from_error (self, "couldn't write", error);
              g_error_free (error);
              close_immediately (self, NULL);
              return FALSE;
            }
        }

      self->priv->out_partial += ret;
      if (self->priv->out_partial >= len)
        {
          g_debug ("%s: wrote %d bytes", self->priv->name, (int)len);
          g_bytes_unref (g_queue_pop_head (self->priv->out_queue));
          self->priv->out_partial = 0;
        }
      else
        {
          if (ret > 0)
            g_debug ("%s: partial write %d of %d bytes", self->priv->name, (int)ret, (int)len);
          return TRUE;
        }
    }

  g_debug ("%s: output queue empty", self->priv->name);

  /* If all messages are done, then stop polling out fd */
  stop_output (self);

  if (self->priv->closing)
    close_output (self);
  else
    close_maybe (self);

  return TRUE;
}
Esempio n. 4
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;
}