diff options
| author | Shritesh Bhattarai <shritesh@shritesh.com> | 2019-04-29 20:54:30 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-04-29 21:54:30 -0400 |
| commit | 01365be82fb413061d052c2ecdb761d24d73125d (patch) | |
| tree | 87273e3249f22d624c55cfe0eab7a0ca38912078 /std/os.zig | |
| parent | 77383f968dde1e0d5d98865db8f560691d5f2afe (diff) | |
| download | zig-01365be82fb413061d052c2ecdb761d24d73125d.tar.gz zig-01365be82fb413061d052c2ecdb761d24d73125d.zip | |
WASI: implement argsAlloc and argsFree (#2364)
* wasi: change URL to canon WASI-core.md
* wasi: import args_get and args_sizes_get
* wasi: Implement argsAlloc and argsFree
* test return value for wasi arg syscalls
* wasi: return unexpectedErrorPosix in argsAlloc
* wasi: Add TODO for ArgIterator
Diffstat (limited to 'std/os.zig')
| -rw-r--r-- | std/os.zig | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/std/os.zig b/std/os.zig index ae2b04b759..139bc5b09d 100644 --- a/std/os.zig +++ b/std/os.zig @@ -2134,6 +2134,11 @@ pub const ArgIterator = struct { inner: InnerType, pub fn init() ArgIterator { + if (builtin.os == Os.wasi) { + // TODO: Figure out a compatible interface accomodating WASI + @compileError("ArgIterator is not yet supported in WASI. Use argsAlloc and argsFree instead."); + } + return ArgIterator{ .inner = InnerType.init() }; } @@ -2166,6 +2171,34 @@ pub fn args() ArgIterator { /// Caller must call argsFree on result. pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 { + if (builtin.os == Os.wasi) { + var count: usize = undefined; + var buf_size: usize = undefined; + + const args_sizes_get_ret = os.wasi.args_sizes_get(&count, &buf_size); + if (args_sizes_get_ret != os.wasi.ESUCCESS) { + return unexpectedErrorPosix(args_sizes_get_ret); + } + + var argv = try allocator.alloc([*]u8, count); + defer allocator.free(argv); + + var argv_buf = try allocator.alloc(u8, buf_size); + const args_get_ret = os.wasi.args_get(argv.ptr, argv_buf.ptr); + if (args_get_ret != os.wasi.ESUCCESS) { + return unexpectedErrorPosix(args_get_ret); + } + + var result_slice = try allocator.alloc([]u8, count); + + var i: usize = 0; + while (i < count) : (i += 1) { + result_slice[i] = mem.toSlice(u8, argv[i]); + } + + return result_slice; + } + // TODO refactor to only make 1 allocation. var it = args(); var contents = try Buffer.initSize(allocator, 0); @@ -2203,6 +2236,16 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 { } pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void { + if (builtin.os == Os.wasi) { + const last_item = args_alloc[args_alloc.len - 1]; + const last_byte_addr = @ptrToInt(last_item.ptr) + last_item.len + 1; // null terminated + const first_item_ptr = args_alloc[0].ptr; + const len = last_byte_addr - @ptrToInt(first_item_ptr); + allocator.free(first_item_ptr[0..len]); + + return allocator.free(args_alloc); + } + var total_bytes: usize = 0; for (args_alloc) |arg| { total_bytes += @sizeOf([]u8) + arg.len; |
