| author | |
| committer | |
| log | e9cb8a777b88b124ddc093a09d2ae7a62b8cda81 |
| tree | 6a20ea5c755347e0df0e48cc7f038dc8a6647b99 |
| parent | 87be80f6e9d1aa95cb55a8d7ef95808ca4aba44b |
| parent | 9a69aede0e250c136de5f1e1b33f072d4d744ffc |
8 files changed, 121 insertions(+), 26 deletions(-)
.github/workflows/ci.yaml-18| ... | ... | @@ -50,24 +50,6 @@ jobs: |
| 50 | 50 | uses: actions/checkout@v4 |
| 51 | 51 | - name: Build and Test |
| 52 | 52 | run: sh ci/aarch64-linux-release.sh |
| 53 | riscv64-linux-debug: | |
| 54 | if: ${{ github.event_name == 'push' }} | |
| 55 | timeout-minutes: 1020 | |
| 56 | runs-on: [self-hosted, Linux, riscv64] | |
| 57 | steps: | |
| 58 | - name: Checkout | |
| 59 | uses: actions/checkout@v4 | |
| 60 | - name: Build and Test | |
| 61 | run: sh ci/riscv64-linux-debug.sh | |
| 62 | riscv64-linux-release: | |
| 63 | if: ${{ github.event_name == 'push' }} | |
| 64 | timeout-minutes: 900 | |
| 65 | runs-on: [self-hosted, Linux, riscv64] | |
| 66 | steps: | |
| 67 | - name: Checkout | |
| 68 | uses: actions/checkout@v4 | |
| 69 | - name: Build and Test | |
| 70 | run: sh ci/riscv64-linux-release.sh | |
| 71 | 53 | x86_64-macos-release: |
| 72 | 54 | runs-on: "macos-13" |
| 73 | 55 | env: |
.github/workflows/riscv.yaml created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | name: riscv | |
| 2 | on: | |
| 3 | workflow_dispatch: | |
| 4 | permissions: | |
| 5 | contents: read | |
| 6 | jobs: | |
| 7 | riscv64-linux-debug: | |
| 8 | timeout-minutes: 1020 | |
| 9 | runs-on: [self-hosted, Linux, riscv64] | |
| 10 | steps: | |
| 11 | - name: Checkout | |
| 12 | uses: actions/checkout@v4 | |
| 13 | - name: Build and Test | |
| 14 | run: sh ci/riscv64-linux-debug.sh | |
| 15 | riscv64-linux-release: | |
| 16 | timeout-minutes: 900 | |
| 17 | runs-on: [self-hosted, Linux, riscv64] | |
| 18 | steps: | |
| 19 | - name: Checkout | |
| 20 | uses: actions/checkout@v4 | |
| 21 | - name: Build and Test | |
| 22 | run: sh ci/riscv64-linux-release.sh |
lib/std/Io/Reader.zig+14| ... | ... | @@ -1303,6 +1303,13 @@ fn takeMultipleOf7Leb128(r: *Reader, comptime Result: type) TakeLeb128Error!Resu |
| 1303 | 1303 | } |
| 1304 | 1304 | |
| 1305 | 1305 | /// Left-aligns data such that `r.seek` becomes zero. |
| 1306 | /// | |
| 1307 | /// If `r.seek` is not already zero then `buffer` is mutated, making it illegal | |
| 1308 | /// to call this function with a const-casted `buffer`, such as in the case of | |
| 1309 | /// `fixed`. This issue can be avoided: | |
| 1310 | /// * in implementations, by attempting a read before a rebase, in which | |
| 1311 | /// case the read will return `error.EndOfStream`, preventing the rebase. | |
| 1312 | /// * in usage, by copying into a mutable buffer before initializing `fixed`. | |
| 1306 | 1313 | pub fn rebase(r: *Reader) void { |
| 1307 | 1314 | if (r.seek == 0) return; |
| 1308 | 1315 | const data = r.buffer[r.seek..r.end]; |
| ... | ... | @@ -1315,6 +1322,13 @@ pub fn rebase(r: *Reader) void { |
| 1315 | 1322 | /// if necessary. |
| 1316 | 1323 | /// |
| 1317 | 1324 | /// Asserts `capacity` is within the buffer capacity. |
| 1325 | /// | |
| 1326 | /// If the rebase occurs then `buffer` is mutated, making it illegal to call | |
| 1327 | /// this function with a const-casted `buffer`, such as in the case of `fixed`. | |
| 1328 | /// This issue can be avoided: | |
| 1329 | /// * in implementations, by attempting a read before a rebase, in which | |
| 1330 | /// case the read will return `error.EndOfStream`, preventing the rebase. | |
| 1331 | /// * in usage, by copying into a mutable buffer before initializing `fixed`. | |
| 1318 | 1332 | pub fn rebaseCapacity(r: *Reader, capacity: usize) void { |
| 1319 | 1333 | if (r.end > r.buffer.len - capacity) rebase(r); |
| 1320 | 1334 | } |
lib/std/Io/Writer.zig+45-4| ... | ... | @@ -2194,8 +2194,10 @@ pub const Discarding = struct { |
| 2194 | 2194 | const d: *Discarding = @alignCast(@fieldParentPtr("writer", w)); |
| 2195 | 2195 | d.count += w.end; |
| 2196 | 2196 | w.end = 0; |
| 2197 | if (limit == .nothing) return 0; | |
| 2197 | 2198 | if (file_reader.getSize()) |size| { |
| 2198 | 2199 | const n = limit.minInt64(size - file_reader.pos); |
| 2200 | if (n == 0) return error.EndOfStream; | |
| 2199 | 2201 | file_reader.seekBy(@intCast(n)) catch return error.Unimplemented; |
| 2200 | 2202 | w.end = 0; |
| 2201 | 2203 | d.count += n; |
| ... | ... | @@ -2489,18 +2491,17 @@ pub const Allocating = struct { |
| 2489 | 2491 | |
| 2490 | 2492 | fn sendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) FileError!usize { |
| 2491 | 2493 | if (File.Handle == void) return error.Unimplemented; |
| 2494 | if (limit == .nothing) return 0; | |
| 2492 | 2495 | const a: *Allocating = @fieldParentPtr("writer", w); |
| 2493 | 2496 | const gpa = a.allocator; |
| 2494 | 2497 | var list = a.toArrayList(); |
| 2495 | 2498 | defer setArrayList(a, list); |
| 2496 | 2499 | const pos = file_reader.pos; |
| 2497 | 2500 | const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line; |
| 2501 | if (additional == 0) return error.EndOfStream; | |
| 2498 | 2502 | list.ensureUnusedCapacity(gpa, limit.minInt64(additional)) catch return error.WriteFailed; |
| 2499 | 2503 | const dest = limit.slice(list.unusedCapacitySlice()); |
| 2500 | const n = file_reader.read(dest) catch |err| switch (err) { | |
| 2501 | error.ReadFailed => return error.ReadFailed, | |
| 2502 | error.EndOfStream => 0, | |
| 2503 | }; | |
| 2504 | const n = try file_reader.read(dest); | |
| 2504 | 2505 | list.items.len += n; |
| 2505 | 2506 | return n; |
| 2506 | 2507 | } |
| ... | ... | @@ -2522,3 +2523,43 @@ pub const Allocating = struct { |
| 2522 | 2523 | try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", a.getWritten()); |
| 2523 | 2524 | } |
| 2524 | 2525 | }; |
| 2526 | ||
| 2527 | test "discarding sendFile" { | |
| 2528 | var tmp_dir = testing.tmpDir(.{}); | |
| 2529 | defer tmp_dir.cleanup(); | |
| 2530 | ||
| 2531 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); | |
| 2532 | defer file.close(); | |
| 2533 | var r_buffer: [256]u8 = undefined; | |
| 2534 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); | |
| 2535 | try file_writer.interface.writeByte('h'); | |
| 2536 | try file_writer.interface.flush(); | |
| 2537 | ||
| 2538 | var file_reader = file_writer.moveToReader(); | |
| 2539 | try file_reader.seekTo(0); | |
| 2540 | ||
| 2541 | var w_buffer: [256]u8 = undefined; | |
| 2542 | var discarding: std.io.Writer.Discarding = .init(&w_buffer); | |
| 2543 | ||
| 2544 | _ = try file_reader.interface.streamRemaining(&discarding.writer); | |
| 2545 | } | |
| 2546 | ||
| 2547 | test "allocating sendFile" { | |
| 2548 | var tmp_dir = testing.tmpDir(.{}); | |
| 2549 | defer tmp_dir.cleanup(); | |
| 2550 | ||
| 2551 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); | |
| 2552 | defer file.close(); | |
| 2553 | var r_buffer: [256]u8 = undefined; | |
| 2554 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); | |
| 2555 | try file_writer.interface.writeByte('h'); | |
| 2556 | try file_writer.interface.flush(); | |
| 2557 | ||
| 2558 | var file_reader = file_writer.moveToReader(); | |
| 2559 | try file_reader.seekTo(0); | |
| 2560 | ||
| 2561 | var allocating: std.io.Writer.Allocating = .init(std.testing.allocator); | |
| 2562 | defer allocating.deinit(); | |
| 2563 | ||
| 2564 | _ = try file_reader.interface.streamRemaining(&allocating.writer); | |
| 2565 | } |
lib/std/os/windows.zig+34| ... | ... | @@ -1690,6 +1690,40 @@ pub fn getpeername(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.so |
| 1690 | 1690 | return ws2_32.getpeername(s, name, @as(*i32, @ptrCast(namelen))); |
| 1691 | 1691 | } |
| 1692 | 1692 | |
| 1693 | pub fn sendmsg( | |
| 1694 | s: ws2_32.SOCKET, | |
| 1695 | msg: *ws2_32.WSAMSG_const, | |
| 1696 | flags: u32, | |
| 1697 | ) i32 { | |
| 1698 | var bytes_send: DWORD = undefined; | |
| 1699 | if (ws2_32.WSASendMsg(s, msg, flags, &bytes_send, null, null) == ws2_32.SOCKET_ERROR) { | |
| 1700 | return ws2_32.SOCKET_ERROR; | |
| 1701 | } else { | |
| 1702 | return @as(i32, @as(u31, @intCast(bytes_send))); | |
| 1703 | } | |
| 1704 | } | |
| 1705 | ||
| 1706 | pub fn sendto(s: ws2_32.SOCKET, buf: [*]const u8, len: usize, flags: u32, to: ?*const ws2_32.sockaddr, to_len: ws2_32.socklen_t) i32 { | |
| 1707 | var buffer = ws2_32.WSABUF{ .len = @as(u31, @truncate(len)), .buf = @constCast(buf) }; | |
| 1708 | var bytes_send: DWORD = undefined; | |
| 1709 | if (ws2_32.WSASendTo(s, @as([*]ws2_32.WSABUF, @ptrCast(&buffer)), 1, &bytes_send, flags, to, @as(i32, @intCast(to_len)), null, null) == ws2_32.SOCKET_ERROR) { | |
| 1710 | return ws2_32.SOCKET_ERROR; | |
| 1711 | } else { | |
| 1712 | return @as(i32, @as(u31, @intCast(bytes_send))); | |
| 1713 | } | |
| 1714 | } | |
| 1715 | ||
| 1716 | pub fn recvfrom(s: ws2_32.SOCKET, buf: [*]u8, len: usize, flags: u32, from: ?*ws2_32.sockaddr, from_len: ?*ws2_32.socklen_t) i32 { | |
| 1717 | var buffer = ws2_32.WSABUF{ .len = @as(u31, @truncate(len)), .buf = buf }; | |
| 1718 | var bytes_received: DWORD = undefined; | |
| 1719 | var flags_inout = flags; | |
| 1720 | if (ws2_32.WSARecvFrom(s, @as([*]ws2_32.WSABUF, @ptrCast(&buffer)), 1, &bytes_received, &flags_inout, from, @as(?*i32, @ptrCast(from_len)), null, null) == ws2_32.SOCKET_ERROR) { | |
| 1721 | return ws2_32.SOCKET_ERROR; | |
| 1722 | } else { | |
| 1723 | return @as(i32, @as(u31, @intCast(bytes_received))); | |
| 1724 | } | |
| 1725 | } | |
| 1726 | ||
| 1693 | 1727 | pub fn poll(fds: [*]ws2_32.pollfd, n: c_ulong, timeout: i32) i32 { |
| 1694 | 1728 | return ws2_32.WSAPoll(fds, n, timeout); |
| 1695 | 1729 | } |
test/standalone/build.zig+1| ... | ... | @@ -31,6 +31,7 @@ pub fn build(b: *std.Build) void { |
| 31 | 31 | const tools_target = b.resolveTargetQuery(.{}); |
| 32 | 32 | for ([_][]const u8{ |
| 33 | 33 | // Alphabetically sorted. No need to build `tools/spirv/grammar.zig`. |
| 34 | "../../tools/dump-cov.zig", | |
| 34 | 35 | "../../tools/fetch_them_macos_headers.zig", |
| 35 | 36 | "../../tools/gen_macos_headers_c.zig", |
| 36 | 37 | "../../tools/gen_outline_atomics.zig", |
test/standalone/build.zig.zon+2-1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | .{ |
| 2 | .name = "standalone_test_cases", | |
| 2 | .name = .standalone_test_cases, | |
| 3 | .fingerprint = 0xc0dbdf9c818957be, | |
| 3 | 4 | .version = "0.0.0", |
| 4 | 5 | .dependencies = .{ |
| 5 | 6 | .simple = .{ |
tools/dump-cov.zig+3-3| ... | ... | @@ -33,7 +33,7 @@ pub fn main() !void { |
| 33 | 33 | defer coverage.deinit(gpa); |
| 34 | 34 | |
| 35 | 35 | var debug_info = std.debug.Info.load(gpa, exe_path, &coverage) catch |err| { |
| 36 | fatal("failed to load debug info for {}: {s}", .{ exe_path, @errorName(err) }); | |
| 36 | fatal("failed to load debug info for {f}: {s}", .{ exe_path, @errorName(err) }); | |
| 37 | 37 | }; |
| 38 | 38 | defer debug_info.deinit(gpa); |
| 39 | 39 | |
| ... | ... | @@ -42,10 +42,10 @@ pub fn main() !void { |
| 42 | 42 | cov_path.sub_path, |
| 43 | 43 | 1 << 30, |
| 44 | 44 | null, |
| 45 | @alignOf(SeenPcsHeader), | |
| 45 | .of(SeenPcsHeader), | |
| 46 | 46 | null, |
| 47 | 47 | ) catch |err| { |
| 48 | fatal("failed to load coverage file {}: {s}", .{ cov_path, @errorName(err) }); | |
| 48 | fatal("failed to load coverage file {f}: {s}", .{ cov_path, @errorName(err) }); | |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | 51 | var stdout_buffer: [4000]u8 = undefined; |