diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2020-07-13 08:01:01 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2020-07-22 08:51:22 +0200 |
| commit | 515c663cd6e31d5f8ae07e804f2b32b99d025895 (patch) | |
| tree | 5950337a1fe1a4362594b73e9879369480e0fc42 /lib/std | |
| parent | cc83d92b0b12f5b3fa6462ed878cd7bec7412940 (diff) | |
| download | zig-515c663cd6e31d5f8ae07e804f2b32b99d025895.tar.gz zig-515c663cd6e31d5f8ae07e804f2b32b99d025895.zip | |
Add readlink smoke test
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/os.zig | 28 | ||||
| -rw-r--r-- | lib/std/os/test.zig | 31 | ||||
| -rw-r--r-- | lib/std/os/windows/bits.zig | 2 |
3 files changed, 49 insertions, 12 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig index 983f7f9a90..ab54ba5fe8 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -2355,6 +2355,8 @@ pub const ReadLinkError = error{ FileNotFound, SystemResources, NotDir, + InvalidUtf8, + BadPathName, /// Windows-only. UnsupportedSymlinkType, } || UnexpectedError; @@ -2366,7 +2368,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { @compileError("readlink is not supported in WASI; use readlinkat instead"); } else if (builtin.os.tag == .windows) { const file_path_w = try windows.sliceToPrefixedFileW(file_path); - return readlinkW(file_path_w.span().ptr, out_buffer); + return readlinkW(file_path_w.span(), out_buffer); } else { const file_path_c = try toPosixPath(file_path); return readlinkZ(&file_path_c, out_buffer); @@ -2377,11 +2379,11 @@ 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: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 { +pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 { const handle = windows.OpenFile(file_path, .{ .access_mask = 0, - .creation = c.FILE_OPEN_REPARSE_POINT | c.FILE_LIST_DIRECTORY, - .io_mode = 0, + .creation = windows.FILE_OPEN_REPARSE_POINT | windows.FILE_LIST_DIRECTORY, + .io_mode = std.io.default_mode, }) catch |err| { switch (err) { error.IsDir => unreachable, @@ -2390,28 +2392,32 @@ pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 error.PipeBusy => unreachable, error.PathAlreadyExists => unreachable, error.WouldBlock => unreachable, - else => return err, + else => |e| return e, } }; var reparse_buf: [windows.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined; _ = try windows.DeviceIoControl(handle, windows.FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null); - const reparse_struct = @bitCast(windows._REPARSE_DATA_BUFFER, reparse_buf[0..@sizeOf(windows._REPARSE_DATA_BUFFER)]); + const reparse_struct = mem.bytesAsValue(windows._REPARSE_DATA_BUFFER, reparse_buf[0..@sizeOf(windows._REPARSE_DATA_BUFFER)]); switch (reparse_struct.ReparseTag) { - windows.IO_REPARSE_TAG_SYMLINK => {}, - windows.IO_REPARSE_TAG_MOUNT_POINT => {}, + windows.IO_REPARSE_TAG_SYMLINK => { + std.debug.warn("got symlink!", .{}); + }, + windows.IO_REPARSE_TAG_MOUNT_POINT => { + std.debug.warn("got mount point!", .{}); + }, else => |value| { - std.debug.print("unsupported symlink type: {}", value); + std.debug.warn("unsupported symlink type: {}", .{value}); return error.UnsupportedSymlinkType; }, } - @compileError("TODO implement readlink for Windows"); + @panic("Oh no!"); } /// Same as `readlink` except `file_path` is null-terminated. pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { if (builtin.os.tag == .windows) { const file_path_w = try windows.cStrToPrefixedFileW(file_path); - return readlinkW(file_path_w.span().ptr, out_buffer); + return readlinkW(file_path_w.span(), out_buffer); } const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len); switch (errno(rc)) { diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index e508f5ae20..b3f0136cf6 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -17,6 +17,7 @@ const AtomicRmwOp = builtin.AtomicRmwOp; const AtomicOrder = builtin.AtomicOrder; const tmpDir = std.testing.tmpDir; const Dir = std.fs.Dir; +const ArenaAllocator = std.heap.ArenaAllocator; test "fstatat" { // enable when `fstat` and `fstatat` are implemented on Windows @@ -40,6 +41,36 @@ test "fstatat" { expectEqual(stat, statat); } +test "readlink" { + if (builtin.os.tag == .wasi) return error.SkipZigTest; + + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + + // create file + try tmp.dir.writeFile("file.txt", "nonsense"); + + // get paths + // TODO: use Dir's realpath function once that exists + var arena = ArenaAllocator.init(testing.allocator); + defer arena.deinit(); + + const base_path = blk: { + 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"}); + + // create symbolic link by path + try os.symlink(target_path, symlink_path); + + // now, read the link and verify + var buffer: [fs.MAX_PATH_BYTES]u8 = undefined; + const given = try os.readlink(symlink_path, buffer[0..]); + expect(mem.eql(u8, symlink_path, given)); +} + test "readlinkat" { // enable when `readlinkat` and `symlinkat` are implemented on Windows if (builtin.os.tag == .windows) return error.SkipZigTest; diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index 6182dc5de8..998d4a8091 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -488,7 +488,7 @@ pub const FILE_OPEN_BY_FILE_ID = 0x00002000; pub const FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000; pub const FILE_NO_COMPRESSION = 0x00008000; pub const FILE_RESERVE_OPFILTER = 0x00100000; -pub const FILE_TRANSACTED_MODE = 0x00200000; +pub const FILE_OPEN_REPARSE_POINT = 0x00200000; pub const FILE_OPEN_OFFLINE_FILE = 0x00400000; pub const FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000; |
