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
▶ M src/loop.zig
+10, -7
jump to top
......@@ -1298,6 +1298,9 @@ pub const Daemon = struct {
12981298 // Chunk large files to stay under command-line length limits.
12991299 // 48000 is divisible by 3 (clean base64 boundaries) and encodes
13001300 // 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.
13011304 const chunk_size = 48000;
13021305 var offset: usize = 0;
13031306 var is_first = true;
......@@ -1311,16 +1314,16 @@ pub const Daemon = struct {
13111314 defer gpa.free(encoded);
13121315 _ = std.base64.standard.Encoder.encode(encoded, chunk);
13131316
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);
13161319 if (is_first) {
1317- self.queuePtyInput(gpa, "' | base64 -d > '");
1320+ try self.pty_write_buf.appendSlice(gpa, "' | base64 -d > '");
13181321 } else {
1319- self.queuePtyInput(gpa, "' | base64 -d >> '");
1322+ try self.pty_write_buf.appendSlice(gpa, "' | base64 -d >> '");
13201323 }
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");
13241327
13251328 offset = end;
13261329 is_first = false;
+22, -0
jump to top
......@@ -314,3 +314,25 @@ load test_helper
314314 [[ "$output" == *"12345678901234567890"* ]]
315315 }
316316
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+}