Skip to content

SimSerial: add a Unix-socket console for input + line-buffered output - #37

Closed
rgrizzell wants to merge 1 commit into
l5yth:mainfrom
rgrizzell:simserial-socket-console
Closed

rgrizzell wants to merge 1 commit into
l5yth:mainfrom
rgrizzell:simserial-socket-console

Conversation

@rgrizzell

Copy link
Copy Markdown
Contributor

The Linux console (SimSerial, the Serial global) was output-only. begin() now opens a listening AF_UNIX socket. The path is $ARDULINUX_CONSOLE_SOCKET when set, else $XDG_RUNTIME_DIR/ardulinux/console.sock The socket is created mode 0600 in a 0700 directory: connecting grants the privileged local console, gated by filesystem permissions. stdout is line-buffered from construction, removing the need for stdbuf -oL.

Adds unit tests for client I/O, newline mapping, peek, the no-client default, socket permissions, no-SIGPIPE-on-write-after-disconnect, and reconnect through the available()-gated consumer loop shape.

The Linux console (SimSerial, the `Serial` global) was output-only:
available()/read()/peek() were stubbed, so a line-oriented CLI reading
`Serial` could never receive input, and write() used block-buffered
putchar(), so logs needed an external `stdbuf -oL` wrapper to reach
journald promptly.

begin() now opens a listening AF_UNIX socket. The path is
$ARDULINUX_CONSOLE_SOCKET when set, else $XDG_RUNTIME_DIR/ardulinux/
console.sock (fallback /tmp/ardulinux-<uid>/console.sock). A connected
client's bytes are delivered to read()/available()/peek() non-blocking,
and write() mirrors output to the client as well as stdout. Incoming
'\n' is mapped to '\r' (1:1, preserving available()/read() byte counts)
so CLIs that terminate on '\r' work with tools that send '\n'. The
socket is created mode 0600 in a 0700 directory: connecting grants the
privileged local console, gated by filesystem permissions. stdout is
line-buffered from construction, removing the need for `stdbuf -oL`.

Robustness for a consumer that only read()s when available()>0 (e.g. the
MeshCore repeater loop, which also logs continuously):
  - write() uses send(MSG_NOSIGNAL) so logging to a hung-up peer cannot
    raise SIGPIPE and terminate the daemon.
  - available() reaps a closed peer via a MSG_PEEK probe (FIONREAD can't
    distinguish "no data" from "closed"), then accepts the next client,
    so the console keeps working across reconnects.

Adds unit tests for client I/O, newline mapping, peek, the no-client
default, socket permissions, no-SIGPIPE-on-write-after-disconnect, and
reconnect through the available()-gated consumer loop shape.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBaSxeXYbJBJ7EYyfR3Lb
@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.95154% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cores/ardulinux/linux/LinuxSerial.cpp 81.60% 16 Missing ⚠️

📢 Thoughts on this report? Let us know!

@rgrizzell

Copy link
Copy Markdown
Contributor Author

@l5yth As far as MeshCore goes, this now allows meshcore-cli to configure Repeaters. I feel this was one of the missing features needed for a Production-ready Linux target.

Previously, making changes to a Repeater involved editing the config file and restarting meshcored. Alternatively, it could be configured with MeshCore companion over LoRa, but that requires the radios to share the same settings. Both options lead to friction when trying add configs for other Linux-based devices. If the radio config is not one-shot, it can take a while to figure out what's wrong. Being able to check the running config as well as forcing adverts over serial helps tremendously.

@rgrizzell

rgrizzell commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Made a big mistake here, the socket creation should have been abstracted into the Repeater code rather than SimSerial. I'll open a new PR for the stdout fix.

@rgrizzell
rgrizzell deleted the simserial-socket-console branch August 31, 2026 02:19
@l5yth

l5yth commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Thank you, this is useful. I'll take a look at #38.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants