about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLuqman Aden <laden@csclub.uwaterloo.ca>2013-02-11 23:07:29 -0500
committerLuqman Aden <laden@csclub.uwaterloo.ca>2013-02-11 23:49:49 -0500
commit625fac3c7eea1d28a38f0636b100b60dd4be15aa (patch)
treea8a712c4c8cf9caafca4cba9e76223c83b742c91 /src
parent9877d98b8f91be7e1494e84d685882996b84c877 (diff)
downloadrust-625fac3c7eea1d28a38f0636b100b60dd4be15aa.tar.gz
rust-625fac3c7eea1d28a38f0636b100b60dd4be15aa.zip
core: Rewrite last_os_error in Rust for windows as well.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/os.rs36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/libcore/os.rs b/src/libcore/os.rs
index 8abbce0649d..d067a83c2e6 100644
--- a/src/libcore/os.rs
+++ b/src/libcore/os.rs
@@ -808,7 +808,7 @@ pub fn errno() -> uint {
     }
 
     unsafe {
-        GetLastError() as uint;
+        GetLastError() as uint
     }
 }
 
@@ -852,15 +852,45 @@ pub fn last_os_error() -> ~str {
             if err < 0 {
                 die!(~"strerror_r failure");
             }
-            
+
             str::raw::from_c_str(&buf[0])
         }
     }
 
     #[cfg(windows)]
     fn strerror() -> ~str {
+        use libc::types::os::arch::extra::DWORD;
+        use libc::types::os::arch::extra::LPSTR;
+        use libc::types::os::arch::extra::LPVOID;
+
+        #[link_name = "kernel32"]
+        #[abi = "stdcall"]
+        extern {
+            unsafe fn FormatMessageA(flags: DWORD, lpSrc: LPVOID,
+                                     msgId: DWORD, langId: DWORD,
+                                     buf: LPSTR, nsize: DWORD,
+                                     args: *c_void) -> DWORD;
+        }
+
+        const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
+        const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
+
+        let mut buf = [0 as c_char, ..TMPBUF_SZ];
+
+        // This value is calculated from the macro
+        // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
+        let langId = 0x0800 as DWORD;
+        let err = errno() as DWORD;
         unsafe {
-            rustrt::last_os_error()
+            let res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+                                     FORMAT_MESSAGE_IGNORE_INSERTS,
+                                     ptr::mut_null(), err, langId,
+                                     &mut buf[0], TMPBUF_SZ as DWORD, ptr::null());
+            if res == 0 {
+                die!(fmt!("[%?] FormatMessage failure", errno()));
+            }
+
+            str::raw::from_c_str(&buf[0])
         }
     }