aboutsummaryrefslogtreecommitdiff
path: root/lib/std/fs
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-07-09 07:59:32 +0200
committerAndrew Kelley <andrew@ziglang.org>2020-07-12 21:02:33 +0000
commiteea7271c4e9d56e9c0fadcaac0ffef54ad786bf8 (patch)
tree55b5a649eae827d2c3d5d616418b4f67765721ed /lib/std/fs
parente1a5e061ca7897ce6e08b724d517a83ae439bf41 (diff)
downloadzig-eea7271c4e9d56e9c0fadcaac0ffef54ad786bf8.tar.gz
zig-eea7271c4e9d56e9c0fadcaac0ffef54ad786bf8.zip
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.
Diffstat (limited to 'lib/std/fs')
-rw-r--r--lib/std/fs/wasi.zig12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/std/fs/wasi.zig b/lib/std/fs/wasi.zig
index 4a897c78f7..149ede252d 100644
--- a/lib/std/fs/wasi.zig
+++ b/lib/std/fs/wasi.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const os = std.os;
const mem = std.mem;
+const math = std.math;
const Allocator = mem.Allocator;
usingnamespace std.os.wasi;
@@ -72,7 +73,7 @@ pub const PreopenList = struct {
const Self = @This();
- pub const Error = os.UnexpectedError || Allocator.Error;
+ pub const Error = error{ OutOfMemory, Overflow } || os.UnexpectedError;
/// Deinitialize with `deinit`.
pub fn init(allocator: *Allocator) Self {
@@ -94,6 +95,12 @@ pub const PreopenList = struct {
///
/// If called more than once, it will clear its contents every time before
/// issuing the syscalls.
+ ///
+ /// In the unlinkely event of overflowing the number of available file descriptors,
+ /// returns `error.Overflow`. In this case, even though an error condition was reached
+ /// the preopen list still contains all valid preopened file descriptors that are valid
+ /// for use. Therefore, it is fine to call `find`, `asSlice`, or `toOwnedSlice`. Finally,
+ /// `deinit` still must be called!
pub fn populate(self: *Self) Error!void {
// Clear contents if we're being called again
for (self.toOwnedSlice()) |preopen| {
@@ -110,6 +117,7 @@ pub const PreopenList = struct {
ESUCCESS => {},
ENOTSUP => {
// not a preopen, so keep going
+ fd = try math.add(fd_t, fd, 1);
continue;
},
EBADF => {
@@ -127,7 +135,7 @@ pub const PreopenList = struct {
}
const preopen = Preopen.new(fd, PreopenType{ .Dir = path_buf });
try self.buffer.append(preopen);
- fd += 1;
+ fd = try math.add(fd_t, fd, 1);
}
}