serial: add pty sink (mode = "pty")#147
Merged
Merged
Conversation
Allocate a host pseudo-terminal and bridge Paula's serial port to it, so a terminal program (minicom/screen/picocom) attaches to the slave path directly, with no TCP in the loop. Unix only; opt-in via [serial] mode = "pty" or --serial pty. A background reader thread stages input, and the sink holds its own slave fd open so the master never EIO-spins while nothing is attached. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a Unix pseudo-terminal (“pty”) serial sink so the emulator can bridge Paula’s serial port directly to a host /dev/pts/N, enabling local terminal attachment without TCP.
Changes:
- Add
PtySerialSink(Unix-only) with a background reader thread andhas_pending_inputcounter, mirroring the existing TCP sink pattern. - Extend serial mode plumbing across config parsing, CLI/help text, emulator sink construction, and launcher UI labels to support
pty. - Document
tcpandptyserial modes incopperline.example.toml.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/serial.rs | Implements the new PtySerialSink and adds a unit test for pty round-tripping. |
| src/config.rs | Adds SerialMode::Pty, label support, and parsing/error-message updates. |
| src/emulator.rs | Wires SerialMode::Pty into build_serial_sink with Unix/non-Unix handling. |
| src/main.rs | Updates --serial CLI error/help text to include tcp/pty. |
| src/video/launcher.rs | Adds Pty to the launcher’s serial-mode picker and label mapping. |
| copperline.example.toml | Documents tcp and pty serial configuration options. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Warn when tcgetattr/tcsetattr fail instead of silently dropping raw mode, so a terminal that ends up echoing or rewriting CR/LF is diagnosable. Poll the pty with a 5s deadline in the round-trip test so an output regression fails instead of wedging CI on a blocking tty read. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LinuxJedi
approved these changes
Jul 7, 2026
LinuxJedi
left a comment
Owner
There was a problem hiding this comment.
Another great feature. Thanks again!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a pseudo-terminal serial sink:
[serial] mode = "pty"(or--serial pty).The emulator allocates a host pty, logs the slave path (
/dev/pts/N), andbridges Paula's serial port to it, so a terminal program attaches directly with
no network in the loop -- with an
AUX:shell on the Amiga side, a localAmigaDOS console.
What's here
PtySerialSink(Unix only):posix_openpt/grantpt/unlockpt/ptsname,slave line discipline set raw (no echo, no CR/LF rewriting) so the Amiga gets
bytes verbatim. Mirrors
TcpSerialSink: a background reader thread stagesinput into a channel and a signed counter drives
has_pending_input, soPaula's idle fast path polls a counter, never a syscall.
alive across terminal programs attaching/detaching, and stops the master read
from returning
EIO(the "no slave attached" error a naive blocking readerwould hot-spin on) while nothing is attached.
SerialMode::Pty,parse_serial_mode, launcher picker + label,build_serial_sink(errors clearly on non-Unix hosts).copperline.example.tomldocuments
pty(and fills in the previously-undocumentedtcpmode).Testing
pty_sink_round_trips_input_and_output: opens the sink, attaches tothe slave path, checks input staging and output delivery both directions.
--serial pty, ran anAUX:shellover the pty, drove it interactively from minicom/screen/picocom.
Not in this PR (follow-up): an opt-in output-cooking option (
0x9BC1 CSI ->7-bit
ESC[,\n->\r\n) so dumb/UTF-8 terminals render the Amiga consolewithout per-terminal termios tuning. Kept separate to keep this change small.
🤖 Generated with Claude Code