static GDBusConnection * create_connection (GIOStream *stream, GMainLoop *main_loop, GError **error) { GDBusConnection *ret; g_assert (G_IS_IO_STREAM (stream)); g_assert (main_loop != NULL); g_assert (error != NULL); if ((ret = g_dbus_connection_new_sync (stream, NULL, G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, NULL, NULL, error))) { g_dbus_connection_set_exit_on_close (ret, FALSE); g_signal_connect_swapped (ret, "closed", G_CALLBACK (g_main_loop_quit), main_loop); } return ret; }
/* Called in new thread */ static gboolean on_run (GSocketService *service, GSocketConnection *socket_connection, GObject *source_object, gpointer user_data) { GDBusServer *server = G_DBUS_SERVER (user_data); GDBusConnection *connection; GDBusConnectionFlags connection_flags; if (server->nonce != NULL) { gchar buf[16]; gsize bytes_read; if (!g_input_stream_read_all (g_io_stream_get_input_stream (G_IO_STREAM (socket_connection)), buf, 16, &bytes_read, NULL, /* GCancellable */ NULL)) /* GError */ goto out; if (bytes_read != 16) goto out; if (memcmp (buf, server->nonce, 16) != 0) goto out; } connection_flags = G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING; if (server->flags & G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS) connection_flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), server->guid, connection_flags, server->authentication_observer, NULL, /* GCancellable */ NULL); /* GError */ if (connection == NULL) goto out; if (server->flags & G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) { gboolean claimed; claimed = FALSE; g_signal_emit (server, _signals[NEW_CONNECTION_SIGNAL], 0, connection, &claimed); if (claimed) g_dbus_connection_start_message_processing (connection); g_object_unref (connection); } else { GSource *idle_source; EmitIdleData *data; data = g_new0 (EmitIdleData, 1); data->server = g_object_ref (server); data->connection = g_object_ref (connection); idle_source = g_idle_source_new (); g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); g_source_set_callback (idle_source, emit_new_connection_in_idle, data, (GDestroyNotify) emit_idle_data_free); g_source_attach (idle_source, server->main_context_at_construction); g_source_unref (idle_source); } out: return TRUE; }
static GDBusConnection* get_connection_for_path (gchar *sysroot, gboolean force_peer, GPid *out_peer_pid, GCancellable *cancellable, GError **error) { glnx_unref_object GDBusConnection *connection = NULL; glnx_unref_object GSocketConnection *stream = NULL; glnx_unref_object GSocket *socket = NULL; _cleanup_peer_ GPid peer_pid = 0; gchar buffer[16]; int pair[2]; const gchar *args[] = { "rpm-ostree", "start-daemon", "--sysroot", sysroot, "--dbus-peer", buffer, NULL }; /* This is only intended for use by installed tests. * Note that it disregards the 'sysroot' and 'force_peer' options * and assumes the service activation command has been configured * to use the desired system root path. */ if (g_getenv ("RPMOSTREE_USE_SESSION_BUS") != NULL) { if (sysroot != NULL) g_warning ("RPMOSTREE_USE_SESSION_BUS set, ignoring --sysroot=%s", sysroot); /* NB: as opposed to other early returns, this is _also_ a happy path */ GDBusConnection *ret = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, error); if (!ret) return glnx_prefix_error_null (error, "Connecting to session bus"); return ret; } if (sysroot == NULL) sysroot = "/"; if (g_strcmp0 ("/", sysroot) == 0 && force_peer == FALSE) { /* NB: as opposed to other early returns, this is _also_ a happy path */ GDBusConnection *ret = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error); if (!ret) return glnx_prefix_error_null (error, "Connecting to system bus"); return ret; } g_print ("Running in single user mode. Be sure no other users are modifying the system\n"); if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0) return glnx_null_throw_errno_prefix (error, "couldn't create socket pair"); g_snprintf (buffer, sizeof (buffer), "%d", pair[1]); socket = g_socket_new_from_fd (pair[0], error); if (socket == NULL) { close (pair[0]); close (pair[1]); return NULL; } if (!g_spawn_async (NULL, (gchar **)args, NULL, G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &peer_pid, error)) { close (pair[1]); return NULL; } stream = g_socket_connection_factory_create_connection (socket); connection = g_dbus_connection_new_sync (G_IO_STREAM (stream), NULL, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, cancellable, error); if (!connection) return NULL; *out_peer_pid = peer_pid; peer_pid = 0; return connection; }