From 9b03a1eb04442c74dd990cda0f44ccf283413a75 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 11 Oct 2017 18:10:54 +0200 Subject: [PATCH 3/3] Revert "sharing: Use systemd to track running services" This reverts commit e0b7f4143bdd201c824499dd09159f5890a07c6a. --- plugins/sharing/gsd-sharing-manager.c | 114 +++++++++++++------------- 1 file changed, 55 insertions(+), 59 deletions(-) diff --git a/plugins/sharing/gsd-sharing-manager.c b/plugins/sharing/gsd-sharing-manager.c index 26663442..b24c4814 100644 --- a/plugins/sharing/gsd-sharing-manager.c +++ b/plugins/sharing/gsd-sharing-manager.c @@ -11,60 +11,62 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "config.h" #include #include #include #include #include #ifdef HAVE_NETWORK_MANAGER #include #endif /* HAVE_NETWORK_MANAGER */ #include "gnome-settings-profile.h" #include "gsd-sharing-manager.h" #include "gsd-sharing-enums.h" #define GSD_SHARING_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SHARING_MANAGER, GsdSharingManagerPrivate)) typedef struct { const char *name; GSettings *settings; + gboolean started; + GSubprocess *process; } ServiceInfo; struct GsdSharingManagerPrivate { GDBusNodeInfo *introspection_data; guint name_id; GDBusConnection *connection; GCancellable *cancellable; #ifdef HAVE_NETWORK_MANAGER NMClient *client; #endif /* HAVE_NETWORK_MANAGER */ GHashTable *services; char *current_network; char *current_network_name; char *carrier_type; GsdSharingStatus sharing_status; }; #define GSD_DBUS_NAME "org.gnome.SettingsDaemon" #define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" #define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon" #define GSD_SHARING_DBUS_NAME GSD_DBUS_NAME ".Sharing" #define GSD_SHARING_DBUS_PATH GSD_DBUS_PATH "/Sharing" static const gchar introspection_xml[] = "" @@ -77,176 +79,170 @@ static const gchar introspection_xml[] = " " " " " " " " " " " " " " " " " " " " " " " " ""; static void gsd_sharing_manager_class_init (GsdSharingManagerClass *klass); static void gsd_sharing_manager_init (GsdSharingManager *manager); static void gsd_sharing_manager_finalize (GObject *object); G_DEFINE_TYPE (GsdSharingManager, gsd_sharing_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; static const char * const services[] = { "rygel", "vino-server", "gnome-remote-desktop", "gnome-user-share-webdav" }; static void -handle_unit_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +gsd_sharing_manager_start_service (GsdSharingManager *manager, + ServiceInfo *service) { + GDesktopAppInfo *app; + const char *exec; + char *desktop, **argvp; GError *error = NULL; - GVariant *ret; - const char *operation = user_data; - ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), - res, &error); - if (!ret) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("Failed to %s service: %s", operation, error->message); - g_error_free (error); + if (service->started) return; - } + g_debug ("About to start %s", service->name); - g_variant_unref (ret); + desktop = g_strdup_printf ("%s.desktop", service->name); + app = g_desktop_app_info_new (desktop); + g_free (desktop); -} + if (!app) { + g_warning ("Could not find desktop file for service '%s'", service->name); + return; + } -static void -gsd_sharing_manager_handle_service (GsdSharingManager *manager, - const char *method, - GAsyncReadyCallback callback, - ServiceInfo *service) -{ - char *service_file; - - service_file = g_strdup_printf ("%s.service", service->name); - g_dbus_connection_call (manager->priv->connection, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - method, - g_variant_new ("(ss)", service_file, "replace"), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - manager->priv->cancellable, - callback, - manager); - g_free (service_file); -} + exec = g_app_info_get_commandline (G_APP_INFO (app)); -static void -gsd_sharing_manager_start_service (GsdSharingManager *manager, - ServiceInfo *service) -{ - g_debug ("About to start %s", service->name); + if (!g_shell_parse_argv (exec, NULL, &argvp, &error)) { + g_warning ("Could not parse command-line '%s': %s", exec, error->message); + g_error_free (error); + g_object_unref (app); + return; + } - /* We use StartUnit, not StartUnitReplace, since the latter would - * cancel any pending start we already have going from an - * earlier _start_service() call */ - gsd_sharing_manager_handle_service (manager, "StartUnit", - handle_unit_cb, "start"); -} + service->process = g_subprocess_newv ((const gchar * const*) argvp, G_SUBPROCESS_FLAGS_NONE, &error); -static void -gsd_sharing_manager_stop_service (GsdSharingManager *manager, - ServiceInfo *service) -{ - g_debug ("About to stop %s", service->name); + if (!service->process) { + g_warning ("Could not start command-line '%s': %s", exec, error->message); + g_error_free (error); + service->started = FALSE; + } else { + service->started = TRUE; + } - gsd_sharing_manager_handle_service (manager, "StopUnit", - handle_unit_cb, "stop"); + g_strfreev (argvp); + g_object_unref (app); } #ifdef HAVE_NETWORK_MANAGER static gboolean service_is_enabled_on_current_connection (GsdSharingManager *manager, ServiceInfo *service) { char **connections; int j; gboolean ret; connections = g_settings_get_strv (service->settings, "enabled-connections"); ret = FALSE; for (j = 0; connections[j] != NULL; j++) { if (g_strcmp0 (connections[j], manager->priv->current_network) == 0) { ret = TRUE; break; } } g_strfreev (connections); return ret; } #else static gboolean service_is_enabled_on_current_connection (GsdSharingManager *manager, ServiceInfo *service) { return FALSE; } #endif /* HAVE_NETWORK_MANAGER */ +static void +gsd_sharing_manager_stop_service (GsdSharingManager *manager, + ServiceInfo *service) +{ + if (!service->started || + service->process == NULL) { + return; + } + + g_debug ("About to stop %s", service->name); + + g_subprocess_send_signal (service->process, SIGTERM); + g_clear_object (&service->process); + service->started = FALSE; +} + static void gsd_sharing_manager_sync_services (GsdSharingManager *manager) { GList *services, *l; services = g_hash_table_get_values (manager->priv->services); for (l = services; l != NULL; l = l->next) { ServiceInfo *service = l->data; gboolean should_be_started = FALSE; if (manager->priv->sharing_status == GSD_SHARING_STATUS_AVAILABLE && service_is_enabled_on_current_connection (manager, service)) should_be_started = TRUE; - if (should_be_started) - gsd_sharing_manager_start_service (manager, service); - else - gsd_sharing_manager_stop_service (manager, service); + if (service->started != should_be_started) { + if (service->started) + gsd_sharing_manager_stop_service (manager, service); + else + gsd_sharing_manager_start_service (manager, service); + } } g_list_free (services); } #ifdef HAVE_NETWORK_MANAGER static void properties_changed (GsdSharingManager *manager) { GVariantBuilder props_builder; GVariant *props_changed = NULL; /* not yet connected to the session bus */ if (manager->priv->connection == NULL) return; g_variant_builder_init (&props_builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&props_builder, "{sv}", "CurrentNetwork", g_variant_new_string (manager->priv->current_network)); g_variant_builder_add (&props_builder, "{sv}", "CurrentNetworkName", g_variant_new_string (manager->priv->current_network_name)); g_variant_builder_add (&props_builder, "{sv}", "CarrierType", g_variant_new_string (manager->priv->carrier_type)); g_variant_builder_add (&props_builder, "{sv}", "SharingStatus", g_variant_new_uint32 (manager->priv->sharing_status)); props_changed = g_variant_new ("(s@a{sv}@as)", GSD_SHARING_DBUS_NAME, g_variant_builder_end (&props_builder), g_variant_new_strv (NULL, 0)); -- 2.17.0