/daemon/gvfsjobcreatemonitor.c

https://gitlab.com/mvglasow/gvfs · C · 244 lines · 179 code · 37 blank · 28 comment · 18 complexity · f35eb78f3c09c72bbdf0868358cb1a5e MD5 · raw file

  1. /* GIO - GLib Input, Output and Streaming Library
  2. *
  3. * Copyright (C) 2006-2007 Red Hat, Inc.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General
  16. * Public License along with this library; if not, write to the
  17. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  18. * Boston, MA 02110-1301, USA.
  19. *
  20. * Author: Alexander Larsson <alexl@redhat.com>
  21. */
  22. #include <config.h>
  23. #include <unistd.h>
  24. #include <sys/types.h>
  25. #include <sys/socket.h>
  26. #include <sys/un.h>
  27. #include <glib.h>
  28. #include <glib/gi18n.h>
  29. #include "gvfsjobcreatemonitor.h"
  30. G_DEFINE_TYPE (GVfsJobCreateMonitor, g_vfs_job_create_monitor, G_VFS_TYPE_JOB_DBUS)
  31. static void run (GVfsJob *job);
  32. static gboolean try (GVfsJob *job);
  33. static void create_reply (GVfsJob *job,
  34. GVfsDBusMount *object,
  35. GDBusMethodInvocation *invocation);
  36. static void
  37. g_vfs_job_create_monitor_finalize (GObject *object)
  38. {
  39. GVfsJobCreateMonitor *job;
  40. job = G_VFS_JOB_CREATE_MONITOR (object);
  41. g_free (job->filename);
  42. if (job->monitor)
  43. g_object_unref (job->monitor);
  44. if (G_OBJECT_CLASS (g_vfs_job_create_monitor_parent_class)->finalize)
  45. (*G_OBJECT_CLASS (g_vfs_job_create_monitor_parent_class)->finalize) (object);
  46. }
  47. static void
  48. g_vfs_job_create_monitor_class_init (GVfsJobCreateMonitorClass *klass)
  49. {
  50. GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  51. GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
  52. GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass);
  53. gobject_class->finalize = g_vfs_job_create_monitor_finalize;
  54. job_class->run = run;
  55. job_class->try = try;
  56. job_dbus_class->create_reply = create_reply;
  57. }
  58. static void
  59. g_vfs_job_create_monitor_init (GVfsJobCreateMonitor *job)
  60. {
  61. }
  62. static gboolean
  63. create_monitor_new_handle (GVfsDBusMount *object,
  64. GDBusMethodInvocation *invocation,
  65. const gchar *arg_path_data,
  66. guint arg_flags,
  67. GVfsBackend *backend,
  68. gboolean is_directory)
  69. {
  70. GVfsJobCreateMonitor *job;
  71. if (g_vfs_backend_invocation_first_handler (object, invocation, backend))
  72. return TRUE;
  73. job = g_object_new (G_VFS_TYPE_JOB_CREATE_MONITOR,
  74. "object", object,
  75. "invocation", invocation,
  76. NULL);
  77. job->is_directory = is_directory;
  78. job->filename = g_strdup (arg_path_data);
  79. job->backend = backend;
  80. job->flags = arg_flags;
  81. g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job));
  82. g_object_unref (job);
  83. return TRUE;
  84. }
  85. gboolean
  86. g_vfs_job_create_file_monitor_new_handle (GVfsDBusMount *object,
  87. GDBusMethodInvocation *invocation,
  88. const gchar *arg_path_data,
  89. guint arg_flags,
  90. GVfsBackend *backend)
  91. {
  92. return create_monitor_new_handle (object, invocation, arg_path_data, arg_flags, backend, FALSE);
  93. }
  94. gboolean
  95. g_vfs_job_create_directory_monitor_new_handle (GVfsDBusMount *object,
  96. GDBusMethodInvocation *invocation,
  97. const gchar *arg_path_data,
  98. guint arg_flags,
  99. GVfsBackend *backend)
  100. {
  101. return create_monitor_new_handle (object, invocation, arg_path_data, arg_flags, backend, TRUE);
  102. }
  103. void
  104. g_vfs_job_create_monitor_set_monitor (GVfsJobCreateMonitor *job,
  105. GVfsMonitor *monitor)
  106. {
  107. job->monitor = g_object_ref (monitor);
  108. }
  109. static void
  110. run (GVfsJob *job)
  111. {
  112. GVfsJobCreateMonitor *op_job = G_VFS_JOB_CREATE_MONITOR (job);
  113. GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
  114. if (op_job->is_directory)
  115. {
  116. if (class->create_dir_monitor == NULL)
  117. g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
  118. _("Operation not supported by backend"));
  119. else
  120. class->create_dir_monitor (op_job->backend,
  121. op_job,
  122. op_job->filename,
  123. op_job->flags);
  124. }
  125. else
  126. {
  127. if (class->create_file_monitor == NULL)
  128. g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
  129. _("Operation not supported by backend"));
  130. else
  131. class->create_file_monitor (op_job->backend,
  132. op_job,
  133. op_job->filename,
  134. op_job->flags);
  135. }
  136. }
  137. static gboolean
  138. try (GVfsJob *job)
  139. {
  140. GVfsJobCreateMonitor *op_job = G_VFS_JOB_CREATE_MONITOR (job);
  141. GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
  142. if (op_job->is_directory)
  143. {
  144. if (class->try_create_dir_monitor == NULL)
  145. {
  146. if (class->create_dir_monitor == NULL)
  147. {
  148. g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
  149. _("Operation not supported by backend"));
  150. return TRUE;
  151. }
  152. return FALSE;
  153. }
  154. return class->try_create_dir_monitor (op_job->backend,
  155. op_job,
  156. op_job->filename,
  157. op_job->flags);
  158. }
  159. else
  160. {
  161. if (class->try_create_file_monitor == NULL)
  162. {
  163. if (class->create_file_monitor == NULL)
  164. {
  165. g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
  166. _("Operation not supported by backend"));
  167. return TRUE;
  168. }
  169. return FALSE;
  170. }
  171. return class->try_create_file_monitor (op_job->backend,
  172. op_job,
  173. op_job->filename,
  174. op_job->flags);
  175. }
  176. }
  177. static gboolean
  178. unref_monitor_timeout (gpointer data)
  179. {
  180. GVfsMonitor *monitor = data;
  181. /* Unref the refcount for the VfsMonitor that we returned.
  182. If we didn't get an initial subscriber this is where we free the
  183. monitor */
  184. g_object_unref (monitor);
  185. return FALSE;
  186. }
  187. /* Might be called on an i/o thread */
  188. static void
  189. create_reply (GVfsJob *job,
  190. GVfsDBusMount *object,
  191. GDBusMethodInvocation *invocation)
  192. {
  193. GVfsJobCreateMonitor *op_job = G_VFS_JOB_CREATE_MONITOR (job);
  194. const char *obj_path;
  195. /* Keep the monitor alive for at least 5 seconds
  196. to allow for a subscribe call to come in and bump
  197. the refcount */
  198. g_object_ref (op_job->monitor);
  199. g_timeout_add_seconds (5,
  200. unref_monitor_timeout,
  201. op_job->monitor);
  202. obj_path = g_vfs_monitor_get_object_path (op_job->monitor);
  203. if (op_job->is_directory)
  204. gvfs_dbus_mount_complete_create_directory_monitor (object, invocation, obj_path);
  205. else
  206. gvfs_dbus_mount_complete_create_file_monitor (object, invocation, obj_path);
  207. }