Start drafting out openZ
parent
f127dee474
commit
d7ca220121
|
@ -879,6 +879,30 @@ pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t
|
|||
return openW(file_path_w.span(), flags, perm);
|
||||
}
|
||||
while (true) {
|
||||
if (builtin.os.tag == .wasi and !builtin.link_libc) {
|
||||
var dirfd: fd_t = undefined;
|
||||
var prefix: usize = undefined;
|
||||
const path = mem.span(file_path);
|
||||
|
||||
switch (wasi.resolve_preopen(path, &dirfd, &prefix)) {
|
||||
0 => {},
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
|
||||
const rel_path = path[prefix + 1 ..];
|
||||
// TODO map flags to wasi.oflag_t
|
||||
// TODO call wasi.fd_fdstat_get to verify rights
|
||||
// TODO adjust all flags to path_open
|
||||
var fd: fd_t = undefined;
|
||||
|
||||
switch (wasi.path_open(dirfd, 0x0, rel_path.ptr, rel_path.len, wasi.O_CREAT, 0x0, 0x0, 0x0, &fd)) {
|
||||
0 => {},
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
const rc = system.open(file_path, flags, perm);
|
||||
switch (errno(rc)) {
|
||||
0 => return @intCast(fd_t, rc),
|
||||
|
|
|
@ -12,6 +12,8 @@ pub const timespec = extern struct {
|
|||
tv_nsec: isize,
|
||||
};
|
||||
|
||||
pub const PATH_MAX = 4096; // TODO verify this!
|
||||
|
||||
// As defined in the wasi_snapshot_preview1 spec file:
|
||||
// https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
|
||||
pub const advice_t = u8;
|
||||
|
|
|
@ -20,6 +20,51 @@ comptime {
|
|||
pub const iovec_t = iovec;
|
||||
pub const ciovec_t = iovec_const;
|
||||
|
||||
fn is_prefix(preopen: []const u8, path: []const u8) bool {
|
||||
if (preopen.len > path.len) {
|
||||
return false;
|
||||
}
|
||||
var i: usize = 0;
|
||||
while (i < preopen.len) {
|
||||
std.debug.warn("{} == {}", .{ preopen[i], path[i] });
|
||||
if (preopen[i] != path[i]) {
|
||||
return false;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn resolve_preopen(path: []const u8, dirfd: *fd_t, prefix: *usize) errno_t {
|
||||
var fd: fd_t = 3; // start fd has to be beyond stdio fds
|
||||
var preopen_path = [_]u8{0} ** PATH_MAX;
|
||||
|
||||
while (true) {
|
||||
var buf: prestat_t = undefined;
|
||||
switch (fd_prestat_get(fd, &buf)) {
|
||||
ESUCCESS => {},
|
||||
EBADF => {
|
||||
break;
|
||||
},
|
||||
else => |err| return err,
|
||||
}
|
||||
const preopen_len = buf.u.dir.pr_name_len;
|
||||
switch (fd_prestat_dir_name(fd, &preopen_path, preopen_len)) {
|
||||
ESUCCESS => {},
|
||||
else => |err| return err,
|
||||
}
|
||||
if (is_prefix(preopen_path[0..preopen_len], path)) {
|
||||
dirfd.* = fd;
|
||||
prefix.* = preopen_len;
|
||||
return ESUCCESS;
|
||||
}
|
||||
std.mem.set(u8, &preopen_path, 0);
|
||||
fd += 1;
|
||||
}
|
||||
|
||||
return ENOTCAPABLE;
|
||||
}
|
||||
|
||||
pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
|
||||
pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
|
||||
|
||||
|
|
Loading…
Reference in New Issue