about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlan Williams <mralert@gmail.com>2014-05-07 11:06:15 -0700
committerAlan Williams <mralert@gmail.com>2014-05-07 11:20:28 -0700
commitfacd1270c636beb7c2c8153424ffd6dda4179d59 (patch)
treeb29d80f2b9677297d62fee4cccd2b1274ff4b921
parent8543e1b6ced6547057a07f43c413193deb3f9cb1 (diff)
downloadrust-facd1270c636beb7c2c8153424ffd6dda4179d59.tar.gz
rust-facd1270c636beb7c2c8153424ffd6dda4179d59.zip
Move Windows compatibility layer to libnative
-rw-r--r--src/libnative/io/c_win32.rs93
-rw-r--r--src/libnative/io/file_win32.rs4
-rw-r--r--src/libnative/lib.rs1
-rw-r--r--src/libstd/os.rs96
4 files changed, 96 insertions, 98 deletions
diff --git a/src/libnative/io/c_win32.rs b/src/libnative/io/c_win32.rs
index 6c84424e97a..382746decd2 100644
--- a/src/libnative/io/c_win32.rs
+++ b/src/libnative/io/c_win32.rs
@@ -62,3 +62,96 @@ extern "system" {
 
     pub fn CancelIo(hFile: libc::HANDLE) -> libc::BOOL;
 }
