lib.rs (7272B)
1 /* -*- Mode: rust; rust-indent-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #![allow(non_camel_case_types)] 7 #![allow(non_upper_case_globals)] 8 9 #[macro_use] 10 extern crate lazy_static; 11 extern crate libc; 12 13 use libc::{c_void,c_int,c_char,c_ulonglong,dev_t}; 14 use libc::{RTLD_GLOBAL,RTLD_LAZY,RTLD_NOLOAD}; 15 use libc::{dlopen,dlclose,dlsym}; 16 use std::ffi::CString; 17 use std::{marker,mem,ops,ptr}; 18 19 #[repr(C)] 20 pub struct udev { 21 __private: c_void 22 } 23 24 #[repr(C)] 25 pub struct udev_list_entry { 26 __private: c_void 27 } 28 29 #[repr(C)] 30 pub struct udev_device { 31 __private: c_void 32 } 33 34 #[repr(C)] 35 pub struct udev_monitor { 36 __private: c_void 37 } 38 39 #[repr(C)] 40 pub struct udev_enumerate { 41 __private: c_void 42 } 43 44 macro_rules! ifnull { 45 ($a:expr, $b:expr) => { 46 if $a.is_null() { $b } else { $a } 47 } 48 } 49 50 struct Library(*mut c_void); 51 52 impl Library { 53 fn open(name: &'static str) -> Library { 54 let flags = RTLD_LAZY | RTLD_GLOBAL; 55 let flags_noload = flags | RTLD_NOLOAD; 56 let name = CString::new(name).unwrap(); 57 let name = name.as_ptr(); 58 59 Library(unsafe { 60 ifnull!(dlopen(name, flags_noload), dlopen(name, flags)) 61 }) 62 } 63 64 fn get(&self, name: &'static str) -> *mut c_void { 65 let name = CString::new(name).unwrap(); 66 unsafe { dlsym(self.0, name.as_ptr()) } 67 } 68 } 69 70 impl Drop for Library { 71 fn drop(&mut self) { 72 unsafe { dlclose(self.0); } 73 } 74 } 75 76 unsafe impl Sync for Library {} 77 unsafe impl Send for Library {} 78 79 lazy_static! { 80 static ref LIBRARY: Library = { 81 Library::open("libudev.so.1") 82 }; 83 } 84 85 pub struct Symbol<T> { 86 ptr: *mut c_void, 87 pd: marker::PhantomData<T> 88 } 89 90 impl<T> Symbol<T> { 91 fn new(ptr: *mut c_void) -> Self { 92 let default = Self::default as *mut c_void; 93 Self { ptr: ifnull!(ptr, default), pd: marker::PhantomData } 94 } 95 96 // This is the default symbol, used whenever dlopen() fails. 97 // Users of this library are expected to check whether udev_new() returns 98 // a nullptr, and if so they MUST NOT call any other exported functions. 99 extern "C" fn default() -> *mut c_void { 100 ptr::null_mut() 101 } 102 } 103 104 impl<T> ops::Deref for Symbol<T> { 105 type Target = T; 106 107 fn deref(&self) -> &T { 108 unsafe { mem::transmute(&self.ptr) } 109 } 110 } 111 112 unsafe impl<T: Sync + Send> Sync for Symbol<T> {} 113 unsafe impl<T: Sync + Send> Send for Symbol<T> {} 114 115 macro_rules! define { 116 ($name:ident, $type:ty) => { 117 lazy_static! { 118 pub static ref $name : Symbol<$type> = { 119 Symbol::new(LIBRARY.get(stringify!($name))) 120 }; 121 } 122 }; 123 } 124 125 // udev 126 define!(udev_new, extern "C" fn () -> *mut udev); 127 define!(udev_unref, extern "C" fn (*mut udev) -> *mut udev); 128 129 // udev_list 130 define!(udev_list_entry_get_next, extern "C" fn (*mut udev_list_entry) -> *mut udev_list_entry); 131 define!(udev_list_entry_get_name, extern "C" fn (*mut udev_list_entry) -> *const c_char); 132 define!(udev_list_entry_get_value, extern "C" fn (*mut udev_list_entry) -> *const c_char); 133 134 // udev_device 135 define!(udev_device_ref, extern "C" fn (*mut udev_device) -> *mut udev_device); 136 define!(udev_device_unref, extern "C" fn (*mut udev_device) -> *mut udev_device); 137 define!(udev_device_new_from_syspath, extern "C" fn (*mut udev, *const c_char) -> *mut udev_device); 138 define!(udev_device_get_parent, extern "C" fn (*mut udev_device) -> *mut udev_device); 139 define!(udev_device_get_devpath, extern "C" fn (*mut udev_device) -> *const c_char); 140 define!(udev_device_get_subsystem, extern "C" fn (*mut udev_device) -> *const c_char); 141 define!(udev_device_get_devtype, extern "C" fn (*mut udev_device) -> *const c_char); 142 define!(udev_device_get_syspath, extern "C" fn (*mut udev_device) -> *const c_char); 143 define!(udev_device_get_sysname, extern "C" fn (*mut udev_device) -> *const c_char); 144 define!(udev_device_get_sysnum, extern "C" fn (*mut udev_device) -> *const c_char); 145 define!(udev_device_get_devnode, extern "C" fn (*mut udev_device) -> *const c_char); 146 define!(udev_device_get_is_initialized, extern "C" fn (*mut udev_device) -> c_int); 147 define!(udev_device_get_properties_list_entry, extern "C" fn (*mut udev_device) -> *mut udev_list_entry); 148 define!(udev_device_get_property_value, extern "C" fn (*mut udev_device, *const c_char) -> *const c_char); 149 define!(udev_device_get_driver, extern "C" fn (*mut udev_device) -> *const c_char); 150 define!(udev_device_get_devnum, extern "C" fn (*mut udev_device) -> dev_t); 151 define!(udev_device_get_action, extern "C" fn (*mut udev_device) -> *const c_char); 152 define!(udev_device_get_sysattr_value, extern "C" fn (*mut udev_device, *const c_char) -> *const c_char); 153 define!(udev_device_set_sysattr_value, extern "C" fn (*mut udev_device, *const c_char, *mut c_char) -> c_int); 154 define!(udev_device_get_sysattr_list_entry, extern "C" fn (*mut udev_device) -> *mut udev_list_entry); 155 define!(udev_device_get_seqnum, extern "C" fn (*mut udev_device) -> c_ulonglong); 156 157 // udev_monitor 158 define!(udev_monitor_ref, extern "C" fn (*mut udev_monitor) -> *mut udev_monitor); 159 define!(udev_monitor_unref, extern "C" fn (*mut udev_monitor) -> *mut udev_monitor); 160 define!(udev_monitor_new_from_netlink, extern "C" fn (*mut udev, *const c_char) -> *mut udev_monitor); 161 define!(udev_monitor_enable_receiving, extern "C" fn (*mut udev_monitor) -> c_int); 162 define!(udev_monitor_get_fd, extern "C" fn (*mut udev_monitor) -> c_int); 163 define!(udev_monitor_receive_device, extern "C" fn (*mut udev_monitor) -> *mut udev_device); 164 define!(udev_monitor_filter_add_match_subsystem_devtype, extern "C" fn (*mut udev_monitor, *const c_char, *const c_char) -> c_int); 165 define!(udev_monitor_filter_add_match_tag, extern "C" fn (*mut udev_monitor, *const c_char) -> c_int); 166 define!(udev_monitor_filter_remove, extern "C" fn (*mut udev_monitor) -> c_int); 167 168 // udev_enumerate 169 define!(udev_enumerate_unref, extern "C" fn (*mut udev_enumerate) -> *mut udev_enumerate); 170 define!(udev_enumerate_new, extern "C" fn (*mut udev) -> *mut udev_enumerate); 171 define!(udev_enumerate_add_match_subsystem, extern "C" fn (*mut udev_enumerate, *const c_char) -> c_int); 172 define!(udev_enumerate_add_nomatch_subsystem, extern "C" fn (*mut udev_enumerate, *const c_char) -> c_int); 173 define!(udev_enumerate_add_match_sysattr, extern "C" fn (*mut udev_enumerate, *const c_char, *const c_char) -> c_int); 174 define!(udev_enumerate_add_nomatch_sysattr, extern "C" fn (*mut udev_enumerate, *const c_char, *const c_char) -> c_int); 175 define!(udev_enumerate_add_match_property, extern "C" fn (*mut udev_enumerate, *const c_char, *const c_char) -> c_int); 176 define!(udev_enumerate_add_match_tag, extern "C" fn (*mut udev_enumerate, *const c_char) -> c_int); 177 define!(udev_enumerate_add_match_parent, extern "C" fn (*mut udev_enumerate, *mut udev_device) -> c_int); 178 define!(udev_enumerate_add_match_is_initialized, extern "C" fn (*mut udev_enumerate) -> c_int); 179 define!(udev_enumerate_add_match_sysname, extern "C" fn (*mut udev_enumerate, *const c_char) -> c_int); 180 define!(udev_enumerate_add_syspath, extern "C" fn (*mut udev_enumerate, *const c_char) -> c_int); 181 define!(udev_enumerate_scan_devices, extern "C" fn (*mut udev_enumerate) -> c_int); 182 define!(udev_enumerate_get_list_entry, extern "C" fn (*mut udev_enumerate) -> *mut udev_list_entry);