diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2020-07-13 23:41:06 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2020-07-22 08:51:22 +0200 |
| commit | 49b58153642bbff19ab976b70e329c5592fa1684 (patch) | |
| tree | 7633506ceccb3e25d86c1651c194c7827a549e41 /lib/std | |
| parent | 92d11fd4e95b86d6ace166783cda69030647e688 (diff) | |
| download | zig-49b58153642bbff19ab976b70e329c5592fa1684.tar.gz zig-49b58153642bbff19ab976b70e329c5592fa1684.zip | |
Add windows.ReadLink similar to OpenFile but for reparse points only
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/os.zig | 7 | ||||
| -rw-r--r-- | lib/std/os/test.zig | 3 | ||||
| -rw-r--r-- | lib/std/os/windows.zig | 63 |
3 files changed, 54 insertions, 19 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig index eb033babfb..f9c50adc06 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -2393,12 +2393,7 @@ pub const readlinkC = @compileError("deprecated: renamed to readlinkZ"); /// Windows-only. Same as `readlink` except `file_path` is null-terminated, WTF16 encoded. /// See also `readlinkZ`. pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 { - const handle = windows.OpenFile(file_path, .{ - .access_mask = windows.GENERIC_READ, - .creation = windows.FILE_OPEN, - .options = windows.FILE_OPEN_REPARSE_POINT, - .io_mode = std.io.default_mode, - }) catch |err| { + const handle = windows.ReadLink(file_path) catch |err| { switch (err) { error.IsDir => unreachable, error.NoDevice => return error.FileNotFound, diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index eb2da384a6..826be1cc8e 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -45,8 +45,7 @@ test "readlink" { if (builtin.os.tag == .wasi) return error.SkipZigTest; var tmp = tmpDir(.{}); - //defer tmp.cleanup(); - std.debug.print("tmp = {}\n", .{tmp.sub_path[0..]}); + defer tmp.cleanup(); // create file try tmp.dir.writeFile("file.txt", "nonsense"); diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 049a2a8612..9fc0a123be 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -110,7 +110,6 @@ pub const OpenFileOptions = struct { share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, share_access_nonblocking: bool = false, creation: ULONG, - options: ?ULONG = null, io_mode: std.io.ModeOverride, }; @@ -147,14 +146,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN var delay: usize = 1; while (true) { var flags: ULONG = undefined; - if (options.options) |opt| { - flags = opt; - } else { - const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; - flags = FILE_NON_DIRECTORY_FILE | blocking_flag; - } - // const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; - // const flags = if (options.options) |opt| opt else FILE_NON_DIRECTORY_FILE; + const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; const rc = ntdll.NtCreateFile( &result, options.access_mask, @@ -164,8 +156,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN FILE_ATTRIBUTE_NORMAL, options.share_access, options.creation, - // flags | blocking_flag, - flags, + FILE_NON_DIRECTORY_FILE | blocking_flag, null, 0, ); @@ -1380,3 +1371,53 @@ pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError { } return error.Unexpected; } + +pub fn ReadLink(path_w: []const u16) OpenError!HANDLE { + var result: HANDLE = undefined; + + const path_len_bytes = math.cast(u16, path_w.len * 2) catch |err| switch (err) { + error.Overflow => return error.NameTooLong, + }; + var nt_name = UNICODE_STRING{ + .Length = path_len_bytes, + .MaximumLength = path_len_bytes, + .Buffer = @intToPtr([*]u16, @ptrToInt(path_w.ptr)), + }; + var attr = OBJECT_ATTRIBUTES{ + .Length = @sizeOf(OBJECT_ATTRIBUTES), + .RootDirectory = null, + .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here. + .ObjectName = &nt_name, + .SecurityDescriptor = null, + .SecurityQualityOfService = null, + }; + var io: IO_STATUS_BLOCK = undefined; + const rc = ntdll.NtCreateFile( + &result, + FILE_LIST_DIRECTORY, + &attr, + &io, + null, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_DELETE, + FILE_OPEN, + FILE_OPEN_REPARSE_POINT, + null, + 0, + ); + switch (rc) { + .SUCCESS => return result, + .OBJECT_NAME_INVALID => unreachable, + .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, + .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, + .NO_MEDIA_IN_DEVICE => return error.NoDevice, + .INVALID_PARAMETER => unreachable, + .SHARING_VIOLATION => return error.WouldBlock, + .ACCESS_DENIED => return error.AccessDenied, + .PIPE_BUSY => return error.PipeBusy, + .OBJECT_PATH_SYNTAX_BAD => unreachable, + .OBJECT_NAME_COLLISION => return error.PathAlreadyExists, + .FILE_IS_A_DIRECTORY => return error.IsDir, + else => return unexpectedStatus(rc), + } +}
\ No newline at end of file |
