| ... | ... | @@ -219,7 +219,11 @@ pub const LOG = struct { |
| 219 | 219 | pub const DEBUG = 7; |
| 220 | 220 | }; |
| 221 | 221 | |
| 222 | | pub const RelativePath = struct { |
| 222 | /// An fd-relative file path |
| 223 | /// |
| 224 | /// This is currently only used for WASI-specific functionality, but the concept |
| 225 | /// is the same as the dirfd/pathname pairs in the `*at(...)` POSIX functions. |
| 226 | pub const RelativePathWasi = struct { |
| 223 | 227 | /// Handle to directory |
| 224 | 228 | dir_fd: fd_t, |
| 225 | 229 | /// Path to resource within `dir_fd`. |
| ... | ... | @@ -1425,7 +1429,7 @@ var wasi_cwd = if (builtin.os.tag == .wasi and !builtin.link_libc) struct { |
| 1425 | 1429 | // Memory buffer for storing the relative portion of the CWD |
| 1426 | 1430 | path_buffer: [MAX_PATH_BYTES]u8 = undefined, |
| 1427 | 1431 | // Current Working Directory, stored as an fd_t and a relative path |
| 1428 | | cwd: ?RelativePath = null, |
| 1432 | cwd: ?RelativePathWasi = null, |
| 1429 | 1433 | // Preopen associated with `cwd`, if any |
| 1430 | 1434 | cwd_preopen: ?Preopen = null, |
| 1431 | 1435 | }{} else undefined; |
| ... | ... | @@ -1451,7 +1455,7 @@ pub fn initPreopensWasi(alloc: Allocator, cwd_init: ?[]const u8) !void { |
| 1451 | 1455 | const preopen = wasi_cwd.preopens.?.findContaining(.{ .Dir = cwd }); |
| 1452 | 1456 | if (preopen) |po| { |
| 1453 | 1457 | wasi_cwd.cwd_preopen = po.base; |
| 1454 | | wasi_cwd.cwd = RelativePath{ |
| 1458 | wasi_cwd.cwd = RelativePathWasi{ |
| 1455 | 1459 | .dir_fd = po.base.fd, |
| 1456 | 1460 | .relative_path = po.relative_path, |
| 1457 | 1461 | }; |
| ... | ... | @@ -1470,13 +1474,13 @@ pub fn initPreopensWasi(alloc: Allocator, cwd_init: ?[]const u8) !void { |
| 1470 | 1474 | /// |
| 1471 | 1475 | /// For absolute paths, this automatically searches among available Preopens to find |
| 1472 | 1476 | /// a match. For relative paths, it uses the "emulated" CWD. |
| 1473 | | pub fn resolvePathWasi(path: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) !RelativePath { |
| 1474 | | // Note: Due to WASI's "sandboxed" file handles, operations with this RelativePath |
| 1477 | pub fn resolvePathWasi(path: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) !RelativePathWasi { |
| 1478 | // Note: Due to WASI's "sandboxed" file handles, operations with this RelativePathWasi |
| 1475 | 1479 | // will fail if the relative path navigates outside of `dir_fd` using ".." |
| 1476 | 1480 | return resolvePathAndGetWasiPreopen(path, null, out_buffer); |
| 1477 | 1481 | } |
| 1478 | 1482 | |
| 1479 | | fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffer: *[MAX_PATH_BYTES]u8) !RelativePath { |
| 1483 | fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffer: *[MAX_PATH_BYTES]u8) !RelativePathWasi { |
| 1480 | 1484 | var allocator = std.heap.FixedBufferAllocator.init(out_buffer); |
| 1481 | 1485 | var alloc = allocator.allocator(); |
| 1482 | 1486 | |
| ... | ... | @@ -1492,7 +1496,7 @@ fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffe |
| 1492 | 1496 | const rel_path = if (path.len > fd_end + 1) path[fd_end + 1 ..] else "."; |
| 1493 | 1497 | |
| 1494 | 1498 | if (preopen) |p| p.* = wasi_cwd.preopens.?.findByFd(fd); |
| 1495 | | return RelativePath{ |
| 1499 | return RelativePathWasi{ |
| 1496 | 1500 | .dir_fd = fd, |
| 1497 | 1501 | .relative_path = alloc.dupe(u8, rel_path) catch return error.NameTooLong, |
| 1498 | 1502 | }; |
| ... | ... | @@ -1504,7 +1508,7 @@ fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffe |
| 1504 | 1508 | |
| 1505 | 1509 | if (preopen_uri) |po| { |
| 1506 | 1510 | if (preopen) |p| p.* = po.base; |
| 1507 | | return RelativePath{ |
| 1511 | return RelativePathWasi{ |
| 1508 | 1512 | .dir_fd = po.base.fd, |
| 1509 | 1513 | .relative_path = po.relative_path, |
| 1510 | 1514 | }; |
| ... | ... | @@ -1529,7 +1533,7 @@ fn resolvePathAndGetWasiPreopen(path: []const u8, preopen: ?*?Preopen, out_buffe |
| 1529 | 1533 | const resolved_relative_path = resolved_path[1..]; |
| 1530 | 1534 | |
| 1531 | 1535 | if (preopen) |p| p.* = wasi_cwd.cwd_preopen; |
| 1532 | | return RelativePath{ |
| 1536 | return RelativePathWasi{ |
| 1533 | 1537 | .dir_fd = cwd.dir_fd, |
| 1534 | 1538 | .relative_path = resolved_relative_path, |
| 1535 | 1539 | }; |
| ... | ... | @@ -1568,6 +1572,7 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: mode_t) Ope |
| 1568 | 1572 | return openatZ(dir_fd, &file_path_c, flags, mode); |
| 1569 | 1573 | } |
| 1570 | 1574 | |
| 1575 | /// A struct to contain all lookup/rights flags accepted by `wasi.path_open` |
| 1571 | 1576 | const WasiOpenOptions = struct { |
| 1572 | 1577 | oflags: wasi.oflags_t, |
| 1573 | 1578 | lookup_flags: wasi.lookupflags_t, |
| ... | ... | @@ -2232,8 +2237,8 @@ pub fn linkat( |
| 2232 | 2237 | var resolve_olddir: bool = (olddir == wasi.AT.FDCWD or fs.path.isAbsolute(oldpath)); |
| 2233 | 2238 | var resolve_newdir: bool = (newdir == wasi.AT.FDCWD or fs.path.isAbsolute(newpath)); |
| 2234 | 2239 | |
| 2235 | | var old: RelativePath = .{ .dir_fd = olddir, .relative_path = oldpath }; |
| 2236 | | var new: RelativePath = .{ .dir_fd = newdir, .relative_path = newpath }; |
| 2240 | var old: RelativePathWasi = .{ .dir_fd = olddir, .relative_path = oldpath }; |
| 2241 | var new: RelativePathWasi = .{ .dir_fd = newdir, .relative_path = newpath }; |
| 2237 | 2242 | |
| 2238 | 2243 | // Resolve absolute or CWD-relative paths to a path within a Preopen |
| 2239 | 2244 | if (resolve_olddir or resolve_newdir) { |
| ... | ... | @@ -2257,7 +2262,7 @@ pub fn linkat( |
| 2257 | 2262 | |
| 2258 | 2263 | /// WASI-only. The same as `linkat` but targeting WASI. |
| 2259 | 2264 | /// See also `linkat`. |
| 2260 | | pub fn linkatWasi(old: RelativePath, new: RelativePath, flags: i32) LinkatError!void { |
| 2265 | pub fn linkatWasi(old: RelativePathWasi, new: RelativePathWasi, flags: i32) LinkatError!void { |
| 2261 | 2266 | var old_flags: wasi.lookupflags_t = 0; |
| 2262 | 2267 | // TODO: Why is this not defined in wasi-libc? |
| 2263 | 2268 | if (flags & linux.AT.SYMLINK_FOLLOW != 0) old_flags |= wasi.LOOKUP_SYMLINK_FOLLOW; |
| ... | ... | @@ -2545,8 +2550,8 @@ pub fn renameat( |
| 2545 | 2550 | var resolve_old: bool = (old_dir_fd == wasi.AT.FDCWD or fs.path.isAbsolute(old_path)); |
| 2546 | 2551 | var resolve_new: bool = (new_dir_fd == wasi.AT.FDCWD or fs.path.isAbsolute(new_path)); |
| 2547 | 2552 | |
| 2548 | | var old: RelativePath = .{ .dir_fd = old_dir_fd, .relative_path = old_path }; |
| 2549 | | var new: RelativePath = .{ .dir_fd = new_dir_fd, .relative_path = new_path }; |
| 2553 | var old: RelativePathWasi = .{ .dir_fd = old_dir_fd, .relative_path = old_path }; |
| 2554 | var new: RelativePathWasi = .{ .dir_fd = new_dir_fd, .relative_path = new_path }; |
| 2550 | 2555 | |
| 2551 | 2556 | // Resolve absolute or CWD-relative paths to a path within a Preopen |
| 2552 | 2557 | if (resolve_old or resolve_new) { |
| ... | ... | @@ -2570,7 +2575,7 @@ pub fn renameat( |
| 2570 | 2575 | |
| 2571 | 2576 | /// WASI-only. Same as `renameat` expect targeting WASI. |
| 2572 | 2577 | /// See also `renameat`. |
| 2573 | | pub fn renameatWasi(old: RelativePath, new: RelativePath) RenameError!void { |
| 2578 | pub fn renameatWasi(old: RelativePathWasi, new: RelativePathWasi) RenameError!void { |
| 2574 | 2579 | switch (wasi.path_rename(old.dir_fd, old.relative_path.ptr, old.relative_path.len, new.dir_fd, new.relative_path.ptr, new.relative_path.len)) { |
| 2575 | 2580 | .SUCCESS => return, |
| 2576 | 2581 | .ACCES => return error.AccessDenied, |
| ... | ... | @@ -4495,7 +4500,7 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr |
| 4495 | 4500 | const path_w = try windows.sliceToPrefixedFileW(path); |
| 4496 | 4501 | return faccessatW(dirfd, path_w.span().ptr, mode, flags); |
| 4497 | 4502 | } else if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 4498 | | var resolved = RelativePath{ .dir_fd = dirfd, .relative_path = path }; |
| 4503 | var resolved = RelativePathWasi{ .dir_fd = dirfd, .relative_path = path }; |
| 4499 | 4504 | |
| 4500 | 4505 | const file = blk: { |
| 4501 | 4506 | if (dirfd == wasi.AT.FDCWD or fs.path.isAbsolute(path)) { |