aboutsummaryrefslogtreecommitdiff
path: root/std/os.zig
diff options
context:
space:
mode:
authorShritesh Bhattarai <shritesh@shritesh.com>2019-04-29 20:54:30 -0500
committerAndrew Kelley <andrew@ziglang.org>2019-04-29 21:54:30 -0400
commit01365be82fb413061d052c2ecdb761d24d73125d (patch)
tree87273e3249f22d624c55cfe0eab7a0ca38912078 /std/os.zig
parent77383f968dde1e0d5d98865db8f560691d5f2afe (diff)
downloadzig-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.zig43
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;