| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | |
| 8 | 8 | #include "os.hpp" |
| 9 | 9 | #include "buffer.hpp" |
| 10 | #include "heap.hpp" |
| 10 | 11 | #include "util.hpp" |
| 11 | 12 | #include "error.hpp" |
| 12 | 13 | #include "util_base.hpp" |
| ... | ... | @@ -78,6 +79,7 @@ typedef SSIZE_T ssize_t; |
| 78 | 79 | |
| 79 | 80 | #if defined(ZIG_OS_WINDOWS) |
| 80 | 81 | static void utf16le_ptr_to_utf8(Buf *out, WCHAR *utf16le); |
| 82 | static size_t utf8_to_utf16le(WCHAR *utf16_le, Slice<uint8_t> utf8); |
| 81 | 83 | static uint64_t windows_perf_freq; |
| 82 | 84 | #elif defined(__MACH__) |
| 83 | 85 | static clock_serv_t macos_calendar_clock; |
| ... | ... | @@ -153,15 +155,21 @@ static void os_spawn_process_windows(ZigList<const char *> &args, Termination *t |
| 153 | 155 | os_windows_create_command_line(&command_line, args); |
| 154 | 156 | |
| 155 | 157 | PROCESS_INFORMATION piProcInfo = {0}; |
| 156 | | STARTUPINFO siStartInfo = {0}; |
| 157 | | siStartInfo.cb = sizeof(STARTUPINFO); |
| 158 | STARTUPINFOW siStartInfo = {0}; |
| 159 | siStartInfo.cb = sizeof(STARTUPINFOW); |
| 158 | 160 | |
| 159 | | const char *exe = args.at(0); |
| 160 | | BOOL success = CreateProcessA(exe, buf_ptr(&command_line), nullptr, nullptr, TRUE, 0, nullptr, nullptr, |
| 161 | Slice<uint8_t> exe_slice = str(args.at(0)); |
| 162 | auto exe_utf16_slice = Slice<WCHAR>::alloc(exe_slice.len + 1); |
| 163 | exe_utf16_slice.ptr[utf8_to_utf16le(exe_utf16_slice.ptr, exe_slice)] = 0; |
| 164 | |
| 165 | auto command_line_utf16 = Slice<WCHAR>::alloc(buf_len(&command_line) + 1); |
| 166 | command_line_utf16.ptr[utf8_to_utf16le(command_line_utf16.ptr, buf_to_slice(&command_line))] = 0; |
| 167 | |
| 168 | BOOL success = CreateProcessW(exe_utf16_slice.ptr, command_line_utf16.ptr, nullptr, nullptr, TRUE, CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, |
| 161 | 169 | &siStartInfo, &piProcInfo); |
| 162 | 170 | |
| 163 | 171 | if (!success) { |
| 164 | | zig_panic("CreateProcess failed. exe: %s command_line: %s", exe, buf_ptr(&command_line)); |
| 172 | zig_panic("CreateProcess failed. exe: %s command_line: %s", args.at(0), buf_ptr(&command_line)); |
| 165 | 173 | } |
| 166 | 174 | |
| 167 | 175 | WaitForSingleObject(piProcInfo.hProcess, INFINITE); |
| ... | ... | @@ -274,7 +282,7 @@ void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) { |
| 274 | 282 | |
| 275 | 283 | Error os_path_real(Buf *rel_path, Buf *out_abs_path) { |
| 276 | 284 | #if defined(ZIG_OS_WINDOWS) |
| 277 | | PathSpace rel_path_space = slice_to_prefixed_file_w({ (uint8_t*)buf_ptr(rel_path), buf_len(rel_path) }); |
| 285 | PathSpace rel_path_space = slice_to_prefixed_file_w(buf_to_slice(rel_path)); |
| 278 | 286 | PathSpace out_abs_path_space; |
| 279 | 287 | |
| 280 | 288 | if (_wfullpath(&out_abs_path_space.data.items[0], &rel_path_space.data.items[0], PATH_MAX_WIDE) == nullptr) { |
| ... | ... | @@ -780,7 +788,7 @@ Error os_fetch_file(FILE *f, Buf *out_buf) { |
| 780 | 788 | |
| 781 | 789 | Error os_file_exists(Buf *full_path, bool *result) { |
| 782 | 790 | #if defined(ZIG_OS_WINDOWS) |
| 783 | | PathSpace path_space = slice_to_prefixed_file_w({ (uint8_t*)buf_ptr(full_path), buf_len(full_path) }); |
| 791 | PathSpace path_space = slice_to_prefixed_file_w(buf_to_slice(full_path)); |
| 784 | 792 | *result = GetFileAttributesW(&path_space.data.items[0]) != INVALID_FILE_ATTRIBUTES; |
| 785 | 793 | return ErrorNone; |
| 786 | 794 | #else |
| ... | ... | @@ -1338,8 +1346,8 @@ Error os_rename(Buf *src_path, Buf *dest_path) { |
| 1338 | 1346 | return ErrorNone; |
| 1339 | 1347 | } |
| 1340 | 1348 | #if defined(ZIG_OS_WINDOWS) |
| 1341 | | PathSpace src_path_space = slice_to_prefixed_file_w({ (uint8_t*)buf_ptr(src_path), buf_len(src_path) }); |
| 1342 | | PathSpace dest_path_space = slice_to_prefixed_file_w({ (uint8_t*)buf_ptr(dest_path), buf_len(dest_path) }); |
| 1349 | PathSpace src_path_space = slice_to_prefixed_file_w(buf_to_slice(src_path)); |
| 1350 | PathSpace dest_path_space = slice_to_prefixed_file_w(buf_to_slice(dest_path)); |
| 1343 | 1351 | if (!MoveFileExW(&src_path_space.data.items[0], &dest_path_space.data.items[0], MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { |
| 1344 | 1352 | return ErrorFileSystem; |
| 1345 | 1353 | } |
| ... | ... | @@ -1436,7 +1444,14 @@ Error os_make_path(Buf *path) { |
| 1436 | 1444 | |
| 1437 | 1445 | Error os_make_dir(Buf *path) { |
| 1438 | 1446 | #if defined(ZIG_OS_WINDOWS) |
| 1439 | | PathSpace path_space = slice_to_prefixed_file_w({ (uint8_t*)buf_ptr(path), buf_len(path) }); |
| 1447 | PathSpace path_space = slice_to_prefixed_file_w(buf_to_slice(path)); |
| 1448 | if (memEql(buf_to_slice(path), str("C:\\dev\\tést"))) { |
| 1449 | for (size_t i = 0; i < path_space.len; i++) { |
| 1450 | fprintf(stderr, "%d ", path_space.data.items[i]); |
| 1451 | } |
| 1452 | fprintf(stderr, "\n"); |
| 1453 | } |
| 1454 | |
| 1440 | 1455 | if (!CreateDirectoryW(&path_space.data.items[0], NULL)) { |
| 1441 | 1456 | if (GetLastError() == ERROR_ALREADY_EXISTS) |
| 1442 | 1457 | return ErrorPathAlreadyExists; |
| ... | ... | @@ -1727,22 +1742,11 @@ static uint8_t utf8CodepointSequenceLength(uint32_t c) { |
| 1727 | 1742 | |
| 1728 | 1743 | // Ported from std.unicode.utf8ByteSequenceLength |
| 1729 | 1744 | static uint8_t utf8ByteSequenceLength(uint8_t first_byte) { |
| 1730 | | switch (clzll(~first_byte)) { |
| 1731 | | case 0: |
| 1732 | | return 1; |
| 1733 | | break; |
| 1734 | | case 2: |
| 1735 | | return 2; |
| 1736 | | break; |
| 1737 | | case 3: |
| 1738 | | return 3; |
| 1739 | | break; |
| 1740 | | case 4: |
| 1741 | | return 4; |
| 1742 | | break; |
| 1743 | | default: |
| 1744 | | zig_unreachable(); |
| 1745 | | } |
| 1745 | if (first_byte < 0b10000000) return 1; |
| 1746 | if ((first_byte & 0b11100000) == 0b11000000) return 2; |
| 1747 | if ((first_byte & 0b11110000) == 0b11100000) return 3; |
| 1748 | if ((first_byte & 0b11111000) == 0b11110000) return 4; |
| 1749 | zig_unreachable(); |
| 1746 | 1750 | } |
| 1747 | 1751 | |
| 1748 | 1752 | // Ported from std/unicode.zig |
| ... | ... | @@ -2016,7 +2020,7 @@ Error os_self_exe_shared_libs(ZigList<Buf *> &paths) { |
| 2016 | 2020 | |
| 2017 | 2021 | Error os_file_open_rw(Buf *full_path, OsFile *out_file, OsFileAttr *attr, bool need_write, uint32_t mode) { |
| 2018 | 2022 | #if defined(ZIG_OS_WINDOWS) |
| 2019 | | PathSpace path_space = slice_to_prefixed_file_w({ (uint8_t*)buf_ptr(full_path), buf_len(full_path) }); |
| 2023 | PathSpace path_space = slice_to_prefixed_file_w(buf_to_slice(full_path)); |
| 2020 | 2024 | HANDLE result = CreateFileW(&path_space.data.items[0], |
| 2021 | 2025 | need_write ? (GENERIC_READ|GENERIC_WRITE) : GENERIC_READ, |
| 2022 | 2026 | need_write ? 0 : FILE_SHARE_READ, |
| ... | ... | @@ -2121,7 +2125,7 @@ Error os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_ |
| 2121 | 2125 | |
| 2122 | 2126 | Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) { |
| 2123 | 2127 | #if defined(ZIG_OS_WINDOWS) |
| 2124 | | PathSpace path_space = slice_to_prefixed_file_w({ (uint8_t*)buf_ptr(full_path), buf_len(full_path) }); |
| 2128 | PathSpace path_space = slice_to_prefixed_file_w(buf_to_slice(full_path)); |
| 2125 | 2129 | for (;;) { |
| 2126 | 2130 | HANDLE result = CreateFileW(&path_space.data.items[0], GENERIC_READ | GENERIC_WRITE, |
| 2127 | 2131 | 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); |