+
+pub mod compat {
+    use std::intrinsics::{atomic_store_relaxed, transmute};
+    use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
+    use std::os::win32::as_utf16_p;
+
+    extern "system" {
+        fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
+        fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
+    }
+
+    // store_func() is idempotent, so using relaxed ordering for the atomics should be enough.
+    // This way, calling a function in this compatibility layer (after it's loaded) shouldn't
+    // be any slower than a regular DLL call.
+    unsafe fn store_func<T: Copy>(ptr: *mut T, module: &str, symbol: &str, fallback: T) {
+        as_utf16_p(module, |module| {
+            symbol.with_c_str(|symbol| {
+                let handle = GetModuleHandleW(module);
+                let func: Option<T> = transmute(GetProcAddress(handle, symbol));
+                atomic_store_relaxed(ptr, func.unwrap_or(fallback))
+            })
+        })
+    }
+
+    /// Macro for creating a compatibility fallback for a Windows function
+    ///
+    /// # Example
+    /// ```
+    /// compat_fn!(adll32::SomeFunctionW(_arg: LPCWSTR) {
+    ///     // Fallback implementation
+    /// })
+    /// ```
+    ///
+    /// Note that arguments unused by the fallback implementation should not be called `_` as
+    /// they are used to be passed to the real function if available.
+    macro_rules! compat_fn(
+        ($module:ident::$symbol:ident($($argname:ident: $argtype:ty),*)
+                                      -> $rettype:ty $fallback:block) => (
+            #[inline(always)]
+            pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
+                static mut ptr: extern "system" fn($($argname: $argtype),*) -> $rettype = thunk;
+
+                extern "system" fn thunk($($argname: $argtype),*) -> $rettype {
+                    unsafe {
+                        ::io::c::compat::store_func(&mut ptr,
+                                                             stringify!($module),
+                                                             stringify!($symbol),
+                                                             fallback);
+                        ::std::intrinsics::atomic_load_relaxed(&ptr)($($argname),*)
+                    }
+                }
+
+                extern "system" fn fallback($($argname: $argtype),*) -> $rettype $fallback
+
+                ::std::intrinsics::atomic_load_relaxed(&ptr)($($argname),*)
+            }
+        );
+
+        ($module:ident::$symbol:ident($($argname:ident: $argtype:ty),*) $fallback:block) => (
+            compat_fn!($module::$symbol($($argname: $argtype),*) -> () $fallback)
+        )
+    )
+
+    /// Compatibility layer for functions in `kernel32.dll`
+    ///
+    /// Latest versions of Windows this is needed for:
+    ///
+    /// * `CreateSymbolicLinkW`: Windows XP, Windows Server 2003
+    /// * `GetFinalPathNameByHandleW`: Windows XP, Windows Server 2003
+    pub mod kernel32 {
+        use libc::types::os::arch::extra::{DWORD, LPCWSTR, BOOLEAN, HANDLE};
+        use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
+
+        extern "system" {
+            fn SetLastError(dwErrCode: DWORD);
+        }
+
+        compat_fn!(kernel32::CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
+                                                 _lpTargetFileName: LPCWSTR,
+                                                 _dwFlags: DWORD) -> BOOLEAN {
+            unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); }
+            0
+        })
+
+        compat_fn!(kernel32::GetFinalPathNameByHandleW(_hFile: HANDLE,
+                                                       _lpszFilePath: LPCWSTR,
+                                                       _cchFilePath: DWORD,
+                                                       _dwFlags: DWORD) -> DWORD {
+            unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); }
+            0
+        })
+    }
+}
diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs
index ea105b267c1..1c69392165d 100644
--- a/src/libnative/io/file_win32.rs
+++ b/src/libnative/io/file_win32.rs
@@ -408,7 +408,7 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
 
 pub fn readlink(p: &CString) -> IoResult<Path> {
     // FIXME: I have a feeling that this reads intermediate symlinks as well.
-    use std::os::win32::compat::kernel32::GetFinalPathNameByHandleW;
+    use io::c::compat::kernel32::GetFinalPathNameByHandleW;
     let handle = unsafe {
         as_utf16_p(p.as_str().unwrap(), |p| {
             libc::CreateFileW(p,
@@ -441,7 +441,7 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
 }
 
 pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
-    use std::os::win32::compat::kernel32::CreateSymbolicLinkW;
+    use io::c::compat::kernel32::CreateSymbolicLinkW;
     super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
         as_utf16_p(dst.as_str().unwrap(), |dst| {
             unsafe { CreateSymbolicLinkW(dst, src, 0) }
diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs
index 4c0c4dcc18e..6309e4df40e 100644
--- a/src/libnative/lib.rs
+++ b/src/libnative/lib.rs
@@ -50,6 +50,7 @@
        html_root_url = "http://static.rust-lang.org/doc/master")]
 #![deny(unused_result, unused_must_use)]
 #![allow(non_camel_case_types)]
+#![feature(macro_rules)]
 
 // NB this crate explicitly does *not* allow glob imports, please seriously
 //    consider whether they're needed before adding that feature here (the
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 0458b9135f6..071aae974db 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -145,102 +145,6 @@ pub mod win32 {
         t.push(0u16);
         f(t.as_ptr())
     }
-
-    pub mod compat {
-        use kinds::Copy;
-        use option::Option;
-        use c_str::ToCStr;
-        use intrinsics::{atomic_store_relaxed, transmute};
-        use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
-        use os::win32::as_utf16_p;
-
-        extern "system" {
-            fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
-            fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
-        }
-
-        // store_func() is idempotent, so using relaxed ordering for the atomics should be enough.
-        // This way, calling a function in this compatibility layer (after it's loaded) shouldn't
-        // be any slower than a regular DLL call.
-        unsafe fn store_func<T: Copy>(ptr: *mut T, module: &str, symbol: &str, fallback: T) {
-            as_utf16_p(module, |module| {
-                symbol.with_c_str(|symbol| {
-                    let handle = GetModuleHandleW(module);
-                    let func: Option<T> = transmute(GetProcAddress(handle, symbol));
-                    atomic_store_relaxed(ptr, func.unwrap_or(fallback))
-                })
-            })
-        }
-
-        /// Macro for creating a compatibility fallback for a Windows function
-        ///
-        /// # Example
-        /// ```
-        /// compat_fn!(adll32::SomeFunctionW(_arg: LPCWSTR) {
-        ///     // Fallback implementation
-        /// })
-        /// ```
-        ///
-        /// Note that arguments unused by the fallback implementation should not be called `_` as
-        /// they are used to be passed to the real function if available.
-        macro_rules! compat_fn(
-            ($module:ident::$symbol:ident($($argname:ident: $argtype:ty),*)
-                                          -> $rettype:ty $fallback:block) => (
-                #[inline(always)]
-                pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
-                    static mut ptr: extern "system" fn($($argname: $argtype),*) -> $rettype = thunk;
-
-                    extern "system" fn thunk($($argname: $argtype),*) -> $rettype {
-                        unsafe {
-                            ::os::win32::compat::store_func(&mut ptr,
-                                                                 stringify!($module),
-                                                                 stringify!($symbol),
-                                                                 fallback);
-                            ::intrinsics::atomic_load_relaxed(&ptr)($($argname),*)
-                        }
-                    }
-
-                    extern "system" fn fallback($($argname: $argtype),*) -> $rettype $fallback
-
-                    ::intrinsics::atomic_load_relaxed(&ptr)($($argname),*)
-                }
-            );
-
-            ($module:ident::$symbol:ident($($argname:ident: $argtype:ty),*) $fallback:block) => (
-                compat_fn!($module::$symbol($($argname: $argtype),*) -> () $fallback)
-            )
-        )
-
-        /// Compatibility layer for functions in `kernel32.dll`
-        ///
-        /// Latest versions of Windows this is needed for:
-        ///
-        /// * `CreateSymbolicLinkW`: Windows XP, Windows Server 2003
-        /// * `GetFinalPathNameByHandleW`: Windows XP, Windows Server 2003
-        pub mod kernel32 {
-            use libc::types::os::arch::extra::{DWORD, LPCWSTR, BOOLEAN, HANDLE};
-            use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
-
-            extern "system" {
-                fn SetLastError(dwErrCode: DWORD);
-            }
-
-            compat_fn!(kernel32::CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
-                                                     _lpTargetFileName: LPCWSTR,
-                                                     _dwFlags: DWORD) -> BOOLEAN {
-                unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); }
-                0
-            })
-
-            compat_fn!(kernel32::GetFinalPathNameByHandleW(_hFile: HANDLE,
-                                                           _lpszFilePath: LPCWSTR,
-                                                           _cchFilePath: DWORD,
-                                                           _dwFlags: DWORD) -> DWORD {
-                unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); }
-                0
-            })
-        }
-    }
 }
 
 /*