| author | |
| committer | |
| log | 92d11fd4e95b86d6ace166783cda69030647e688 |
| tree | 5b1d297421025740852a5e9775bae4e031c2681c |
| parent | 791795a63a34bc69af59717d5eff5d4c76349756 |
3 files changed, 29 insertions(+), 10 deletions(-)
lib/std/os.zig+5-4| ... | ... | @@ -1554,7 +1554,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError! |
| 1554 | 1554 | if (builtin.os.tag == .windows) { |
| 1555 | 1555 | const target_path_w = try windows.sliceToPrefixedFileW(target_path); |
| 1556 | 1556 | const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path); |
| 1557 | return symlinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr); | |
| 1557 | return symlinkW(target_path_w.span().ptr, sym_link_path_w.span().ptr); | |
| 1558 | 1558 | } |
| 1559 | 1559 | const target_path_c = try toPosixPath(target_path); |
| 1560 | 1560 | 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 |
| 1578 | 1578 | if (builtin.os.tag == .windows) { |
| 1579 | 1579 | const target_path_w = try windows.cStrToPrefixedFileW(target_path); |
| 1580 | 1580 | const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path); |
| 1581 | return windows.CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, 0); | |
| 1581 | return symlinkW(target_path_w.span().ptr, sym_link_path_w.span().ptr); | |
| 1582 | 1582 | } |
| 1583 | 1583 | switch (errno(system.symlink(target_path, sym_link_path))) { |
| 1584 | 1584 | 0 => return, |
| ... | ... | @@ -2394,8 +2394,9 @@ pub const readlinkC = @compileError("deprecated: renamed to readlinkZ"); |
| 2394 | 2394 | /// See also `readlinkZ`. |
| 2395 | 2395 | pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 { |
| 2396 | 2396 | const handle = windows.OpenFile(file_path, .{ |
| 2397 | .access_mask = 0, | |
| 2398 | .creation = windows.FILE_OPEN_REPARSE_POINT | windows.FILE_LIST_DIRECTORY, | |
| 2397 | .access_mask = windows.GENERIC_READ, | |
| 2398 | .creation = windows.FILE_OPEN, | |
| 2399 | .options = windows.FILE_OPEN_REPARSE_POINT, | |
| 2399 | 2400 | .io_mode = std.io.default_mode, |
| 2400 | 2401 | }) catch |err| { |
| 2401 | 2402 | switch (err) { |
lib/std/os/test.zig+4-3| ... | ... | @@ -45,7 +45,8 @@ test "readlink" { |
| 45 | 45 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 46 | 46 | |
| 47 | 47 | var tmp = tmpDir(.{}); |
| 48 | defer tmp.cleanup(); | |
| 48 | //defer tmp.cleanup(); | |
| 49 | std.debug.print("tmp = {}\n", .{tmp.sub_path[0..]}); | |
| 49 | 50 | |
| 50 | 51 | // create file |
| 51 | 52 | try tmp.dir.writeFile("file.txt", "nonsense"); |
| ... | ... | @@ -59,8 +60,8 @@ test "readlink" { |
| 59 | 60 | const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..]}); |
| 60 | 61 | break :blk try fs.realpathAlloc(&arena.allocator, relative_path); |
| 61 | 62 | }; |
| 62 | const target_path = try fs.path.join(&arena.allocator, &[_][]const u8{"file.txt"}); | |
| 63 | const symlink_path = try fs.path.join(&arena.allocator, &[_][]const u8{"symlinked"}); | |
| 63 | const target_path = try fs.path.join(&arena.allocator, &[_][]const u8{base_path, "file.txt"}); | |
| 64 | const symlink_path = try fs.path.join(&arena.allocator, &[_][]const u8{base_path, "symlinked"}); | |
| 64 | 65 | |
| 65 | 66 | // create symbolic link by path |
| 66 | 67 | try os.symlink(target_path, symlink_path); |
lib/std/os/windows.zig+20-3| ... | ... | @@ -110,6 +110,7 @@ pub const OpenFileOptions = struct { |
| 110 | 110 | share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, |
| 111 | 111 | share_access_nonblocking: bool = false, |
| 112 | 112 | creation: ULONG, |
| 113 | options: ?ULONG = null, | |
| 113 | 114 | io_mode: std.io.ModeOverride, |
| 114 | 115 | }; |
| 115 | 116 | |
| ... | ... | @@ -145,7 +146,15 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 145 | 146 | |
| 146 | 147 | var delay: usize = 1; |
| 147 | 148 | while (true) { |
| 148 | const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; | |
| 149 | var flags: ULONG = undefined; | |
| 150 | if (options.options) |opt| { | |
| 151 | flags = opt; | |
| 152 | } else { | |
| 153 | const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; | |
| 154 | flags = FILE_NON_DIRECTORY_FILE | blocking_flag; | |
| 155 | } | |
| 156 | // const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; | |
| 157 | // const flags = if (options.options) |opt| opt else FILE_NON_DIRECTORY_FILE; | |
| 149 | 158 | const rc = ntdll.NtCreateFile( |
| 150 | 159 | &result, |
| 151 | 160 | options.access_mask, |
| ... | ... | @@ -155,7 +164,8 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 155 | 164 | FILE_ATTRIBUTE_NORMAL, |
| 156 | 165 | options.share_access, |
| 157 | 166 | options.creation, |
| 158 | FILE_NON_DIRECTORY_FILE | blocking_flag, | |
| 167 | // flags | blocking_flag, | |
| 168 | flags, | |
| 159 | 169 | null, |
| 160 | 170 | 0, |
| 161 | 171 | ); |
| ... | ... | @@ -601,7 +611,12 @@ pub fn GetCurrentDirectory(buffer: []u8) GetCurrentDirectoryError![]u8 { |
| 601 | 611 | return buffer[0..end_index]; |
| 602 | 612 | } |
| 603 | 613 | |
| 604 | pub const CreateSymbolicLinkError = error{AccessDenied, FileNotFound, Unexpected}; | |
| 614 | pub const CreateSymbolicLinkError = error{ | |
| 615 | AccessDenied, | |
| 616 | PathAlreadyExists, | |
| 617 | FileNotFound, | |
| 618 | Unexpected | |
| 619 | }; | |
| 605 | 620 | |
| 606 | 621 | pub const CreateSymbolicLinkFlags = enum(DWORD) { |
| 607 | 622 | File = SYMBOLIC_LINK_FLAG_FILE, |
| ... | ... | @@ -638,6 +653,7 @@ pub fn CreateSymbolicLinkW( |
| 638 | 653 | .FILE_NOT_FOUND => return error.FileNotFound, |
| 639 | 654 | .PATH_NOT_FOUND => return error.FileNotFound, |
| 640 | 655 | .ACCESS_DENIED => return error.AccessDenied, |
| 656 | .ALREADY_EXISTS => return error.PathAlreadyExists, | |
| 641 | 657 | else => |err| return unexpectedError(err), |
| 642 | 658 | } |
| 643 | 659 | } |
| ... | ... | @@ -647,6 +663,7 @@ pub fn CreateSymbolicLinkW( |
| 647 | 663 | .FILE_NOT_FOUND => return error.FileNotFound, |
| 648 | 664 | .PATH_NOT_FOUND => return error.FileNotFound, |
| 649 | 665 | .ACCESS_DENIED => return error.AccessDenied, |
| 666 | .ALREADY_EXISTS => return error.PathAlreadyExists, | |
| 650 | 667 | else => |err| return unexpectedError(err), |
| 651 | 668 | } |
| 652 | 669 | } |