aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/Io/Dir.zig7
-rw-r--r--lib/std/Io/Threaded.zig17
-rw-r--r--lib/std/fs/test.zig8
-rw-r--r--lib/std/os/linux.zig2
4 files changed, 25 insertions, 9 deletions
diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig
index 2de0fbe564..330ac5bf62 100644
--- a/lib/std/Io/Dir.zig
+++ b/lib/std/Io/Dir.zig
@@ -102,7 +102,12 @@ pub const Reader = struct {
end: usize,
/// A length for `buffer` that allows all implementations to function.
- pub const min_buffer_len = std.mem.alignForward(usize, max_name_bytes, @alignOf(usize));
+ pub const min_buffer_len = switch (native_os) {
+ .linux => @sizeOf(std.os.linux.dirent64) +
+ std.mem.alignForward(usize, max_name_bytes, @alignOf(std.os.linux.dirent64)),
+ .windows => std.mem.alignForward(usize, max_name_bytes, @alignOf(usize)),
+ else => if (builtin.link_libc) @sizeOf(std.c.dirent) else std.mem.alignForward(usize, max_name_bytes, @alignOf(usize)),
+ };
pub const State = enum {
/// Indicates the next call to `read` should rewind and start over the
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
index 81c18a8c74..3472b8fbe2 100644
--- a/lib/std/Io/Threaded.zig
+++ b/lib/std/Io/Threaded.zig
@@ -3399,7 +3399,10 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
dr.state = .finished;
return 0;
},
- .INVAL => return error.Unexpected, // Linux may in some cases return EINVAL when reading /proc/$PID/net.
+ // This can occur when reading /proc/$PID/net, or
+ // if the provided buffer is too small. Neither
+ // scenario is intended to be handled by this API.
+ .INVAL => return error.Unexpected,
.ACCES => return error.AccessDenied, // Lacking permission to iterate this directory.
else => |err| return posix.unexpectedErrno(err),
}
@@ -3413,11 +3416,19 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
dr.index = 0;
dr.end = n;
}
- const linux_entry: *align(1) linux.dirent64 = @ptrCast(&dr.buffer[dr.index]);
+ // Linux aligns the header by padding after the null byte of the name
+ // to align the next entry. This means we can find the end of the name
+ // by looking at only the 8 bytes before the next record. However since
+ // file names are usually short it's better to keep the machine code
+ // simpler.
+ const linux_entry: *linux.dirent64 = @ptrCast(@alignCast(&dr.buffer[dr.index]));
const next_index = dr.index + linux_entry.reclen;
dr.index = next_index;
+ const name_ptr: [*]u8 = &linux_entry.name;
+ const padded_name = name_ptr[0 .. linux_entry.reclen - @offsetOf(linux.dirent64, "name")];
+ const name_len = std.mem.findScalar(u8, padded_name, 0).?;
+ const name = name_ptr[0..name_len :0];
- const name = std.mem.sliceTo(@as([*:0]u8, @ptrCast(&linux_entry.name)), 0);
if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue;
const entry_kind: File.Kind = switch (linux_entry.type) {
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig
index 19df1189fb..d66868379d 100644
--- a/lib/std/fs/test.zig
+++ b/lib/std/fs/test.zig
@@ -1418,12 +1418,12 @@ test "max file name component lengths" {
// On WASI, the maxed filename depends on the host OS, so in order for this test to
// work on any host, we need to use a length that will work for all platforms
// (i.e. the minimum max_name_bytes of all supported platforms).
- const maxed_wasi_filename1 = [_]u8{'1'} ** 255;
- const maxed_wasi_filename2 = [_]u8{'2'} ** 255;
+ const maxed_wasi_filename1: [255]u8 = @splat('1');
+ const maxed_wasi_filename2: [255]u8 = @splat('2');
try testFilenameLimits(io, tmp.dir, &maxed_wasi_filename1, &maxed_wasi_filename2);
} else {
- const maxed_ascii_filename1 = [_]u8{'1'} ** std.fs.max_name_bytes;
- const maxed_ascii_filename2 = [_]u8{'2'} ** std.fs.max_name_bytes;
+ const maxed_ascii_filename1: [Dir.max_name_bytes]u8 = @splat('1');
+ const maxed_ascii_filename2: [Dir.max_name_bytes]u8 = @splat('2');
try testFilenameLimits(io, tmp.dir, &maxed_ascii_filename1, &maxed_ascii_filename2);
}
}
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index 1db462ad3e..96b4c8ee6f 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -6040,7 +6040,7 @@ pub const dirent64 = extern struct {
off: u64,
reclen: u16,
type: u8,
- name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173
+ name: [0]u8,
};
pub const dl_phdr_info = extern struct {