summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/gvfsdaemondbus.c88
1 files changed, 75 insertions, 13 deletions
diff --git a/client/gvfsdaemondbus.c b/client/gvfsdaemondbus.c
index f8deb097..f7b383a5 100644
--- a/client/gvfsdaemondbus.c
+++ b/client/gvfsdaemondbus.c
@@ -31,12 +31,14 @@
#include <errno.h>
#include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
#include <gio/gio.h>
#include "gvfsdaemondbus.h"
#include <gvfsdaemonprotocol.h>
#include <gdaemonvfs.h>
#include <gvfsdbus.h>
+#include <gvfsutils.h>
/* Extra vfs-specific data for GDBusConnections */
typedef struct {
@@ -156,6 +158,7 @@ set_connection_for_async (GDBusConnection *connection, const char *dbus_id)
typedef struct {
char *dbus_id;
+ GVfsDBusDaemon *proxy;
GDBusConnection *connection;
GCancellable *cancellable;
@@ -174,6 +177,7 @@ async_call_finish (AsyncDBusCall *async_call)
async_call->io_error,
async_call->callback_data);
+ g_clear_object (&async_call->proxy);
g_clear_object (&async_call->connection);
g_clear_object (&async_call->cancellable);
g_clear_error (&async_call->io_error);
@@ -261,31 +265,66 @@ async_get_connection_response (GVfsDBusDaemon *proxy,
}
static void
+socket_dir_query_info_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncDBusCall *async_call = user_data;
+ g_autoptr (GFileInfo) socket_dir_info = NULL;
+
+ socket_dir_info = g_file_query_info_finish (G_FILE (source_object),
+ res,
+ &async_call->io_error);
+ if (socket_dir_info == NULL ||
+ !g_file_info_get_attribute_boolean (socket_dir_info,
+ G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+ {
+ if (!async_call->io_error)
+ async_call->io_error = g_error_new_literal (G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED,
+ _("Permission denied"));
+
+ async_call_finish (async_call);
+ return;
+ }
+
+ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (async_call->proxy), G_VFS_DBUS_TIMEOUT_MSECS);
+
+ gvfs_dbus_daemon_call_get_connection (async_call->proxy,
+ async_call->cancellable,
+ (GAsyncReadyCallback) async_get_connection_response,
+ async_call);
+}
+
+static void
open_connection_async_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
- GVfsDBusDaemon *proxy;
AsyncDBusCall *async_call = user_data;
GError *error = NULL;
-
- proxy = gvfs_dbus_daemon_proxy_new_finish (res, &error);
- if (proxy == NULL)
+ g_autofree gchar *socket_dir_path = NULL;
+ g_autoptr (GFile) socket_dir = NULL;
+
+ async_call->proxy = gvfs_dbus_daemon_proxy_new_finish (res, &error);
+ if (async_call->proxy == NULL)
{
async_call->io_error = g_error_copy (error);
g_error_free (error);
async_call_finish (async_call);
return;
}
-
- g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_VFS_DBUS_TIMEOUT_MSECS);
-
- gvfs_dbus_daemon_call_get_connection (proxy,
- async_call->cancellable,
- (GAsyncReadyCallback) async_get_connection_response,
- async_call);
-
- g_object_unref (proxy);
+
+ /* This is needed to prevent socket leaks. */
+ socket_dir_path = gvfs_get_socket_dir ();
+ socket_dir = g_file_new_for_path (socket_dir_path);
+ g_file_query_info_async (socket_dir,
+ G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
+ G_FILE_QUERY_INFO_NONE,
+ G_PRIORITY_DEFAULT,
+ async_call->cancellable,
+ socket_dir_query_info_cb,
+ user_data);
}
static void
@@ -522,6 +561,9 @@ _g_dbus_connection_get_sync (const char *dbus_id,
gchar *address1;
GVfsDBusDaemon *daemon_proxy;
gboolean res;
+ g_autofree gchar *socket_dir_path = NULL;
+ g_autoptr (GFile) socket_dir = NULL;
+ g_autoptr (GFileInfo) socket_dir_info = NULL;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return NULL;
@@ -591,6 +633,26 @@ _g_dbus_connection_get_sync (const char *dbus_id,
if (daemon_proxy == NULL)
return NULL;
+ /* This is needed to prevent socket leaks. */
+ socket_dir_path = gvfs_get_socket_dir ();
+ socket_dir = g_file_new_for_path (socket_dir_path);
+ socket_dir_info = g_file_query_info (socket_dir,
+ G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
+ G_FILE_QUERY_INFO_NONE,
+ cancellable,
+ error);
+ if (socket_dir_info == NULL ||
+ !g_file_info_get_attribute_boolean (socket_dir_info,
+ G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+ {
+ if (error && !*error)
+ *error = g_error_new_literal (G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED,
+ _("Permission denied"));
+
+ return NULL;
+ }
+
address1 = NULL;
res = gvfs_dbus_daemon_call_get_connection_sync (daemon_proxy,
&address1,