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

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

mercurial