Commit 92d11fd4e9

Jakub Konka <kubkon@jakubkonka.com>
2020-07-13 17:51:14
Debug readlinkW using OpenFile
1 parent 791795a
Changed files (3)
lib/std/os/test.zig
@@ -45,7 +45,8 @@ test "readlink" {
     if (builtin.os.tag == .wasi) return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
-    defer tmp.cleanup();
+    //defer tmp.cleanup();
+    std.debug.print("tmp = {}\n", .{tmp.sub_path[0..]});
 
     // create file
     try tmp.dir.writeFile("file.txt", "nonsense");
@@ -59,8 +60,8 @@ test "readlink" {
         const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..]});
         break :blk try fs.realpathAlloc(&arena.allocator, relative_path);
     };
-    const target_path = try fs.path.join(&arena.allocator, &[_][]const u8{"file.txt"});
-    const symlink_path = try fs.path.join(&arena.allocator, &[_][]const u8{"symlinked"});
+    const target_path = try fs.path.join(&arena.allocator, &[_][]const u8{base_path, "file.txt"});
+    const symlink_path = try fs.path.join(&arena.allocator, &[_][]const u8{base_path, "symlinked"});
 
     // create symbolic link by path
     try os.symlink(target_path, symlink_path);
lib/std/os/windows.zig
@@ -110,6 +110,7 @@ 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,
 };
 
@@ -145,7 +146,15 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
 
     var delay: usize = 1;
     while (true) {
-        const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0;
+        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 rc = ntdll.NtCreateFile(
             &result,
             options.access_mask,
@@ -155,7 +164,8 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
             FILE_ATTRIBUTE_NORMAL,
             options.share_access,
             options.creation,
-            FILE_NON_DIRECTORY_FILE | blocking_flag,
+            // flags | blocking_flag,
+            flags,
             null,
             0,
         );
@@ -601,7 +611,12 @@ pub fn GetCurrentDirectory(buffer: []u8) GetCurrentDirectoryError![]u8 {
     return buffer[0..end_index];
 }
 
-pub const CreateSymbolicLinkError = error{AccessDenied, FileNotFound, Unexpected};
+pub const CreateSymbolicLinkError = error{
+    AccessDenied,
+    PathAlreadyExists,
+    FileNotFound,
+    Unexpected
+};
 
 pub const CreateSymbolicLinkFlags = enum(DWORD) {
     File = SYMBOLIC_LINK_FLAG_FILE,
@@ -638,6 +653,7 @@ pub fn CreateSymbolicLinkW(
                         .FILE_NOT_FOUND => return error.FileNotFound,
                         .PATH_NOT_FOUND => return error.FileNotFound,
                         .ACCESS_DENIED => return error.AccessDenied,
+                        .ALREADY_EXISTS => return error.PathAlreadyExists,
                         else => |err| return unexpectedError(err),
                     }
                 }
@@ -647,6 +663,7 @@ pub fn CreateSymbolicLinkW(
             .FILE_NOT_FOUND => return error.FileNotFound,
             .PATH_NOT_FOUND => return error.FileNotFound,
             .ACCESS_DENIED => return error.AccessDenied,
+            .ALREADY_EXISTS => return error.PathAlreadyExists,
             else => |err| return unexpectedError(err),
         }
     }
lib/std/os.zig
@@ -1554,7 +1554,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!
     if (builtin.os.tag == .windows) {
         const target_path_w = try windows.sliceToPrefixedFileW(target_path);
         const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);
-        return symlinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr);
+        return symlinkW(target_path_w.span().ptr, sym_link_path_w.span().ptr);
     }
     const target_path_c = try toPosixPath(target_path);
     const sym_link_path_c = try toPosixPath(sym_link_path);
@@ -1578,7 +1578,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin
     if (builtin.os.tag == .windows) {
         const target_path_w = try windows.cStrToPrefixedFileW(target_path);
         const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);
-        return windows.CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, 0);
+        return symlinkW(target_path_w.span().ptr, sym_link_path_w.span().ptr);
     }
     switch (errno(system.symlink(target_path, sym_link_path))) {
         0 => return,
@@ -2394,8 +2394,9 @@ pub const readlinkC = @compileError("deprecated: renamed to readlinkZ");
 /// See also `readlinkZ`.
 pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
     const handle = windows.OpenFile(file_path, .{
-        .access_mask = 0,
-        .creation = windows.FILE_OPEN_REPARSE_POINT | windows.FILE_LIST_DIRECTORY,
+        .access_mask = windows.GENERIC_READ,
+        .creation = windows.FILE_OPEN,
+        .options = windows.FILE_OPEN_REPARSE_POINT,
         .io_mode = std.io.default_mode,
     }) catch |err| {
         switch (err) {