| author | |
| committer | |
| log | 002d444964869a5fd4d588d45c46f3acfa16cf5d |
| tree | a92f8dcd1de9c85613a721d4f92f71f20bb520a4 |
| parent | 018e34271fe58e540dc46e8bca529ce399625bef |
4 files changed, 25 insertions(+), 9 deletions(-)
lib/std/Io/Dir.zig+6-1| ... | ... | @@ -102,7 +102,12 @@ pub const Reader = struct { |
| 102 | 102 | end: usize, |
| 103 | 103 | |
| 104 | 104 | /// A length for `buffer` that allows all implementations to function. |
| 105 | pub const min_buffer_len = std.mem.alignForward(usize, max_name_bytes, @alignOf(usize)); | |
| 105 | pub const min_buffer_len = switch (native_os) { | |
| 106 | .linux => @sizeOf(std.os.linux.dirent64) + | |
| 107 | std.mem.alignForward(usize, max_name_bytes, @alignOf(std.os.linux.dirent64)), | |
| 108 | .windows => std.mem.alignForward(usize, max_name_bytes, @alignOf(usize)), | |
| 109 | else => if (builtin.link_libc) @sizeOf(std.c.dirent) else std.mem.alignForward(usize, max_name_bytes, @alignOf(usize)), | |
| 110 | }; | |
| 106 | 111 | |
| 107 | 112 | pub const State = enum { |
| 108 | 113 | /// Indicates the next call to `read` should rewind and start over the |
lib/std/Io/Threaded.zig+14-3| ... | ... | @@ -3399,7 +3399,10 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir |
| 3399 | 3399 | dr.state = .finished; |
| 3400 | 3400 | return 0; |
| 3401 | 3401 | }, |
| 3402 | .INVAL => return error.Unexpected, // Linux may in some cases return EINVAL when reading /proc/$PID/net. | |
| 3402 | // This can occur when reading /proc/$PID/net, or | |
| 3403 | // if the provided buffer is too small. Neither | |
| 3404 | // scenario is intended to be handled by this API. | |
| 3405 | .INVAL => return error.Unexpected, | |
| 3403 | 3406 | .ACCES => return error.AccessDenied, // Lacking permission to iterate this directory. |
| 3404 | 3407 | else => |err| return posix.unexpectedErrno(err), |
| 3405 | 3408 | } |
| ... | ... | @@ -3413,11 +3416,19 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir |
| 3413 | 3416 | dr.index = 0; |
| 3414 | 3417 | dr.end = n; |
| 3415 | 3418 | } |
| 3416 | const linux_entry: *align(1) linux.dirent64 = @ptrCast(&dr.buffer[dr.index]); | |
| 3419 | // Linux aligns the header by padding after the null byte of the name | |
| 3420 | // to align the next entry. This means we can find the end of the name | |
| 3421 | // by looking at only the 8 bytes before the next record. However since | |
| 3422 | // file names are usually short it's better to keep the machine code | |
| 3423 | // simpler. | |
| 3424 | const linux_entry: *linux.dirent64 = @ptrCast(@alignCast(&dr.buffer[dr.index])); | |
| 3417 | 3425 | const next_index = dr.index + linux_entry.reclen; |
| 3418 | 3426 | dr.index = next_index; |
| 3427 | const name_ptr: [*]u8 = &linux_entry.name; | |
| 3428 | const padded_name = name_ptr[0 .. linux_entry.reclen - @offsetOf(linux.dirent64, "name")]; | |
| 3429 | const name_len = std.mem.findScalar(u8, padded_name, 0).?; | |
| 3430 | const name = name_ptr[0..name_len :0]; | |
| 3419 | 3431 | |
| 3420 | const name = std.mem.sliceTo(@as([*:0]u8, @ptrCast(&linux_entry.name)), 0); | |
| 3421 | 3432 | if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue; |
| 3422 | 3433 | |
| 3423 | 3434 | const entry_kind: File.Kind = switch (linux_entry.type) { |
lib/std/fs/test.zig+4-4| ... | ... | @@ -1418,12 +1418,12 @@ test "max file name component lengths" { |
| 1418 | 1418 | // On WASI, the maxed filename depends on the host OS, so in order for this test to |
| 1419 | 1419 | // work on any host, we need to use a length that will work for all platforms |
| 1420 | 1420 | // (i.e. the minimum max_name_bytes of all supported platforms). |
| 1421 | const maxed_wasi_filename1 = [_]u8{'1'} ** 255; | |
| 1422 | const maxed_wasi_filename2 = [_]u8{'2'} ** 255; | |
| 1421 | const maxed_wasi_filename1: [255]u8 = @splat('1'); | |
| 1422 | const maxed_wasi_filename2: [255]u8 = @splat('2'); | |
| 1423 | 1423 | try testFilenameLimits(io, tmp.dir, &maxed_wasi_filename1, &maxed_wasi_filename2); |
| 1424 | 1424 | } else { |
| 1425 | const maxed_ascii_filename1 = [_]u8{'1'} ** std.fs.max_name_bytes; | |
| 1426 | const maxed_ascii_filename2 = [_]u8{'2'} ** std.fs.max_name_bytes; | |
| 1425 | const maxed_ascii_filename1: [Dir.max_name_bytes]u8 = @splat('1'); | |
| 1426 | const maxed_ascii_filename2: [Dir.max_name_bytes]u8 = @splat('2'); | |
| 1427 | 1427 | try testFilenameLimits(io, tmp.dir, &maxed_ascii_filename1, &maxed_ascii_filename2); |
| 1428 | 1428 | } |
| 1429 | 1429 | } |
lib/std/os/linux.zig+1-1| ... | ... | @@ -6040,7 +6040,7 @@ pub const dirent64 = extern struct { |
| 6040 | 6040 | off: u64, |
| 6041 | 6041 | reclen: u16, |
| 6042 | 6042 | type: u8, |
| 6043 | name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173 | |
| 6043 | name: [0]u8, | |
| 6044 | 6044 | }; |
| 6045 | 6045 | |
| 6046 | 6046 | pub const dl_phdr_info = extern struct { |