| author | |
| committer | |
| log | 8173fbfb66132f0fca42a3c8415381ad9f5d632d |
| tree | a33289790cdc09c1a71ff14f6a35e82a54d082b8 |
| parent | 4b02a39aa93b0043f05de0d90443051c019643ab |
| signature | Commit is signed but in an unrecognized format. |
4 files changed, 65 insertions(+), 14 deletions(-)
lib/std/event/batch.zig+2-2| ... | ... | @@ -109,13 +109,13 @@ pub fn Batch( |
| 109 | 109 | |
| 110 | 110 | test "std.event.Batch" { |
| 111 | 111 | var count: usize = 0; |
| 112 | var batch = Batch(void, 2).init(); | |
| 112 | var batch = Batch(void, 2, .auto_async).init(); | |
| 113 | 113 | batch.add(&async sleepALittle(&count)); |
| 114 | 114 | batch.add(&async increaseByTen(&count)); |
| 115 | 115 | batch.wait(); |
| 116 | 116 | testing.expect(count == 11); |
| 117 | 117 | |
| 118 | var another = Batch(anyerror!void, 2).init(); | |
| 118 | var another = Batch(anyerror!void, 2, .auto_async).init(); | |
| 119 | 119 | another.add(&async somethingElse()); |
| 120 | 120 | another.add(&async doSomethingThatFails()); |
| 121 | 121 | testing.expectError(error.ItBroke, another.wait()); |
lib/std/fs.zig+22-9| ... | ... | @@ -818,6 +818,13 @@ pub const Dir = struct { |
| 818 | 818 | ) File.OpenError!File { |
| 819 | 819 | const w = os.windows; |
| 820 | 820 | |
| 821 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { | |
| 822 | return error.IsDir; | |
| 823 | } | |
| 824 | if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) { | |
| 825 | return error.IsDir; | |
| 826 | } | |
| 827 | ||
| 821 | 828 | var result = File{ |
| 822 | 829 | .handle = undefined, |
| 823 | 830 | .io_mode = .blocking, |
| ... | ... | @@ -839,12 +846,6 @@ pub const Dir = struct { |
| 839 | 846 | .SecurityDescriptor = null, |
| 840 | 847 | .SecurityQualityOfService = null, |
| 841 | 848 | }; |
| 842 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { | |
| 843 | return error.IsDir; | |
| 844 | } | |
| 845 | if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) { | |
| 846 | return error.IsDir; | |
| 847 | } | |
| 848 | 849 | var io: w.IO_STATUS_BLOCK = undefined; |
| 849 | 850 | const rc = w.ntdll.NtCreateFile( |
| 850 | 851 | &result.handle, |
| ... | ... | @@ -1332,12 +1333,20 @@ pub const Dir = struct { |
| 1332 | 1333 | /// For example, instead of testing if a file exists and then opening it, just |
| 1333 | 1334 | /// open it and handle the error for file not found. |
| 1334 | 1335 | pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void { |
| 1336 | if (builtin.os == .windows) { | |
| 1337 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); | |
| 1338 | return self.accessW(&sub_path_w, flags); | |
| 1339 | } | |
| 1335 | 1340 | const path_c = try os.toPosixPath(sub_path); |
| 1336 | 1341 | return self.accessZ(&path_c, flags); |
| 1337 | 1342 | } |
| 1338 | 1343 | |
| 1339 | 1344 | /// Same as `access` except the path parameter is null-terminated. |
| 1340 | 1345 | pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void { |
| 1346 | if (builtin.os == .windows) { | |
| 1347 | const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path); | |
| 1348 | return self.accessW(&sub_path_w, flags); | |
| 1349 | } | |
| 1341 | 1350 | const os_mode = if (flags.write and flags.read) |
| 1342 | 1351 | @as(u32, os.R_OK | os.W_OK) |
| 1343 | 1352 | else if (flags.write) |
| ... | ... | @@ -1351,9 +1360,13 @@ pub const Dir = struct { |
| 1351 | 1360 | return result; |
| 1352 | 1361 | } |
| 1353 | 1362 | |
| 1354 | /// Same as `access` except the parameter is null-terminated UTF16LE-encoded. | |
| 1355 | pub fn accessW(self: Dir, sub_path: [*:0]const u16, flags: File.OpenFlags) AccessError!void { | |
| 1356 | return os.faccessatW(self.fd, sub_path, 0, 0); | |
| 1363 | /// Same as `access` except asserts the target OS is Windows and the path parameter is | |
| 1364 | /// * WTF-16 encoded | |
| 1365 | /// * null-terminated | |
| 1366 | /// * NtDll prefixed | |
| 1367 | /// TODO currently this ignores `flags`. | |
| 1368 | pub fn accessW(self: Dir, sub_path_w: [*:0]const u16, flags: File.OpenFlags) AccessError!void { | |
| 1369 | return os.faccessatW(self.fd, sub_path_w, 0, 0); | |
| 1357 | 1370 | } |
| 1358 | 1371 | }; |
| 1359 | 1372 |
lib/std/os.zig+35-3| ... | ... | @@ -2553,10 +2553,42 @@ pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) Acces |
| 2553 | 2553 | } |
| 2554 | 2554 | |
| 2555 | 2555 | /// Same as `faccessat` except asserts the target is Windows and the path parameter |
| 2556 | /// is null-terminated WTF-16 encoded. | |
| 2556 | /// is NtDll-prefixed, null-terminated, WTF-16 encoded. | |
| 2557 | 2557 | /// TODO currently this ignores `mode` and `flags` |
| 2558 | pub fn faccessatW(dirfd: fd_t, path: [*:0]const u16, mode: u32, flags: u32) AccessError!void { | |
| 2559 | @compileError("TODO implement faccessatW on Windows"); | |
| 2558 | pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32) AccessError!void { | |
| 2559 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { | |
| 2560 | return; | |
| 2561 | } | |
| 2562 | if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) { | |
| 2563 | return; | |
| 2564 | } | |
| 2565 | ||
| 2566 | const path_len_bytes = math.cast(u16, mem.toSliceConst(u16, sub_path_w).len * 2) catch |err| switch (err) { | |
| 2567 | error.Overflow => return error.NameTooLong, | |
| 2568 | }; | |
| 2569 | var nt_name = windows.UNICODE_STRING{ | |
| 2570 | .Length = path_len_bytes, | |
| 2571 | .MaximumLength = path_len_bytes, | |
| 2572 | .Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)), | |
| 2573 | }; | |
| 2574 | var attr = windows.OBJECT_ATTRIBUTES{ | |
| 2575 | .Length = @sizeOf(windows.OBJECT_ATTRIBUTES), | |
| 2576 | .RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w)) null else dirfd, | |
| 2577 | .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here. | |
| 2578 | .ObjectName = &nt_name, | |
| 2579 | .SecurityDescriptor = null, | |
| 2580 | .SecurityQualityOfService = null, | |
| 2581 | }; | |
| 2582 | var basic_info: windows.FILE_BASIC_INFORMATION = undefined; | |
| 2583 | switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) { | |
| 2584 | .SUCCESS => return, | |
| 2585 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, | |
| 2586 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, | |
| 2587 | .INVALID_PARAMETER => unreachable, | |
| 2588 | .ACCESS_DENIED => return error.PermissionDenied, | |
| 2589 | .OBJECT_PATH_SYNTAX_BAD => unreachable, | |
| 2590 | else => |rc| return windows.unexpectedStatus(rc), | |
| 2591 | } | |
| 2560 | 2592 | } |
| 2561 | 2593 | |
| 2562 | 2594 | pub const PipeError = error{ |
lib/std/os/windows/ntdll.zig+6| ... | ... | @@ -8,6 +8,12 @@ pub extern "NtDll" fn NtQueryInformationFile( |
| 8 | 8 | Length: ULONG, |
| 9 | 9 | FileInformationClass: FILE_INFORMATION_CLASS, |
| 10 | 10 | ) callconv(.Stdcall) NTSTATUS; |
| 11 | ||
| 12 | pub extern "NtDll" fn NtQueryAttributesFile( | |
| 13 | ObjectAttributes: *OBJECT_ATTRIBUTES, | |
| 14 | FileAttributes: *FILE_BASIC_INFORMATION, | |
| 15 | ) callconv(.Stdcall) NTSTATUS; | |
| 16 | ||
| 11 | 17 | pub extern "NtDll" fn NtCreateFile( |
| 12 | 18 | FileHandle: *HANDLE, |
| 13 | 19 | DesiredAccess: ACCESS_MASK, |