authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-09 07:59:32+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-12 21:02:33+00:00
logeea7271c4e9d56e9c0fadcaac0ffef54ad786bf8
tree55b5a649eae827d2c3d5d616418b4f67765721ed
parente1a5e061ca7897ce6e08b724d517a83ae439bf41

Fix incorrect continue condition in PreopeonList

Also, check for overflow on incremented file descriptors. Previously, we'd trigger a panic if we exceeded the `fd_t` resolution. Now, instead, we throw an `error.Overflow` to signal that there can be no more file descriptors available from the runtime. This way we give the user the ability to still be able to check if their desired preopen exists in the list or not.

1 files changed, 10 insertions(+), 2 deletions(-)

lib/std/fs/wasi.zig+10-2
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const os = std.os;2const os = std.os;
3const mem = std.mem;3const mem = std.mem;
4const math = std.math;
4const Allocator = mem.Allocator;5const Allocator = mem.Allocator;
56
6usingnamespace std.os.wasi;7usingnamespace std.os.wasi;
...@@ -72,7 +73,7 @@ pub const PreopenList = struct {...@@ -72,7 +73,7 @@ pub const PreopenList = struct {
7273
73 const Self = @This();74 const Self = @This();
7475
75 pub const Error = os.UnexpectedError || Allocator.Error;76 pub const Error = error{ OutOfMemory, Overflow } || os.UnexpectedError;
7677
77 /// Deinitialize with `deinit`.78 /// Deinitialize with `deinit`.
78 pub fn init(allocator: *Allocator) Self {79 pub fn init(allocator: *Allocator) Self {
...@@ -94,6 +95,12 @@ pub const PreopenList = struct {...@@ -94,6 +95,12 @@ pub const PreopenList = struct {
94 ///95 ///
95 /// If called more than once, it will clear its contents every time before96 /// If called more than once, it will clear its contents every time before
96 /// issuing the syscalls.97 /// issuing the syscalls.
98 ///
99 /// In the unlinkely event of overflowing the number of available file descriptors,
100 /// returns `error.Overflow`. In this case, even though an error condition was reached
101 /// the preopen list still contains all valid preopened file descriptors that are valid
102 /// for use. Therefore, it is fine to call `find`, `asSlice`, or `toOwnedSlice`. Finally,
103 /// `deinit` still must be called!
97 pub fn populate(self: *Self) Error!void {104 pub fn populate(self: *Self) Error!void {
98 // Clear contents if we're being called again105 // Clear contents if we're being called again
99 for (self.toOwnedSlice()) |preopen| {106 for (self.toOwnedSlice()) |preopen| {
...@@ -110,6 +117,7 @@ pub const PreopenList = struct {...@@ -110,6 +117,7 @@ pub const PreopenList = struct {
110 ESUCCESS => {},117 ESUCCESS => {},
111 ENOTSUP => {118 ENOTSUP => {
112 // not a preopen, so keep going119 // not a preopen, so keep going
120 fd = try math.add(fd_t, fd, 1);
113 continue;121 continue;
114 },122 },
115 EBADF => {123 EBADF => {
...@@ -127,7 +135,7 @@ pub const PreopenList = struct {...@@ -127,7 +135,7 @@ pub const PreopenList = struct {
127 }135 }
128 const preopen = Preopen.new(fd, PreopenType{ .Dir = path_buf });136 const preopen = Preopen.new(fd, PreopenType{ .Dir = path_buf });
129 try self.buffer.append(preopen);137 try self.buffer.append(preopen);
130 fd += 1;138 fd = try math.add(fd_t, fd, 1);
131 }139 }
132 }140 }
133141