about summary refs log tree commit diff
path: root/src/rt/rust_builtin.cpp
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-20 10:31:17 -0700
committerbors <bors@rust-lang.org>2013-10-20 10:31:17 -0700
commit69860b79b8f4882426fb5755c6d00e6717adeb38 (patch)
tree6701ec0cd1c0590e262be00f736511486a929012 /src/rt/rust_builtin.cpp
parent424c171da5e9881f3d5588f22c3794b53b2695e1 (diff)
parent3e53c929a2298e59d9abd3973094db3d34d59e98 (diff)
downloadrust-69860b79b8f4882426fb5755c6d00e6717adeb38.tar.gz
rust-69860b79b8f4882426fb5755c6d00e6717adeb38.zip
auto merge of #9812 : HNO3/rust/windows-utf8, r=alexcrichton
This fixes #9418 and #9618, and potential problems related to directory walking.
Diffstat (limited to 'src/rt/rust_builtin.cpp')
-rw-r--r--src/rt/rust_builtin.cpp46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 755235a9138..17f05b59090 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -106,7 +106,7 @@ rust_list_dir_wfd_fp_buf(void* wfd) {
 #endif
 
 extern "C" CDECL int
-rust_path_is_dir(char *path) {
+rust_path_is_dir(const char *path) {
     struct stat buf;
     if (stat(path, &buf)) {
         return 0;
@@ -115,7 +115,25 @@ rust_path_is_dir(char *path) {
 }
 
 extern "C" CDECL int
-rust_path_exists(char *path) {
+#if defined(__WIN32__)
+rust_path_is_dir_u16(const wchar_t *path) {
+    struct _stat buf;
+    // Don't use GetFileAttributesW, it cannot get attributes of
+    // some system files (e.g. pagefile.sys).
+    if (_wstat(path, &buf)) {
+        return 0;
+    }
+    return S_ISDIR(buf.st_mode);
+}
+#else
+rust_path_is_dir_u16(const void *path) {
+    // Wide version of function is only used on Windows.
+    return 0;
+}
+#endif
+
+extern "C" CDECL int
+rust_path_exists(const char *path) {
     struct stat buf;
     if (stat(path, &buf)) {
         return 0;
@@ -123,6 +141,22 @@ rust_path_exists(char *path) {
     return 1;
 }
 
+extern "C" CDECL int
+#if defined(__WIN32__)
+rust_path_exists_u16(const wchar_t *path) {
+    struct _stat buf;
+    if (_wstat(path, &buf)) {
+        return 0;
+    }
+    return 1;
+}
+#else
+rust_path_exists_u16(const void *path) {
+    // Wide version of function is only used on Windows.
+    return 0;
+}
+#endif
+
 extern "C" CDECL FILE* rust_get_stdin() {return stdin;}
 extern "C" CDECL FILE* rust_get_stdout() {return stdout;}
 extern "C" CDECL FILE* rust_get_stderr() {return stderr;}
@@ -293,8 +327,12 @@ rust_localtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
     const char* zone = NULL;
 #if defined(__WIN32__)
     int32_t gmtoff = -timezone;
-    char buffer[64];
-    if (strftime(buffer, sizeof(buffer), "%Z", &tm) > 0) {
+    wchar_t wbuffer[64];
+    char buffer[256];
+    // strftime("%Z") can contain non-UTF-8 characters on non-English locale (issue #9418),
+    // so time zone should be converted from UTF-16 string set by wcsftime.
+    if (wcsftime(wbuffer, sizeof(wbuffer) / sizeof(wchar_t), L"%Z", &tm) > 0) {
+        WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, sizeof(buffer), NULL, NULL);
         zone = buffer;
     }
 #else