hal/linux/udev.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 * This file defines a wrapper around libudev so we can avoid
michael@0 7 * linking directly to it and use dlopen instead.
michael@0 8 */
michael@0 9
michael@0 10 #ifndef HAL_LINUX_UDEV_H_
michael@0 11 #define HAL_LINUX_UDEV_H_
michael@0 12
michael@0 13 #include <dlfcn.h>
michael@0 14
michael@0 15 #include "mozilla/ArrayUtils.h"
michael@0 16
michael@0 17 namespace mozilla {
michael@0 18
michael@0 19 struct udev;
michael@0 20 struct udev_device;
michael@0 21 struct udev_enumerate;
michael@0 22 struct udev_list_entry;
michael@0 23 struct udev_monitor;
michael@0 24
michael@0 25 class udev_lib {
michael@0 26 public:
michael@0 27 udev_lib() : lib(nullptr),
michael@0 28 udev(nullptr) {
michael@0 29 // Be careful about ABI compat! 0 -> 1 didn't change any
michael@0 30 // symbols this code relies on, per:
michael@0 31 // https://lists.fedoraproject.org/pipermail/devel/2012-June/168227.html
michael@0 32 const char* lib_names[] = {"libudev.so.0", "libudev.so.1"};
michael@0 33 // Check whether a library is already loaded so we don't load two
michael@0 34 // conflicting libs.
michael@0 35 for (unsigned i = 0; i < ArrayLength(lib_names); i++) {
michael@0 36 lib = dlopen(lib_names[i], RTLD_NOLOAD | RTLD_LAZY | RTLD_GLOBAL);
michael@0 37 if (lib) {
michael@0 38 break;
michael@0 39 }
michael@0 40 }
michael@0 41 // If nothing loads the first time through, it means no version of libudev
michael@0 42 // was already loaded.
michael@0 43 if (!lib) {
michael@0 44 for (unsigned i = 0; i < ArrayLength(lib_names); i++) {
michael@0 45 lib = dlopen(lib_names[i], RTLD_LAZY | RTLD_GLOBAL);
michael@0 46 if (lib) {
michael@0 47 break;
michael@0 48 }
michael@0 49 }
michael@0 50 }
michael@0 51 if (lib && LoadSymbols()) {
michael@0 52 udev = udev_new();
michael@0 53 }
michael@0 54 }
michael@0 55
michael@0 56 ~udev_lib() {
michael@0 57 if (udev) {
michael@0 58 udev_unref(udev);
michael@0 59 }
michael@0 60
michael@0 61 if (lib) {
michael@0 62 dlclose(lib);
michael@0 63 }
michael@0 64 }
michael@0 65
michael@0 66 operator bool() {
michael@0 67 return udev;
michael@0 68 }
michael@0 69
michael@0 70 private:
michael@0 71 bool LoadSymbols() {
michael@0 72 #define DLSYM(s) \
michael@0 73 do { \
michael@0 74 s = (typeof(s))dlsym(lib, #s); \
michael@0 75 if (!s) return false; \
michael@0 76 } while (0)
michael@0 77
michael@0 78 DLSYM(udev_new);
michael@0 79 DLSYM(udev_unref);
michael@0 80 DLSYM(udev_device_unref);
michael@0 81 DLSYM(udev_device_new_from_syspath);
michael@0 82 DLSYM(udev_device_get_devnode);
michael@0 83 DLSYM(udev_device_get_parent_with_subsystem_devtype);
michael@0 84 DLSYM(udev_device_get_property_value);
michael@0 85 DLSYM(udev_device_get_action);
michael@0 86 DLSYM(udev_device_get_sysattr_value);
michael@0 87 DLSYM(udev_enumerate_new);
michael@0 88 DLSYM(udev_enumerate_unref);
michael@0 89 DLSYM(udev_enumerate_add_match_subsystem);
michael@0 90 DLSYM(udev_enumerate_scan_devices);
michael@0 91 DLSYM(udev_enumerate_get_list_entry);
michael@0 92 DLSYM(udev_list_entry_get_next);
michael@0 93 DLSYM(udev_list_entry_get_name);
michael@0 94 DLSYM(udev_monitor_new_from_netlink);
michael@0 95 DLSYM(udev_monitor_filter_add_match_subsystem_devtype);
michael@0 96 DLSYM(udev_monitor_enable_receiving);
michael@0 97 DLSYM(udev_monitor_get_fd);
michael@0 98 DLSYM(udev_monitor_receive_device);
michael@0 99 DLSYM(udev_monitor_unref);
michael@0 100 #undef DLSYM
michael@0 101 return true;
michael@0 102 }
michael@0 103
michael@0 104 void* lib;
michael@0 105
michael@0 106 public:
michael@0 107 struct udev* udev;
michael@0 108
michael@0 109 // Function pointers returned from dlsym.
michael@0 110 struct udev* (*udev_new)(void);
michael@0 111 void (*udev_unref)(struct udev*);
michael@0 112
michael@0 113 void (*udev_device_unref)(struct udev_device*);
michael@0 114 struct udev_device* (*udev_device_new_from_syspath)(struct udev*,
michael@0 115 const char*);
michael@0 116 const char* (*udev_device_get_devnode)(struct udev_device*);
michael@0 117 struct udev_device* (*udev_device_get_parent_with_subsystem_devtype)
michael@0 118 (struct udev_device*, const char*, const char*);
michael@0 119 const char* (*udev_device_get_property_value)(struct udev_device*,
michael@0 120 const char*);
michael@0 121 const char* (*udev_device_get_action)(struct udev_device*);
michael@0 122 const char* (*udev_device_get_sysattr_value)(struct udev_device*,
michael@0 123 const char*);
michael@0 124
michael@0 125 struct udev_enumerate* (*udev_enumerate_new)(struct udev*);
michael@0 126 void (*udev_enumerate_unref)(struct udev_enumerate*);
michael@0 127 int (*udev_enumerate_add_match_subsystem)(struct udev_enumerate*,
michael@0 128 const char*);
michael@0 129 int (*udev_enumerate_scan_devices)(struct udev_enumerate*);
michael@0 130 struct udev_list_entry* (*udev_enumerate_get_list_entry)
michael@0 131 (struct udev_enumerate*);
michael@0 132
michael@0 133 struct udev_list_entry* (*udev_list_entry_get_next)(struct udev_list_entry *);
michael@0 134 const char* (*udev_list_entry_get_name)(struct udev_list_entry*);
michael@0 135
michael@0 136 struct udev_monitor* (*udev_monitor_new_from_netlink)(struct udev*,
michael@0 137 const char*);
michael@0 138 int (*udev_monitor_filter_add_match_subsystem_devtype)
michael@0 139 (struct udev_monitor*, const char*, const char*);
michael@0 140 int (*udev_monitor_enable_receiving)(struct udev_monitor*);
michael@0 141 int (*udev_monitor_get_fd)(struct udev_monitor*);
michael@0 142 struct udev_device* (*udev_monitor_receive_device)(struct udev_monitor*);
michael@0 143 void (*udev_monitor_unref)(struct udev_monitor*);
michael@0 144 };
michael@0 145
michael@0 146 } // namespace mozilla
michael@0 147
michael@0 148 #endif // HAL_LINUX_UDEV_H_

mercurial