| ... | @@ -7,6 +7,7 @@ const testing = std.testing; | ... | @@ -7,6 +7,7 @@ const testing = std.testing; |
| 7 | const assert = std.debug.assert; | 7 | const assert = std.debug.assert; |
| 8 | const Progress = @This(); | 8 | const Progress = @This(); |
| 9 | const posix = std.posix; | 9 | const posix = std.posix; |
| | 10 | const is_big_endian = builtin.cpu.arch.endian() == .big; |
| 10 | | 11 | |
| 11 | /// `null` if the current node (and its children) should | 12 | /// `null` if the current node (and its children) should |
| 12 | /// not print on update() | 13 | /// not print on update() |
| ... | @@ -101,6 +102,11 @@ pub const Node = struct { | ... | @@ -101,6 +102,11 @@ pub const Node = struct { |
| 101 | }; | 102 | }; |
| 102 | } | 103 | } |
| 103 | | 104 | |
| | 105 | fn byteSwap(s: *Storage) void { |
| | 106 | s.completed_count = @byteSwap(s.completed_count); |
| | 107 | s.estimated_total_count = @byteSwap(s.estimated_total_count); |
| | 108 | } |
| | 109 | |
| 104 | comptime { | 110 | comptime { |
| 105 | assert((@sizeOf(Storage) % 4) == 0); | 111 | assert((@sizeOf(Storage) % 4) == 0); |
| 106 | } | 112 | } |
| ... | @@ -719,9 +725,14 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff | ... | @@ -719,9 +725,14 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 719 | | 725 | |
| 720 | // Mount the root here. | 726 | // Mount the root here. |
| 721 | copyRoot(main_storage, &storage[0]); | 727 | copyRoot(main_storage, &storage[0]); |
| | 728 | if (is_big_endian) main_storage.byteSwap(); |
| 722 | | 729 | |
| 723 | // Copy the rest of the tree to the end. | 730 | // Copy the rest of the tree to the end. |
| 724 | @memcpy(serialized_buffer.storage[serialized_len..][0..nodes_len], storage[1..][0..nodes_len]); | 731 | const storage_dest = serialized_buffer.storage[serialized_len..][0..nodes_len]; |
| | 732 | @memcpy(storage_dest, storage[1..][0..nodes_len]); |
| | 733 | |
| | 734 | // Always little-endian over the pipe. |
| | 735 | if (is_big_endian) for (storage_dest) |*s| s.byteSwap(); |
| 725 | | 736 | |
| 726 | // Patch up parent pointers taking into account how the subtree is mounted. | 737 | // Patch up parent pointers taking into account how the subtree is mounted. |
| 727 | for (serialized_buffer.parents[serialized_len..][0..nodes_len], parents[1..][0..nodes_len]) |*dest, p| { | 738 | for (serialized_buffer.parents[serialized_len..][0..nodes_len], parents[1..][0..nodes_len]) |*dest, p| { |
| ... | @@ -983,6 +994,10 @@ fn write(buf: []const u8) anyerror!void { | ... | @@ -983,6 +994,10 @@ fn write(buf: []const u8) anyerror!void { |
| 983 | } | 994 | } |
| 984 | | 995 | |
| 985 | fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { | 996 | fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { |
| | 997 | // Byteswap if necessary to ensure little endian over the pipe. This is |
| | 998 | // needed because the parent or child process might be running in qemu. |
| | 999 | if (is_big_endian) for (serialized.storage) |*s| s.byteSwap(); |
| | 1000 | |
| 986 | assert(serialized.parents.len == serialized.storage.len); | 1001 | assert(serialized.parents.len == serialized.storage.len); |
| 987 | const serialized_len: u8 = @intCast(serialized.parents.len); | 1002 | const serialized_len: u8 = @intCast(serialized.parents.len); |
| 988 | const header = std.mem.asBytes(&serialized_len); | 1003 | const header = std.mem.asBytes(&serialized_len); |
| ... | @@ -995,9 +1010,6 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { | ... | @@ -995,9 +1010,6 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { |
| 995 | .{ .base = parents.ptr, .len = parents.len }, | 1010 | .{ .base = parents.ptr, .len = parents.len }, |
| 996 | }; | 1011 | }; |
| 997 | | 1012 | |
| 998 | // TODO: if big endian, byteswap | | |
| 999 | // this is needed because the parent or child process might be running in qemu | | |
| 1000 | | | |
| 1001 | // If this write would block we do not want to keep trying, but we need to | 1013 | // If this write would block we do not want to keep trying, but we need to |
| 1002 | // know if a partial message was written. | 1014 | // know if a partial message was written. |
| 1003 | if (posix.writev(fd, &vecs)) |written| { | 1015 | if (posix.writev(fd, &vecs)) |written| { |