static void set_running_settings (OfficeRunner *run, gboolean running) { if (running) { GVariant *ret; GUnixFDList *fd_list; gint idx; GError *error = NULL; if (run->lid_switch_fd != -1) { g_debug ("Already blocked"); return; } g_debug ("Blocking lid action"); ret = g_dbus_connection_call_with_unix_fd_list_sync (run->connection, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, "Inhibit", g_variant_new ("(ssss)", "handle-lid-switch", g_get_user_name(), _("Office Runner is running"), "block"), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &fd_list, NULL, &error); if (ret == NULL) g_error ("Failed to inhibit: %s", error->message); g_variant_get (ret, "(h)", &idx); run->lid_switch_fd = g_unix_fd_list_get (fd_list, idx, NULL); g_object_unref (fd_list); g_variant_unref (ret); } else { if (run->lid_switch_fd != -1) { close (run->lid_switch_fd); run->lid_switch_fd = -1; g_debug ("Unblocking lid action"); } else { g_debug ("Already released the blocking inhibitor"); } } }
gboolean builder_host_spawnv (GFile *dir, char **output, GError **error, const gchar * const *argv) { guint32 client_pid; GVariantBuilder *fd_builder = g_variant_builder_new (G_VARIANT_TYPE("a{uh}")); GVariantBuilder *env_builder = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); g_autoptr(GUnixFDList) fd_list = g_unix_fd_list_new (); gint stdout_handle, stdin_handle, stderr_handle; g_autoptr(GDBusConnection) connection = NULL; g_autoptr(GVariant) ret = NULL; g_autoptr(GMainLoop) loop = NULL; g_auto(GStrv) env_vars = NULL; guint subscription; HostCommandCallData data = { NULL }; guint sigterm_id = 0, sigint_id = 0; g_autofree gchar *commandline = NULL; g_autoptr(GOutputStream) out = NULL; int pipefd[2]; int i; commandline = flatpak_quote_argv ((const char **) argv); g_debug ("Running '%s' on host", commandline); connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error); if (connection == NULL) return FALSE; loop = g_main_loop_new (NULL, FALSE); data.connection = connection; data.loop = loop; data.refs = 1; subscription = g_dbus_connection_signal_subscribe (connection, NULL, "org.freedesktop.Flatpak.Development", "HostCommandExited", "/org/freedesktop/Flatpak/Development", NULL, G_DBUS_SIGNAL_FLAGS_NONE, host_command_exited_cb, &data, NULL); stdin_handle = g_unix_fd_list_append (fd_list, 0, error); if (stdin_handle == -1) return FALSE; if (output) { g_autoptr(GInputStream) in = NULL; if (pipe2 (pipefd, O_CLOEXEC) != 0) { glnx_set_error_from_errno (error); return FALSE; } data.refs++; in = g_unix_input_stream_new (pipefd[0], TRUE); out = g_memory_output_stream_new_resizable (); g_output_stream_splice_async (out, in, G_OUTPUT_STREAM_SPLICE_NONE, 0, NULL, output_spliced_cb, &data); stdout_handle = g_unix_fd_list_append (fd_list, pipefd[1], error); close (pipefd[1]); if (stdout_handle == -1) return FALSE; } else { stdout_handle = g_unix_fd_list_append (fd_list, 1, error); if (stdout_handle == -1) return FALSE; } stderr_handle = g_unix_fd_list_append (fd_list, 2, error); if (stderr_handle == -1) return FALSE; g_variant_builder_add (fd_builder, "{uh}", 0, stdin_handle); g_variant_builder_add (fd_builder, "{uh}", 1, stdout_handle); g_variant_builder_add (fd_builder, "{uh}", 2, stderr_handle); env_vars = g_listenv (); for (i = 0; env_vars[i] != NULL; i++) { const char *env_var = env_vars[i]; g_variant_builder_add (env_builder, "{ss}", env_var, g_getenv (env_var)); } sigterm_id = g_unix_signal_add (SIGTERM, sigterm_handler, &data); sigint_id = g_unix_signal_add (SIGINT, sigint_handler, &data); ret = g_dbus_connection_call_with_unix_fd_list_sync (connection, "org.freedesktop.Flatpak", "/org/freedesktop/Flatpak/Development", "org.freedesktop.Flatpak.Development", "HostCommand", g_variant_new ("(^ay^aay@a{uh}@a{ss}u)", dir ? flatpak_file_get_path_cached (dir) : "", argv, g_variant_builder_end (fd_builder), g_variant_builder_end (env_builder), FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV), G_VARIANT_TYPE ("(u)"), G_DBUS_CALL_FLAGS_NONE, -1, fd_list, NULL, NULL, error); if (ret == NULL) return FALSE; g_variant_get (ret, "(u)", &client_pid); data.client_pid = client_pid; g_main_loop_run (loop); g_source_remove (sigterm_id); g_source_remove (sigint_id); g_dbus_connection_signal_unsubscribe (connection, subscription); if (!g_spawn_check_exit_status (data.exit_status, error)) return FALSE; if (out) { if (data.splice_error) { g_propagate_error (error, data.splice_error); return FALSE; } /* Null terminate */ g_output_stream_write (out, "\0", 1, NULL, NULL); g_output_stream_close (out, NULL, NULL); *output = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out)); } return TRUE; }
/** * udisks_daemon_util_inhibit_system_sync: * @reason: A human readable explanation of why the system is being inhibited. * * Tries to inhibit the system. * * Right now only * <ulink url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">systemd</ulink> * inhibitors are supported but other inhibitors can be added in the future. * * Returns: A cookie that can be used with udisks_daemon_util_uninhibit_system_sync(). */ UDisksInhibitCookie * udisks_daemon_util_inhibit_system_sync (const gchar *reason) { #ifdef HAVE_LIBSYSTEMD_LOGIN UDisksInhibitCookie *ret = NULL; GDBusConnection *connection = NULL; GVariant *value = NULL; GUnixFDList *fd_list = NULL; gint32 index = -1; GError *error = NULL; g_return_val_if_fail (reason != NULL, NULL); connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (connection == NULL) { udisks_error ("Error getting system bus: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); goto out; } value = g_dbus_connection_call_with_unix_fd_list_sync (connection, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "Inhibit", g_variant_new ("(ssss)", "sleep:shutdown:idle", /* what */ "Disk Manager", /* who */ reason, /* why */ "block"), /* mode */ G_VARIANT_TYPE ("(h)"), G_DBUS_CALL_FLAGS_NONE, -1, /* default timeout */ NULL, /* fd_list */ &fd_list, /* out_fd_list */ NULL, /* GCancellable */ &error); if (value == NULL) { udisks_error ("Error inhibiting: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); goto out; } g_variant_get (value, "(h)", &index); g_assert (index >= 0 && index < g_unix_fd_list_get_length (fd_list)); ret = g_new0 (UDisksInhibitCookie, 1); ret->magic = 0xdeadbeef; ret->fd = g_unix_fd_list_get (fd_list, index, &error); if (ret->fd == -1) { udisks_error ("Error getting fd: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); g_free (ret); ret = NULL; goto out; } out: if (value != NULL) g_variant_unref (value); g_clear_object (&fd_list); g_clear_object (&connection); return ret; #else /* non-systemd: just return a dummy pointer */ g_return_val_if_fail (reason != NULL, NULL); return (UDisksInhibitCookie* ) &udisks_daemon_util_inhibit_system_sync; #endif }