| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const os = std.os; | 2 | const os = std.os; |
| 3 | const mem = std.mem; | 3 | const mem = std.mem; |
| | 4 | const math = std.math; |
| 4 | const Allocator = mem.Allocator; | 5 | const Allocator = mem.Allocator; |
| 5 | | 6 | |
| 6 | usingnamespace std.os.wasi; | 7 | usingnamespace std.os.wasi; |
| ... | @@ -72,7 +73,7 @@ pub const PreopenList = struct { | ... | @@ -72,7 +73,7 @@ pub const PreopenList = struct { |
| 72 | | 73 | |
| 73 | const Self = @This(); | 74 | const Self = @This(); |
| 74 | | 75 | |
| 75 | pub const Error = os.UnexpectedError || Allocator.Error; | 76 | pub const Error = error{ OutOfMemory, Overflow } || os.UnexpectedError; |
| 76 | | 77 | |
| 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 before | 96 | /// 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 again | 105 | // 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 going | 119 | // 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 | } |
| 133 | | 141 | |