You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
11 KiB
310 lines
11 KiB
From 9b03a1eb04442c74dd990cda0f44ccf283413a75 Mon Sep 17 00:00:00 2001 |
|
From: Rui Matos <tiagomatos@gmail.com> |
|
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 <http://www.gnu.org/licenses/>. |
|
* |
|
*/ |
|
|
|
#include "config.h" |
|
|
|
#include <locale.h> |
|
#include <glib.h> |
|
#include <gio/gio.h> |
|
#include <gio/gdesktopappinfo.h> |
|
#include <glib/gstdio.h> |
|
|
|
#ifdef HAVE_NETWORK_MANAGER |
|
#include <NetworkManager.h> |
|
#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[] = |
|
"<node>" |
|
@@ -77,176 +79,170 @@ static const gchar introspection_xml[] = |
|
" <method name='EnableService'>" |
|
" <arg name='service-name' direction='in' type='s'/>" |
|
" </method>" |
|
" <method name='DisableService'>" |
|
" <arg name='service-name' direction='in' type='s'/>" |
|
" <arg name='network' direction='in' type='s'/>" |
|
" </method>" |
|
" <method name='ListNetworks'>" |
|
" <arg name='service-name' direction='in' type='s'/>" |
|
" <arg name='networks' direction='out' type='a(sss)'/>" |
|
" </method>" |
|
" </interface>" |
|
"</node>"; |
|
|
|
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 |
|
|
|
|