Skip to content

Commit f34b478

Browse files
authored
Merge pull request #24521 from ziglang/fs-streaming
std.fs.File: delete writeFileAll and friends
2 parents c41ac8f + 34d2778 commit f34b478

File tree

19 files changed

+722
-1945
lines changed

19 files changed

+722
-1945
lines changed

lib/compiler/build_runner.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ fn runStepNames(
708708

709709
const total_count = success_count + failure_count + pending_count + skipped_count;
710710
ttyconf.setColor(w, .cyan) catch {};
711-
w.writeAll("Build Summary:") catch {};
711+
w.writeAll("\nBuild Summary:") catch {};
712712
ttyconf.setColor(w, .reset) catch {};
713713
w.print(" {d}/{d} steps succeeded", .{ success_count, total_count }) catch {};
714714
if (skipped_count > 0) w.print("; {d} skipped", .{skipped_count}) catch {};

lib/compiler/objcopy.zig

Lines changed: 62 additions & 907 deletions
Large diffs are not rendered by default.

lib/std/Build/Step/Run.zig

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ pub const Output = struct {
169169
pub fn create(owner: *std.Build, name: []const u8) *Run {
170170
const run = owner.allocator.create(Run) catch @panic("OOM");
171171
run.* = .{
172-
.step = Step.init(.{
172+
.step = .init(.{
173173
.id = base_id,
174174
.name = name,
175175
.owner = owner,
@@ -1769,13 +1769,22 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {
17691769
child.stdin = null;
17701770
},
17711771
.lazy_path => |lazy_path| {
1772-
const path = lazy_path.getPath2(b, &run.step);
1773-
const file = b.build_root.handle.openFile(path, .{}) catch |err| {
1772+
const path = lazy_path.getPath3(b, &run.step);
1773+
const file = path.root_dir.handle.openFile(path.subPathOrDot(), .{}) catch |err| {
17741774
return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)});
17751775
};
17761776
defer file.close();
1777-
child.stdin.?.writeFileAll(file, .{}) catch |err| {
1778-
return run.step.fail("unable to write file to stdin: {s}", .{@errorName(err)});
1777+
// TODO https://github.com/ziglang/zig/issues/23955
1778+
var buffer: [1024]u8 = undefined;
1779+
var file_reader = file.reader(&buffer);
1780+
var stdin_writer = child.stdin.?.writer(&.{});
1781+
_ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) {
1782+
error.ReadFailed => return run.step.fail("failed to read from {f}: {t}", .{
1783+
path, file_reader.err.?,
1784+
}),
1785+
error.WriteFailed => return run.step.fail("failed to write to stdin: {t}", .{
1786+
stdin_writer.err.?,
1787+
}),
17791788
};
17801789
child.stdin.?.close();
17811790
child.stdin = null;

lib/std/c.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10497,9 +10497,9 @@ pub const sysconf = switch (native_os) {
1049710497

1049810498
pub const sf_hdtr = switch (native_os) {
1049910499
.freebsd, .macos, .ios, .tvos, .watchos, .visionos => extern struct {
10500-
headers: [*]const iovec_const,
10500+
headers: ?[*]const iovec_const,
1050110501
hdr_cnt: c_int,
10502-
trailers: [*]const iovec_const,
10502+
trailers: ?[*]const iovec_const,
1050310503
trl_cnt: c_int,
1050410504
},
1050510505
else => void,

lib/std/elf.zig

Lines changed: 102 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ pub const Header = struct {
482482
is_64: bool,
483483
endian: std.builtin.Endian,
484484
os_abi: OSABI,
485+
/// The meaning of this value depends on `os_abi`.
485486
abi_version: u8,
486487
type: ET,
487488
machine: EM,
@@ -494,205 +495,135 @@ pub const Header = struct {
494495
shnum: u16,
495496
shstrndx: u16,
496497

497-
pub fn program_header_iterator(self: Header, parse_source: anytype) ProgramHeaderIterator(@TypeOf(parse_source)) {
498-
return ProgramHeaderIterator(@TypeOf(parse_source)){
499-
.elf_header = self,
500-
.parse_source = parse_source,
498+
pub fn iterateProgramHeaders(h: Header, file_reader: *std.fs.File.Reader) ProgramHeaderIterator {
499+
return .{
500+
.elf_header = h,
501+
.file_reader = file_reader,
501502
};
502503
}
503504

504-
pub fn section_header_iterator(self: Header, parse_source: anytype) SectionHeaderIterator(@TypeOf(parse_source)) {
505-
return SectionHeaderIterator(@TypeOf(parse_source)){
506-
.elf_header = self,
507-
.parse_source = parse_source,
505+
pub fn iterateSectionHeaders(h: Header, file_reader: *std.fs.File.Reader) SectionHeaderIterator {
506+
return .{
507+
.elf_header = h,
508+
.file_reader = file_reader,
508509
};
509510
}
510511

511-
pub fn read(parse_source: anytype) !Header {
512-
var hdr_buf: [@sizeOf(Elf64_Ehdr)]u8 align(@alignOf(Elf64_Ehdr)) = undefined;
513-
try parse_source.seekableStream().seekTo(0);
514-
try parse_source.deprecatedReader().readNoEof(&hdr_buf);
515-
return Header.parse(&hdr_buf);
516-
}
512+
pub const ReadError = std.Io.Reader.Error || error{
513+
InvalidElfMagic,
514+
InvalidElfVersion,
515+
InvalidElfClass,
516+
InvalidElfEndian,
517+
};
517518

518-
pub fn parse(hdr_buf: *align(@alignOf(Elf64_Ehdr)) const [@sizeOf(Elf64_Ehdr)]u8) !Header {
519-
const hdr32 = @as(*const Elf32_Ehdr, @ptrCast(hdr_buf));
520-
const hdr64 = @as(*const Elf64_Ehdr, @ptrCast(hdr_buf));
521-
if (!mem.eql(u8, hdr32.e_ident[0..4], MAGIC)) return error.InvalidElfMagic;
522-
if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion;
519+
pub fn read(r: *std.Io.Reader) ReadError!Header {
520+
const buf = try r.peek(@sizeOf(Elf64_Ehdr));
523521

524-
const is_64 = switch (hdr32.e_ident[EI_CLASS]) {
525-
ELFCLASS32 => false,
526-
ELFCLASS64 => true,
527-
else => return error.InvalidElfClass,
528-
};
522+
if (!mem.eql(u8, buf[0..4], MAGIC)) return error.InvalidElfMagic;
523+
if (buf[EI_VERSION] != 1) return error.InvalidElfVersion;
529524

530-
const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) {
525+
const endian: std.builtin.Endian = switch (buf[EI_DATA]) {
531526
ELFDATA2LSB => .little,
532527
ELFDATA2MSB => .big,
533528
else => return error.InvalidElfEndian,
534529
};
535-
const need_bswap = endian != native_endian;
536530

531+
return switch (buf[EI_CLASS]) {
532+
ELFCLASS32 => .init(try r.takeStruct(Elf32_Ehdr, endian), endian),
533+
ELFCLASS64 => .init(try r.takeStruct(Elf64_Ehdr, endian), endian),
534+
else => return error.InvalidElfClass,
535+
};
536+
}
537+
538+
pub fn init(hdr: anytype, endian: std.builtin.Endian) Header {
537539
// Converting integers to exhaustive enums using `@enumFromInt` could cause a panic.
538540
comptime assert(!@typeInfo(OSABI).@"enum".is_exhaustive);
539-
const os_abi: OSABI = @enumFromInt(hdr32.e_ident[EI_OSABI]);
541+
return .{
542+
.is_64 = switch (@TypeOf(hdr)) {
543+
Elf32_Ehdr => false,
544+
Elf64_Ehdr => true,
545+
else => @compileError("bad type"),
546+
},
547+
.endian = endian,
548+
.os_abi = @enumFromInt(hdr.e_ident[EI_OSABI]),
549+
.abi_version = hdr.e_ident[EI_ABIVERSION],
550+
.type = hdr.e_type,
551+
.machine = hdr.e_machine,
552+
.entry = hdr.e_entry,
553+
.phoff = hdr.e_phoff,
554+
.shoff = hdr.e_shoff,
555+
.phentsize = hdr.e_phentsize,
556+
.phnum = hdr.e_phnum,
557+
.shentsize = hdr.e_shentsize,
558+
.shnum = hdr.e_shnum,
559+
.shstrndx = hdr.e_shstrndx,
560+
};
561+
}
562+
};
540563

541-
// The meaning of this value depends on `os_abi` so just make it available as `u8`.
542-
const abi_version = hdr32.e_ident[EI_ABIVERSION];
564+
pub const ProgramHeaderIterator = struct {
565+
elf_header: Header,
566+
file_reader: *std.fs.File.Reader,
567+
index: usize = 0,
543568

544-
const @"type" = if (need_bswap) blk: {
545-
comptime assert(!@typeInfo(ET).@"enum".is_exhaustive);
546-
const value = @intFromEnum(hdr32.e_type);
547-
break :blk @as(ET, @enumFromInt(@byteSwap(value)));
548-
} else hdr32.e_type;
569+
pub fn next(it: *ProgramHeaderIterator) !?Elf64_Phdr {
570+
if (it.index >= it.elf_header.phnum) return null;
571+
defer it.index += 1;
549572

550-
const machine = if (need_bswap) blk: {
551-
comptime assert(!@typeInfo(EM).@"enum".is_exhaustive);
552-
const value = @intFromEnum(hdr32.e_machine);
553-
break :blk @as(EM, @enumFromInt(@byteSwap(value)));
554-
} else hdr32.e_machine;
573+
if (it.elf_header.is_64) {
574+
const offset = it.elf_header.phoff + @sizeOf(Elf64_Phdr) * it.index;
575+
try it.file_reader.seekTo(offset);
576+
const phdr = try it.file_reader.interface.takeStruct(Elf64_Phdr, it.elf_header.endian);
577+
return phdr;
578+
}
555579

556-
return @as(Header, .{
557-
.is_64 = is_64,
558-
.endian = endian,
559-
.os_abi = os_abi,
560-
.abi_version = abi_version,
561-
.type = @"type",
562-
.machine = machine,
563-
.entry = int(is_64, need_bswap, hdr32.e_entry, hdr64.e_entry),
564-
.phoff = int(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff),
565-
.shoff = int(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff),
566-
.phentsize = int(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize),
567-
.phnum = int(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum),
568-
.shentsize = int(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize),
569-
.shnum = int(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum),
570-
.shstrndx = int(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx),
571-
});
580+
const offset = it.elf_header.phoff + @sizeOf(Elf32_Phdr) * it.index;
581+
try it.file_reader.seekTo(offset);
582+
const phdr = try it.file_reader.interface.takeStruct(Elf32_Phdr, it.elf_header.endian);
583+
return .{
584+
.p_type = phdr.p_type,
585+
.p_offset = phdr.p_offset,
586+
.p_vaddr = phdr.p_vaddr,
587+
.p_paddr = phdr.p_paddr,
588+
.p_filesz = phdr.p_filesz,
589+
.p_memsz = phdr.p_memsz,
590+
.p_flags = phdr.p_flags,
591+
.p_align = phdr.p_align,
592+
};
572593
}
573594
};
574595

575-
pub fn ProgramHeaderIterator(comptime ParseSource: anytype) type {
576-
return struct {
577-
elf_header: Header,
578-
parse_source: ParseSource,
579-
index: usize = 0,
580-
581-
pub fn next(self: *@This()) !?Elf64_Phdr {
582-
if (self.index >= self.elf_header.phnum) return null;
583-
defer self.index += 1;
584-
585-
if (self.elf_header.is_64) {
586-
var phdr: Elf64_Phdr = undefined;
587-
const offset = self.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * self.index;
588-
try self.parse_source.seekableStream().seekTo(offset);
589-
try self.parse_source.deprecatedReader().readNoEof(mem.asBytes(&phdr));
590-
591-
// ELF endianness matches native endianness.
592-
if (self.elf_header.endian == native_endian) return phdr;
593-
594-
// Convert fields to native endianness.
595-
mem.byteSwapAllFields(Elf64_Phdr, &phdr);
596-
return phdr;
597-
}
598-
599-
var phdr: Elf32_Phdr = undefined;
600-
const offset = self.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * self.index;
601-
try self.parse_source.seekableStream().seekTo(offset);
602-
try self.parse_source.deprecatedReader().readNoEof(mem.asBytes(&phdr));
603-
604-
// ELF endianness does NOT match native endianness.
605-
if (self.elf_header.endian != native_endian) {
606-
// Convert fields to native endianness.
607-
mem.byteSwapAllFields(Elf32_Phdr, &phdr);
608-
}
609-
610-
// Convert 32-bit header to 64-bit.
611-
return Elf64_Phdr{
612-
.p_type = phdr.p_type,
613-
.p_offset = phdr.p_offset,
614-
.p_vaddr = phdr.p_vaddr,
615-
.p_paddr = phdr.p_paddr,
616-
.p_filesz = phdr.p_filesz,
617-
.p_memsz = phdr.p_memsz,
618-
.p_flags = phdr.p_flags,
619-
.p_align = phdr.p_align,
620-
};
621-
}
622-
};
623-
}
596+
pub const SectionHeaderIterator = struct {
597+
elf_header: Header,
598+
file_reader: *std.fs.File.Reader,
599+
index: usize = 0,
624600

625-
pub fn SectionHeaderIterator(comptime ParseSource: anytype) type {
626-
return struct {
627-
elf_header: Header,
628-
parse_source: ParseSource,
629-
index: usize = 0,
630-
631-
pub fn next(self: *@This()) !?Elf64_Shdr {
632-
if (self.index >= self.elf_header.shnum) return null;
633-
defer self.index += 1;
634-
635-
if (self.elf_header.is_64) {
636-
var shdr: Elf64_Shdr = undefined;
637-
const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
638-
try self.parse_source.seekableStream().seekTo(offset);
639-
try self.parse_source.deprecatedReader().readNoEof(mem.asBytes(&shdr));
640-
641-
// ELF endianness matches native endianness.
642-
if (self.elf_header.endian == native_endian) return shdr;
643-
644-
// Convert fields to native endianness.
645-
mem.byteSwapAllFields(Elf64_Shdr, &shdr);
646-
return shdr;
647-
}
648-
649-
var shdr: Elf32_Shdr = undefined;
650-
const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
651-
try self.parse_source.seekableStream().seekTo(offset);
652-
try self.parse_source.deprecatedReader().readNoEof(mem.asBytes(&shdr));
653-
654-
// ELF endianness does NOT match native endianness.
655-
if (self.elf_header.endian != native_endian) {
656-
// Convert fields to native endianness.
657-
mem.byteSwapAllFields(Elf32_Shdr, &shdr);
658-
}
659-
660-
// Convert 32-bit header to 64-bit.
661-
return Elf64_Shdr{
662-
.sh_name = shdr.sh_name,
663-
.sh_type = shdr.sh_type,
664-
.sh_flags = shdr.sh_flags,
665-
.sh_addr = shdr.sh_addr,
666-
.sh_offset = shdr.sh_offset,
667-
.sh_size = shdr.sh_size,
668-
.sh_link = shdr.sh_link,
669-
.sh_info = shdr.sh_info,
670-
.sh_addralign = shdr.sh_addralign,
671-
.sh_entsize = shdr.sh_entsize,
672-
};
673-
}
674-
};
675-
}
601+
pub fn next(it: *SectionHeaderIterator) !?Elf64_Shdr {
602+
if (it.index >= it.elf_header.shnum) return null;
603+
defer it.index += 1;
676604

677-
fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) {
678-
if (is_64) {
679-
if (need_bswap) {
680-
return @byteSwap(int_64);
681-
} else {
682-
return int_64;
605+
if (it.elf_header.is_64) {
606+
try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf64_Shdr) * it.index);
607+
const shdr = try it.file_reader.interface.takeStruct(Elf64_Shdr, it.elf_header.endian);
608+
return shdr;
683609
}
684-
} else {
685-
return int32(need_bswap, int_32, @TypeOf(int_64));
686-
}
687-
}
688610

689-
fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {
690-
if (need_bswap) {
691-
return @byteSwap(int_32);
692-
} else {
693-
return int_32;
611+
try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf32_Shdr) * it.index);
612+
const shdr = try it.file_reader.interface.takeStruct(Elf32_Shdr, it.elf_header.endian);
613+
return .{
614+
.sh_name = shdr.sh_name,
615+
.sh_type = shdr.sh_type,
616+
.sh_flags = shdr.sh_flags,
617+
.sh_addr = shdr.sh_addr,
618+
.sh_offset = shdr.sh_offset,
619+
.sh_size = shdr.sh_size,
620+
.sh_link = shdr.sh_link,
621+
.sh_info = shdr.sh_info,
622+
.sh_addralign = shdr.sh_addralign,
623+
.sh_entsize = shdr.sh_entsize,
624+
};
694625
}
695-
}
626+
};
696627

697628
pub const ELFCLASSNONE = 0;
698629
pub const ELFCLASS32 = 1;

0 commit comments

Comments
 (0)