aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-07-13 23:41:06 +0200
committerJakub Konka <kubkon@jakubkonka.com>2020-07-22 08:51:22 +0200
commit49b58153642bbff19ab976b70e329c5592fa1684 (patch)
tree7633506ceccb3e25d86c1651c194c7827a549e41 /lib
parent92d11fd4e95b86d6ace166783cda69030647e688 (diff)
downloadzig-49b58153642bbff19ab976b70e329c5592fa1684.tar.gz
zig-49b58153642bbff19ab976b70e329c5592fa1684.zip
Add windows.ReadLink similar to OpenFile but for reparse points only
Diffstat (limited to 'lib')
-rw-r--r--lib/std/os.zig7
-rw-r--r--lib/std/os/test.zig3
-rw-r--r--lib/std/os/windows.zig63
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