Commit 1a6ce3c
Jay Hemnani
·
2026-10-18 03:06:46 -0400 EDT
parent df21d8e
fix: write files larger than the PTY input buffer
2 files changed,
+32,
-7
+10,
-7
jump to top
+10,
-7
jump to top
| ... | ... | @@ -1298,6 +1298,9 @@ pub const Daemon = struct { | |
| 1298 | 1298 | // Chunk large files to stay under command-line length limits. | |
| 1299 | 1299 | // 48000 is divisible by 3 (clean base64 boundaries) and encodes | |
| 1300 | 1300 | // to ~64KB, well under typical ARG_MAX. | |
| 1301 | + | // The commands skip queuePtyInput's cap: it would drop the chunks | |
| 1302 | + | // past PTY_WRITE_BUF_MAX and leave the file cut short. The payload | |
| 1303 | + | // is already bounded by ipc.MAX_PAYLOAD_LEN. | |
| 1301 | 1304 | const chunk_size = 48000; | |
| 1302 | 1305 | var offset: usize = 0; | |
| 1303 | 1306 | var is_first = true; |
| ... | ... | @@ -1311,16 +1314,16 @@ pub const Daemon = struct { | |
| 1311 | 1314 | defer gpa.free(encoded); | |
| 1312 | 1315 | _ = std.base64.standard.Encoder.encode(encoded, chunk); | |
| 1313 | 1316 | ||
| 1314 | - | self.queuePtyInput(gpa, "printf '%s' '"); | |
| 1315 | - | self.queuePtyInput(gpa, encoded); | |
| 1317 | + | try self.pty_write_buf.appendSlice(gpa, "printf '%s' '"); | |
| 1318 | + | try self.pty_write_buf.appendSlice(gpa, encoded); | |
| 1316 | 1319 | if (is_first) { | |
| 1317 | - | self.queuePtyInput(gpa, "' | base64 -d > '"); | |
| 1320 | + | try self.pty_write_buf.appendSlice(gpa, "' | base64 -d > '"); | |
| 1318 | 1321 | } else { | |
| 1319 | - | self.queuePtyInput(gpa, "' | base64 -d >> '"); | |
| 1322 | + | try self.pty_write_buf.appendSlice(gpa, "' | base64 -d >> '"); | |
| 1320 | 1323 | } | |
| 1321 | - | self.queuePtyInput(gpa, file_path); | |
| 1322 | - | self.queuePtyInput(gpa, "'"); | |
| 1323 | - | self.queuePtyInput(gpa, "\r"); | |
| 1324 | + | try self.pty_write_buf.appendSlice(gpa, file_path); | |
| 1325 | + | try self.pty_write_buf.appendSlice(gpa, "'"); | |
| 1326 | + | try self.pty_write_buf.appendSlice(gpa, "\r"); | |
| 1324 | 1327 | ||
| 1325 | 1328 | offset = end; | |
| 1326 | 1329 | is_first = false; |
+22,
-0
jump to top
+22,
-0
jump to top
| ... | ... | @@ -314,3 +314,25 @@ load test_helper | |
| 314 | 314 | [[ "$output" == *"12345678901234567890"* ]] | |
| 315 | 315 | } | |
| 316 | 316 | ||
| 317 | + | ||
| 318 | + | # ============================================================================ | |
| 319 | + | # Write | |
| 320 | + | # ============================================================================ | |
| 321 | + | ||
| 322 | + | @test "write: a file larger than the PTY input buffer arrives whole" { | |
| 323 | + | local src="$BATS_TEST_TMPDIR/src.bin" dst="$BATS_TEST_TMPDIR/dst.bin" i=0 | |
| 324 | + | head -c 400000 /dev/urandom > "$src" | |
| 325 | + | ||
| 326 | + | run timeout 10 "$ZMX" run test-write-large echo write-ready-marker | |
| 327 | + | [ "$status" -eq 0 ] | |
| 328 | + | wait_for_output test-write-large write-ready-marker | |
| 329 | + | ||
| 330 | + | run bash -c 'timeout 10 "$0" write test-write-large "$1" < "$2"' "$ZMX" "$dst" "$src" | |
| 331 | + | [ "$status" -eq 0 ] | |
| 332 | + | ||
| 333 | + | while (( i < 300 )) && ! cmp -s "$src" "$dst"; do | |
| 334 | + | sleep 0.1 | |
| 335 | + | (( i++ )) || true | |
| 336 | + | done | |
| 337 | + | cmp "$src" "$dst" | |
| 338 | + | } |