]> git.proxmox.com Git - rustc.git/blob - vendor/libloading/tests/functions.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / vendor / libloading / tests / functions.rs
1 #[cfg(windows)]
2 extern crate winapi;
3
4 extern crate libloading;
5 use libloading::{Symbol, Library};
6
7 const LIBPATH: &'static str = concat!(env!("OUT_DIR"), "/libtest_helpers.module");
8
9 fn make_helpers() {
10 static ONCE: ::std::sync::Once = ::std::sync::Once::new();
11 ONCE.call_once(|| {
12 let rustc = option_env!("RUSTC").unwrap_or_else(|| { "rustc".into() });
13 let mut cmd = ::std::process::Command::new(rustc);
14 cmd
15 .arg("src/test_helpers.rs")
16 .arg("-o")
17 .arg(LIBPATH)
18 .arg("--target")
19 .arg(env!("LIBLOADING_TEST_TARGET"))
20 .arg("-O");
21
22 cmd
23 .output()
24 .expect("could not compile the test helpers!");
25 });
26 }
27
28 #[test]
29 fn test_id_u32() {
30 make_helpers();
31 let lib = Library::new(LIBPATH).unwrap();
32 unsafe {
33 let f: Symbol<unsafe extern fn(u32) -> u32> = lib.get(b"test_identity_u32\0").unwrap();
34 assert_eq!(42, f(42));
35 }
36 }
37
38 #[repr(C)]
39 #[derive(Clone,Copy,PartialEq,Debug)]
40 struct S {
41 a: u64,
42 b: u32,
43 c: u16,
44 d: u8
45 }
46
47 #[test]
48 fn test_id_struct() {
49 make_helpers();
50 let lib = Library::new(LIBPATH).unwrap();
51 unsafe {
52 let f: Symbol<unsafe extern fn(S) -> S> = lib.get(b"test_identity_struct\0").unwrap();
53 assert_eq!(S { a: 1, b: 2, c: 3, d: 4 }, f(S { a: 1, b: 2, c: 3, d: 4 }));
54 }
55 }
56
57 #[test]
58 fn test_0_no_0() {
59 make_helpers();
60 let lib = Library::new(LIBPATH).unwrap();
61 unsafe {
62 let f: Symbol<unsafe extern fn(S) -> S> = lib.get(b"test_identity_struct\0").unwrap();
63 let f2: Symbol<unsafe extern fn(S) -> S> = lib.get(b"test_identity_struct").unwrap();
64 assert_eq!(*f, *f2);
65 }
66 }
67
68 #[test]
69 fn wrong_name_fails() {
70 Library::new(concat!(env!("OUT_DIR"), "/libtest_help")).err().unwrap();
71 }
72
73 #[test]
74 fn missing_symbol_fails() {
75 make_helpers();
76 let lib = Library::new(LIBPATH).unwrap();
77 unsafe {
78 lib.get::<*mut ()>(b"test_does_not_exist").err().unwrap();
79 lib.get::<*mut ()>(b"test_does_not_exist\0").err().unwrap();
80 }
81 }
82
83 #[test]
84 fn interior_null_fails() {
85 make_helpers();
86 let lib = Library::new(LIBPATH).unwrap();
87 unsafe {
88 lib.get::<*mut ()>(b"test_does\0_not_exist").err().unwrap();
89 lib.get::<*mut ()>(b"test\0_does_not_exist\0").err().unwrap();
90 }
91 }
92
93 #[test]
94 fn test_incompatible_type() {
95 make_helpers();
96 let lib = Library::new(LIBPATH).unwrap();
97 unsafe {
98 assert!(match lib.get::<()>(b"test_identity_u32\0") {
99 Err(libloading::Error::IncompatibleSize) => true,
100 _ => false,
101 })
102 }
103 }
104
105 #[test]
106 fn test_incompatible_type_named_fn() {
107 make_helpers();
108 unsafe fn get<'a, T>(l: &'a Library, _: T) -> Result<Symbol<'a, T>, libloading::Error> {
109 l.get::<T>(b"test_identity_u32\0")
110 }
111 let lib = Library::new(LIBPATH).unwrap();
112 unsafe {
113 assert!(match get(&lib, test_incompatible_type_named_fn) {
114 Err(libloading::Error::IncompatibleSize) => true,
115 _ => false,
116 })
117 }
118 }
119
120 #[test]
121 fn test_static_u32() {
122 make_helpers();
123 let lib = Library::new(LIBPATH).unwrap();
124 unsafe {
125 let var: Symbol<*mut u32> = lib.get(b"TEST_STATIC_U32\0").unwrap();
126 **var = 42;
127 let help: Symbol<unsafe extern fn() -> u32> = lib.get(b"test_get_static_u32\0").unwrap();
128 assert_eq!(42, help());
129 }
130 }
131
132 #[test]
133 fn test_static_ptr() {
134 make_helpers();
135 let lib = Library::new(LIBPATH).unwrap();
136 unsafe {
137 let var: Symbol<*mut *mut ()> = lib.get(b"TEST_STATIC_PTR\0").unwrap();
138 **var = *var as *mut _;
139 let works: Symbol<unsafe extern fn() -> bool> =
140 lib.get(b"test_check_static_ptr\0").unwrap();
141 assert!(works());
142 }
143 }
144
145 #[cfg(unix)]
146 #[test]
147 fn library_this_get() {
148 use libloading::os::unix::Library;
149 make_helpers();
150 let _lib = Library::new(LIBPATH).unwrap();
151 let this = Library::this();
152 // SAFE: functions are never called
153 unsafe {
154 // Library we loaded in `_lib` (should be RTLD_LOCAL).
155 // FIXME: inconsistent behaviour between macos and other posix systems
156 // assert!(this.get::<unsafe extern "C" fn()>(b"test_identity_u32").is_err());
157 // Something obscure from libc...
158 assert!(this.get::<unsafe extern "C" fn()>(b"freopen").is_ok());
159 }
160 }
161
162 #[cfg(windows)]
163 #[test]
164 fn library_this() {
165 use libloading::os::windows::Library;
166 make_helpers();
167 let _lib = Library::new(LIBPATH).unwrap();
168 let this = Library::this().expect("this library");
169 // SAFE: functions are never called
170 unsafe {
171 // Library we loaded in `_lib`.
172 assert!(this.get::<unsafe extern "C" fn()>(b"test_identity_u32").is_err());
173 // Something "obscure" from kernel32...
174 assert!(this.get::<unsafe extern "C" fn()>(b"GetLastError").is_err());
175 }
176 }
177
178 #[cfg(windows)]
179 #[test]
180 fn works_getlasterror() {
181 use winapi::um::errhandlingapi;
182 use winapi::shared::minwindef::DWORD;
183 use libloading::os::windows::{Library, Symbol};
184
185 let lib = Library::new("kernel32.dll").unwrap();
186 let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
187 lib.get(b"GetLastError").unwrap()
188 };
189 unsafe {
190 errhandlingapi::SetLastError(42);
191 assert_eq!(errhandlingapi::GetLastError(), gle())
192 }
193 }
194
195 #[cfg(windows)]
196 #[test]
197 fn works_getlasterror0() {
198 use winapi::um::errhandlingapi;
199 use winapi::shared::minwindef::DWORD;
200 use libloading::os::windows::{Library, Symbol};
201
202 let lib = Library::new("kernel32.dll").unwrap();
203 let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
204 lib.get(b"GetLastError\0").unwrap()
205 };
206 unsafe {
207 errhandlingapi::SetLastError(42);
208 assert_eq!(errhandlingapi::GetLastError(), gle())
209 }
210 }