@@ -73,9 +73,12 @@ skip_foreign_checks: bool,
73
73
/// external executor (such as qemu) but not fail if the executor is unavailable.
74
74
failing_to_execute_foreign_is_an_error : bool ,
75
75
76
+ /// Deprecated in favor of `stdio_limit`.
77
+ max_stdio_size : usize ,
78
+
76
79
/// If stderr or stdout exceeds this amount, the child process is killed and
77
80
/// the step fails.
78
- max_stdio_size : usize ,
81
+ stdio_limit : std.Io.Limit ,
79
82
80
83
captured_stdout : ? * Output ,
81
84
captured_stderr : ? * Output ,
@@ -186,6 +189,7 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {
186
189
.skip_foreign_checks = false ,
187
190
.failing_to_execute_foreign_is_an_error = true ,
188
191
.max_stdio_size = 10 * 1024 * 1024 ,
192
+ .stdio_limit = .unlimited ,
189
193
.captured_stdout = null ,
190
194
.captured_stderr = null ,
191
195
.dep_output_file = null ,
@@ -1011,7 +1015,7 @@ fn populateGeneratedPaths(
1011
1015
}
1012
1016
}
1013
1017
1014
- fn formatTerm (term : ? std.process.Child.Term , w : * std.io .Writer ) std.io .Writer.Error ! void {
1018
+ fn formatTerm (term : ? std.process.Child.Term , w : * std.Io .Writer ) std.Io .Writer.Error ! void {
1015
1019
if (term ) | t | switch (t ) {
1016
1020
.Exited = > | code | try w .print ("exited with code {d}" , .{code }),
1017
1021
.Signal = > | sig | try w .print ("terminated with signal {d}" , .{sig }),
@@ -1500,7 +1504,7 @@ fn evalZigTest(
1500
1504
const gpa = run .step .owner .allocator ;
1501
1505
const arena = run .step .owner .allocator ;
1502
1506
1503
- var poller = std .io .poll (gpa , enum { stdout , stderr }, .{
1507
+ var poller = std .Io .poll (gpa , enum { stdout , stderr }, .{
1504
1508
.stdout = child .stdout .? ,
1505
1509
.stderr = child .stderr .? ,
1506
1510
});
@@ -1524,11 +1528,6 @@ fn evalZigTest(
1524
1528
break :failed false ;
1525
1529
};
1526
1530
1527
- const Header = std .zig .Server .Message .Header ;
1528
-
1529
- const stdout = poller .fifo (.stdout );
1530
- const stderr = poller .fifo (.stderr );
1531
-
1532
1531
var fail_count : u32 = 0 ;
1533
1532
var skip_count : u32 = 0 ;
1534
1533
var leak_count : u32 = 0 ;
@@ -1541,16 +1540,14 @@ fn evalZigTest(
1541
1540
var sub_prog_node : ? std.Progress.Node = null ;
1542
1541
defer if (sub_prog_node ) | n | n .end ();
1543
1542
1543
+ const stdout = poller .reader (.stdout );
1544
+ const stderr = poller .reader (.stderr );
1544
1545
const any_write_failed = first_write_failed or poll : while (true ) {
1545
- while (stdout .readableLength () < @sizeOf (Header )) {
1546
- if (! (try poller .poll ())) break :poll false ;
1547
- }
1548
- const header = stdout .reader ().readStruct (Header ) catch unreachable ;
1549
- while (stdout .readableLength () < header .bytes_len ) {
1550
- if (! (try poller .poll ())) break :poll false ;
1551
- }
1552
- const body = stdout .readableSliceOfLen (header .bytes_len );
1553
-
1546
+ const Header = std .zig .Server .Message .Header ;
1547
+ while (stdout .buffered ().len < @sizeOf (Header )) if (! try poller .poll ()) break :poll false ;
1548
+ const header = stdout .takeStruct (Header , .little ) catch unreachable ;
1549
+ while (stdout .buffered ().len < header .bytes_len ) if (! try poller .poll ()) break :poll false ;
1550
+ const body = stdout .take (header .bytes_len ) catch unreachable ;
1554
1551
switch (header .tag ) {
1555
1552
.zig_version = > {
1556
1553
if (! std .mem .eql (u8 , builtin .zig_version_string , body )) {
@@ -1607,9 +1604,9 @@ fn evalZigTest(
1607
1604
1608
1605
if (tr_hdr .flags .fail or tr_hdr .flags .leak or tr_hdr .flags .log_err_count > 0 ) {
1609
1606
const name = std .mem .sliceTo (md .string_bytes [md .names [tr_hdr .index ].. ], 0 );
1610
- const orig_msg = stderr .readableSlice ( 0 );
1611
- defer stderr .discard ( orig_msg .len );
1612
- const msg = std .mem .trim (u8 , orig_msg , "\n " );
1607
+ const stderr_contents = stderr .buffered ( );
1608
+ stderr .toss ( stderr_contents .len );
1609
+ const msg = std .mem .trim (u8 , stderr_contents , "\n " );
1613
1610
const label = if (tr_hdr .flags .fail )
1614
1611
"failed"
1615
1612
else if (tr_hdr .flags .leak )
@@ -1660,8 +1657,6 @@ fn evalZigTest(
1660
1657
},
1661
1658
else = > {}, // ignore other messages
1662
1659
}
1663
-
1664
- stdout .discard (body .len );
1665
1660
};
1666
1661
1667
1662
if (any_write_failed ) {
@@ -1670,9 +1665,9 @@ fn evalZigTest(
1670
1665
while (try poller .poll ()) {}
1671
1666
}
1672
1667
1673
- if ( stderr .readableLength () > 0 ) {
1674
- const msg = std . mem . trim ( u8 , try stderr . toOwnedSlice (), " \n " );
1675
- if ( msg . len > 0 ) run .step .result_stderr = msg ;
1668
+ const stderr_contents = std . mem . trim ( u8 , stderr .buffered (), " \n " );
1669
+ if ( stderr_contents . len > 0 ) {
1670
+ run .step .result_stderr = try arena . dupe ( u8 , stderr_contents ) ;
1676
1671
}
1677
1672
1678
1673
// Send EOF to stdin.
@@ -1795,28 +1790,43 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {
1795
1790
var stdout_bytes : ? []const u8 = null ;
1796
1791
var stderr_bytes : ? []const u8 = null ;
1797
1792
1793
+ run .stdio_limit = run .stdio_limit .min (.limited (run .max_stdio_size ));
1798
1794
if (child .stdout ) | stdout | {
1799
1795
if (child .stderr ) | stderr | {
1800
- var poller = std .io .poll (arena , enum { stdout , stderr }, .{
1796
+ var poller = std .Io .poll (arena , enum { stdout , stderr }, .{
1801
1797
.stdout = stdout ,
1802
1798
.stderr = stderr ,
1803
1799
});
1804
1800
defer poller .deinit ();
1805
1801
1806
1802
while (try poller .poll ()) {
1807
- if (poller .fifo (.stdout ).count > run .max_stdio_size )
1808
- return error .StdoutStreamTooLong ;
1809
- if (poller .fifo (.stderr ).count > run .max_stdio_size )
1810
- return error .StderrStreamTooLong ;
1803
+ if (run .stdio_limit .toInt ()) | limit | {
1804
+ if (poller .reader (.stderr ).buffered ().len > limit )
1805
+ return error .StdoutStreamTooLong ;
1806
+ if (poller .reader (.stderr ).buffered ().len > limit )
1807
+ return error .StderrStreamTooLong ;
1808
+ }
1811
1809
}
1812
1810
1813
- stdout_bytes = try poller .fifo (.stdout ). toOwnedSlice ( );
1814
- stderr_bytes = try poller .fifo (.stderr ). toOwnedSlice ( );
1811
+ stdout_bytes = try poller .toOwnedSlice (.stdout );
1812
+ stderr_bytes = try poller .toOwnedSlice (.stderr );
1815
1813
} else {
1816
- stdout_bytes = try stdout .deprecatedReader ().readAllAlloc (arena , run .max_stdio_size );
1814
+ var small_buffer : [1 ]u8 = undefined ;
1815
+ var stdout_reader = stdout .readerStreaming (& small_buffer );
1816
+ stdout_bytes = stdout_reader .interface .allocRemaining (arena , run .stdio_limit ) catch | err | switch (err ) {
1817
+ error .OutOfMemory = > return error .OutOfMemory ,
1818
+ error .ReadFailed = > return stdout_reader .err .? ,
1819
+ error .StreamTooLong = > return error .StdoutStreamTooLong ,
1820
+ };
1817
1821
}
1818
1822
} else if (child .stderr ) | stderr | {
1819
- stderr_bytes = try stderr .deprecatedReader ().readAllAlloc (arena , run .max_stdio_size );
1823
+ var small_buffer : [1 ]u8 = undefined ;
1824
+ var stderr_reader = stderr .readerStreaming (& small_buffer );
1825
+ stderr_bytes = stderr_reader .interface .allocRemaining (arena , run .stdio_limit ) catch | err | switch (err ) {
1826
+ error .OutOfMemory = > return error .OutOfMemory ,
1827
+ error .ReadFailed = > return stderr_reader .err .? ,
1828
+ error .StreamTooLong = > return error .StderrStreamTooLong ,
1829
+ };
1820
1830
}
1821
1831
1822
1832
if (stderr_bytes ) | bytes | if (bytes .len > 0 ) {
0 commit comments