diff options
Diffstat (limited to 'src/backends/native/meta-device-pool.c')
-rw-r--r-- | src/backends/native/meta-device-pool.c | 390 |
1 files changed, 0 insertions, 390 deletions
diff --git a/src/backends/native/meta-device-pool.c b/src/backends/native/meta-device-pool.c deleted file mode 100644 index 8bbbe3e34..000000000 --- a/src/backends/native/meta-device-pool.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (C) 2013-2021 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include "config.h" - -#include "backends/native/meta-device-pool-private.h" - -#include <fcntl.h> -#include <gio/gunixfdlist.h> -#include <sys/stat.h> -#include <sys/stat.h> -#include <sys/sysmacros.h> -#include <sys/types.h> - -#include "backends/native/meta-launcher.h" -#include "meta/util.h" - -#include "meta-dbus-login1.h" - -struct _MetaDeviceFile -{ - MetaDevicePool *pool; - - grefcount ref_count; - - char *path; - int major; - int minor; - int fd; - MetaDeviceFileFlags flags; - uint32_t tags[META_DEVICE_FILE_N_TAGS]; -}; - -struct _MetaDevicePool -{ - GObject parent; - - MetaDbusLogin1Session *session_proxy; - - GMutex mutex; - - GList *files; -}; - -G_DEFINE_TYPE (MetaDevicePool, meta_device_pool, G_TYPE_OBJECT) - -static void -release_device_file (MetaDevicePool *pool, - MetaDeviceFile *file); - -static MetaDeviceFile * -meta_device_file_new (MetaDevicePool *pool, - const char *path, - int major, - int minor, - int fd, - MetaDeviceFileFlags flags) -{ - MetaDeviceFile *file; - - file = g_new0 (MetaDeviceFile, 1); - - file->pool = pool; - g_ref_count_init (&file->ref_count); - - file->path = g_strdup (path); - file->major = major; - file->minor = minor; - file->fd = fd; - file->flags = flags; - - return file; -} - -static void -meta_device_file_free (MetaDeviceFile *file) -{ - g_free (file->path); - g_free (file); -} - -int -meta_device_file_get_fd (MetaDeviceFile *device_file) -{ - g_assert (!g_ref_count_compare (&device_file->ref_count, 0)); - - return device_file->fd; -} - -const char * -meta_device_file_get_path (MetaDeviceFile *device_file) -{ - return device_file->path; -} - -void -meta_device_file_tag (MetaDeviceFile *device_file, - MetaDeviceFileTags tag, - uint32_t value) -{ - device_file->tags[tag] |= value; -} - -uint32_t -meta_device_file_has_tag (MetaDeviceFile *device_file, - MetaDeviceFileTags tag, - uint32_t value) -{ - return (device_file->tags[tag] & value) == value; -} - -static MetaDeviceFile * -meta_device_file_acquire_locked (MetaDeviceFile *file) -{ - g_ref_count_inc (&file->ref_count); - return file; -} - -MetaDeviceFile * -meta_device_file_acquire (MetaDeviceFile *file) -{ - g_mutex_lock (&file->pool->mutex); - meta_topic (META_DEBUG_BACKEND, "Acquiring device file '%s'", file->path); - meta_device_file_acquire_locked (file); - g_mutex_unlock (&file->pool->mutex); - - return file; -} - -void -meta_device_file_release (MetaDeviceFile *file) -{ - g_warn_if_fail (file->fd != -1); - - release_device_file (file->pool, file); -} - -MetaDevicePool * -meta_device_file_get_pool (MetaDeviceFile *device_file) -{ - return device_file->pool; -} - -static MetaDeviceFile * -find_device_file_from_path (MetaDevicePool *pool, - const char *path) -{ - GList *l; - - for (l = pool->files; l; l = l->next) - { - MetaDeviceFile *file = l->data; - - if (g_strcmp0 (file->path, path) == 0) - return file; - } - - return NULL; -} - -static gboolean -take_device (MetaDbusLogin1Session *session_proxy, - int dev_major, - int dev_minor, - int *out_fd, - GCancellable *cancellable, - GError **error) -{ - g_autoptr (GVariant) fd_variant = NULL; - g_autoptr (GUnixFDList) fd_list = NULL; - int fd = -1; - - if (!meta_dbus_login1_session_call_take_device_sync (session_proxy, - dev_major, - dev_minor, - NULL, - &fd_variant, - NULL, /* paused */ - &fd_list, - cancellable, - error)) - return FALSE; - - fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error); - if (fd == -1) - return FALSE; - - *out_fd = fd; - return TRUE; -} - -static gboolean -get_device_info_from_path (const char *path, - int *out_major, - int *out_minor) -{ - int ret; - struct stat st; - - ret = stat (path, &st); - if (ret < 0 || !S_ISCHR (st.st_mode)) - return FALSE; - - *out_major = major (st.st_rdev); - *out_minor = minor (st.st_rdev); - return TRUE; -} - -MetaDeviceFile * -meta_device_pool_open (MetaDevicePool *pool, - const char *path, - MetaDeviceFileFlags flags, - GError **error) -{ - g_autoptr (GMutexLocker) locker = NULL; - MetaDeviceFile *file; - int major = -1, minor = -1; - int fd; - - locker = g_mutex_locker_new (&pool->mutex); - - file = find_device_file_from_path (pool, path); - if (file) - { - g_warn_if_fail (file->flags == flags); - meta_device_file_acquire_locked (file); - return file; - } - - if (flags & META_DEVICE_FILE_FLAG_TAKE_CONTROL) - { - meta_topic (META_DEBUG_BACKEND, - "Opening and taking control of device file '%s'", - path); - - if (!pool->session_proxy) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Can't take control without logind session"); - return NULL; - } - - if (!get_device_info_from_path (path, &major, &minor)) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_NOT_FOUND, - "Could not get device info for path %s: %m", path); - return NULL; - } - - if (!take_device (pool->session_proxy, major, minor, &fd, NULL, error)) - return NULL; - } - else - { - int open_flags; - - meta_topic (META_DEBUG_BACKEND, - "Opening device file '%s'", - path); - - if (flags & META_DEVICE_FILE_FLAG_READ_ONLY) - open_flags = O_RDONLY; - else - open_flags = O_RDWR; - open_flags |= O_CLOEXEC; - - do - { - fd = open (path, open_flags); - } - while (fd == -1 && errno == EINTR); - - if (fd == -1) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "Failed to open device '%s': %s", - path, g_strerror (errno)); - return NULL; - } - } - - file = meta_device_file_new (pool, path, major, minor, fd, flags); - pool->files = g_list_prepend (pool->files, file); - - return file; -} - -static void -release_device_file (MetaDevicePool *pool, - MetaDeviceFile *file) -{ - g_autoptr (GMutexLocker) locker = NULL; - g_autoptr (GError) error = NULL; - - locker = g_mutex_locker_new (&pool->mutex); - - meta_topic (META_DEBUG_BACKEND, "Releasing device file '%s'", file->path); - - if (!g_ref_count_dec (&file->ref_count)) - return; - - pool->files = g_list_remove (pool->files, file); - - if (file->flags & META_DEVICE_FILE_FLAG_TAKE_CONTROL) - { - MetaDbusLogin1Session *session_proxy; - - meta_topic (META_DEBUG_BACKEND, - "Releasing control of and closing device file '%s'", - file->path); - - session_proxy = pool->session_proxy; - if (!meta_dbus_login1_session_call_release_device_sync (session_proxy, - file->major, - file->minor, - NULL, &error)) - { - g_warning ("Could not release device '%s' (%d,%d): %s", - file->path, - file->major, file->minor, - error->message); - } - } - else - { - meta_topic (META_DEBUG_BACKEND, - "Closing device file '%s'", - file->path); - } - - close (file->fd); - - meta_device_file_free (file); -} - -MetaDevicePool * -meta_device_pool_new (MetaLauncher *launcher) -{ - MetaDevicePool *pool; - - pool = g_object_new (META_TYPE_DEVICE_POOL, NULL); - - if (launcher) - pool->session_proxy = meta_launcher_get_session_proxy (launcher); - - return pool; -} - -static void -meta_device_pool_finalize (GObject *object) -{ - MetaDevicePool *pool = META_DEVICE_POOL (object); - - g_mutex_clear (&pool->mutex); - g_warn_if_fail (!pool->files); - - G_OBJECT_CLASS (meta_device_pool_parent_class)->finalize (object); -} - -static void -meta_device_pool_init (MetaDevicePool *pool) -{ - g_mutex_init (&pool->mutex); -} - -static void -meta_device_pool_class_init (MetaDevicePoolClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = meta_device_pool_finalize; -} |