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); }
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); }
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; }
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; }