| author | |
| committer | |
| log | 80b1e82b1b8706b7654560013751dd4a6fc8ae2a |
| tree | 0522d7b8579c846441685b105e88f2dd9f1443ef |
| parent | a6470088c6629e91edad8390f3f2930f1d7c92b1 |
3 files changed, 35 insertions(+), 4 deletions(-)
lib/std/os.zig+7-4| ... | @@ -2305,8 +2305,12 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { | ... | @@ -2305,8 +2305,12 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { |
| 2305 | if (builtin.os.tag == .wasi) { | 2305 | if (builtin.os.tag == .wasi) { |
| 2306 | @compileError("chdir is not supported in WASI"); | 2306 | @compileError("chdir is not supported in WASI"); |
| 2307 | } else if (builtin.os.tag == .windows) { | 2307 | } else if (builtin.os.tag == .windows) { |
| 2308 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); | 2308 | windows.SetCurrentDirectory(dir_path) catch |err| switch (err) { |
| 2309 | @compileError("TODO implement chdir for Windows"); | 2309 | error.PathNotFound, error.InvalidName, error.InvalidUtf8 => return error.FileNotFound, |
| 2310 | error.NameTooLong => return error.NameTooLong, | ||
| 2311 | error.NotDir => return error.NotDir, | ||
| 2312 | error.Unexpected => return error.Unexpected, | ||
| 2313 | }; | ||
| 2310 | } else { | 2314 | } else { |
| 2311 | const dir_path_c = try toPosixPath(dir_path); | 2315 | const dir_path_c = try toPosixPath(dir_path); |
| 2312 | return chdirZ(&dir_path_c); | 2316 | return chdirZ(&dir_path_c); |
| ... | @@ -2318,8 +2322,7 @@ pub const chdirC = @compileError("deprecated: renamed to chdirZ"); | ... | @@ -2318,8 +2322,7 @@ pub const chdirC = @compileError("deprecated: renamed to chdirZ"); |
| 2318 | /// Same as `chdir` except the parameter is null-terminated. | 2322 | /// Same as `chdir` except the parameter is null-terminated. |
| 2319 | pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void { | 2323 | pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void { |
| 2320 | if (builtin.os.tag == .windows) { | 2324 | if (builtin.os.tag == .windows) { |
| 2321 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); | 2325 | return chdir(mem.spanZ(dir_path)); |
| 2322 | @compileError("TODO implement chdir for Windows"); | ||
| 2323 | } | 2326 | } |
| 2324 | switch (errno(system.chdir(dir_path))) { | 2327 | switch (errno(system.chdir(dir_path))) { |
| 2325 | 0 => return, | 2328 | 0 => return, |
lib/std/os/windows.zig+27| ... | @@ -555,6 +555,33 @@ pub fn WriteFile( | ... | @@ -555,6 +555,33 @@ pub fn WriteFile( |
| 555 | } | 555 | } |
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | pub const SetCurrentDirectoryError = error{ | ||
| 559 | PathNotFound, | ||
| 560 | InvalidName, | ||
| 561 | InvalidUtf8, | ||
| 562 | NameTooLong, | ||
| 563 | NotDir, | ||
| 564 | Unexpected, | ||
| 565 | }; | ||
| 566 | |||
| 567 | pub fn SetCurrentDirectory(path_name: []const u8) SetCurrentDirectoryError!void { | ||
| 568 | // PATH_MAX_WIDE - 1 as we need to ensure there is space for the null terminator | ||
| 569 | if (path_name.len >= PATH_MAX_WIDE - 1) return error.NameTooLong; | ||
| 570 | |||
| 571 | var utf16le_buf: [PATH_MAX_WIDE]u16 = undefined; | ||
| 572 | const end = try std.unicode.utf8ToUtf16Le(utf16le_buf[0..], path_name); | ||
| 573 | utf16le_buf[end] = 0; | ||
| 574 | |||
| 575 | if (kernel32.SetCurrentDirectoryW(@ptrCast([*:0]const u16, &utf16le_buf)) == 0) { | ||
| 576 | switch (kernel32.GetLastError()) { | ||
| 577 | .PATH_NOT_FOUND, .FILE_NOT_FOUND => return error.PathNotFound, | ||
| 578 | .DIRECTORY => return error.NotDir, | ||
| 579 | .INVALID_NAME => return error.InvalidName, | ||
| 580 | else => |err| return unexpectedError(err), | ||
| 581 | } | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 558 | pub const GetCurrentDirectoryError = error{ | 585 | pub const GetCurrentDirectoryError = error{ |
| 559 | NameTooLong, | 586 | NameTooLong, |
| 560 | Unexpected, | 587 | Unexpected, |
lib/std/os/windows/kernel32.zig+1| ... | @@ -93,6 +93,7 @@ pub extern "kernel32" fn FillConsoleOutputCharacterA(hConsoleOutput: HANDLE, cCh | ... | @@ -93,6 +93,7 @@ pub extern "kernel32" fn FillConsoleOutputCharacterA(hConsoleOutput: HANDLE, cCh |
| 93 | pub extern "kernel32" fn FillConsoleOutputAttribute(hConsoleOutput: HANDLE, wAttribute: WORD, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfAttrsWritten: LPDWORD) callconv(.Stdcall) BOOL; | 93 | pub extern "kernel32" fn FillConsoleOutputAttribute(hConsoleOutput: HANDLE, wAttribute: WORD, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfAttrsWritten: LPDWORD) callconv(.Stdcall) BOOL; |
| 94 | pub extern "kernel32" fn SetConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD) callconv(.Stdcall) BOOL; | 94 | pub extern "kernel32" fn SetConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD) callconv(.Stdcall) BOOL; |
| 95 | 95 | ||
| 96 | pub extern "kernel32" fn SetCurrentDirectoryW(lpPathName: [*:0]const u16) callconv(.Stdcall) BOOL; | ||
| 96 | pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(.Stdcall) DWORD; | 97 | pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(.Stdcall) DWORD; |
| 97 | 98 | ||
| 98 | pub extern "kernel32" fn GetCurrentThread() callconv(.Stdcall) HANDLE; | 99 | pub extern "kernel32" fn GetCurrentThread() callconv(.Stdcall) HANDLE; |