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