Skip to content

Improve client and daemon CLI affordances#134

Merged
kov merged 3 commits into
mainfrom
cli-affordances
Jun 10, 2026
Merged

Improve client and daemon CLI affordances#134
kov merged 3 commits into
mainfrom
cli-affordances

Conversation

@kov

@kov kov commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Third PR from the review pass (after #132 and #133), focused on usability of the two CLIs.

Error returns are decoded strace-style: = -2 (ENOENT: No such file or directory), via a full errno table built on libc constants; format_error_return() replaces the scattered open-coded error formatting.

Client usability batch:

  • --list-syscalls lists the supported names (SIGPIPE-safe for piping into head).
  • Unknown syscall names get a did-you-mean suggestion (Levenshtein over canonical names and aliases), and strace's -e trace=name,... qualifier syntax is accepted.
  • No-argument invocation prints usage to stderr instead of silently tracing nothing.
  • Friendlier D-Bus errors: child exec failures use shell conventions (126/127), a missing daemon suggests sudo systemctl start pinchy, a dead PID exits 9 with a clear message.
  • pinchyd previously had zero argument parsing (--help started the daemon); it now uses clap, handles SIGTERM like SIGINT, demotes periodic status chatter to debug logging, and prints a deliberate Pinchy daemon ready readiness marker — which the UML test runner now waits for instead of grepping incidental log text.
  • Crate metadata: description + default-run = "pinchy".
  • README: daemon install section (D-Bus policy, bus activation, systemd unit), corrected cargo run invocation, new flags documented.

Trace output goes to stderr by default (like strace), keeping the traced program's stdout clean, with -o/--output FILE to write to a file instead; flushing is tuned so a TTY gets per-event output while files/pipes batch. Integration assertions moved from stdout to stderr accordingly.

🤖 Generated with Claude Code

Failed syscalls printed only the raw value ("-2 (error)"), leaving the
user to decode errno numbers by hand for the single most common tracing
task. Decode -errno returns through a libc-constant table:

    openat(...) = -2 (ENOENT: No such file or directory)

All error formatting goes through the new format_error_return(); the
test suite's expectations are updated and integration tests gain an
@errno@ marker for errno-varying assertions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Pinchy’s client/daemon CLI usability and makes trace output/return formatting more strace-like across the codebase.

Changes:

  • Decode raw -errno syscall returns into -N (ENAME: description) via centralized format_error_return() / errno_info() and update tests accordingly.
  • Improve CLI ergonomics: syscall listing, “did you mean” suggestions, accept -e trace=... syntax, print usage on empty invocation, and send trace output to stderr by default (with -o/--output for files).
  • Make the daemon CLI behave like a proper CLI (--help/--version), add a stable readiness marker, and adjust UML runner + integration assertions for the new output streams/markers.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
uml-kernel/uml-test-runner.sh Wait for explicit daemon readiness marker; adjust latency probe to read trace output from stderr.
README.md Update run instructions (separate client/daemon), add daemon installation guidance, and document new CLI flags/env knobs.
pinchy/tests/integration.rs Move trace assertions from stdout to stderr; update expected errno formatting; add @ERRNO@ marker.
pinchy/src/tests/time.rs Update expected formatted errno strings.
pinchy/src/tests/system.rs Update expected formatted errno strings.
pinchy/src/tests/sync.rs Update expected formatted errno strings.
pinchy/src/tests/signal.rs Update expected formatted errno strings.
pinchy/src/tests/security.rs Update expected formatted errno strings.
pinchy/src/tests/scheduling.rs Update expected formatted errno strings.
pinchy/src/tests/return_values.rs Validate new errno decoding behavior in format_return_value().
pinchy/src/tests/process.rs Update expected formatted errno strings.
pinchy/src/tests/network.rs Update expected formatted errno strings.
pinchy/src/tests/memory.rs Update expected formatted errno strings.
pinchy/src/tests/ipc.rs Update expected formatted errno strings.
pinchy/src/tests/filesystem.rs Update expected formatted errno strings.
pinchy/src/server.rs Add clap parsing for daemon, SIGTERM handling, quieter logging, and a readiness marker.
pinchy/src/format_helpers.rs Centralize errno decoding (errno_info, format_error_return) and use it throughout format_return_value.
pinchy/src/client.rs Add syscall listing/suggestions, -o output support, default trace output to stderr, and updated flushing behavior.
pinchy/Cargo.toml Add crate description and set default-run.
pinchy-common/src/syscalls/mod.rs Export SYSCALL_ALIASES list from the syscall declaration macro.
pinchy-client/src/lib.rs Improve exec failure exit codes and D-Bus error messaging/exit codes.
.github/copilot-instructions.md Document new @ERRNO@ integration-test marker.

Comment thread pinchy-client/src/lib.rs Outdated
Comment on lines +56 to +68
// Only reached when exec failed. Use the shell convention: 126 for
// permission problems, 127 for command not found.
let err = std::io::Error::last_os_error();
eprintln!(
"pinchy: cannot execute '{}': {err}",
command[0].to_string_lossy()
);

let code = match err.raw_os_error() {
Some(libc::EACCES) | Some(libc::EPERM) => 126,
_ => 127,
};
std::process::exit(code);

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed and squashed into the affordances commit.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed and squashed into the affordances commit.

Comment thread pinchy/src/client.rs Outdated
Comment on lines +98 to +104
// Tolerate a closed pipe (e.g. `pinchy --list-syscalls | head`).
let mut out = std::io::stdout().lock();
for name in names {
if writeln!(out, "{name}").is_err() {
return;
}
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed and squashed into the affordances commit.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed and squashed into the affordances commit.

Client:
- --list-syscalls prints the supported names; unknown -e names now get
  a did-you-mean suggestion (canonical names and aliases) and a pointer
  to the list
- Accept strace's -e trace=name,... qualifier syntax
- Distinguish "no such PID" (exit 9) from permission denied; suggest
  how to start the daemon when the service is not running (also for
  failed bus activation)
- Failed exec of the traced command now prints why and exits with the
  shell convention (126/127) instead of silently exiting 255
- Give --format a help string and the crate a description so --help
  has an about line

Daemon:
- Parse arguments (--help/--version now work instead of being ignored)
- Handle SIGTERM like SIGINT so systemctl stop closes the bus cleanly
- Hint that root/CAP_BPF is needed when eBPF loading fails
- Demote periodic "Currently serving" and startup chatter to debug
  logging; the journal no longer gets a line every 5 seconds

README: document daemon installation (D-Bus policy/activation files,
systemd unit), fix the cargo run line (needs --bin pinchyd), document
--list-syscalls, --format and the tuning env vars.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kov kov force-pushed the cli-affordances branch from fba0ba9 to 6e90e8a Compare June 10, 2026 15:42
Trace lines used to share stdout with the traced program's own output,
making them impossible to separate. Follow strace's convention: stderr
by default, or a file via -o/--output. Flush latency heuristics now
look at the actual sink (stderr TTY, or threshold-only for files), and
the no-arguments usage message goes to stderr as well.

The daemon now prints a deliberate "Pinchy daemon ready" readiness
marker, which the UML test runner waits for (it previously grepped for
the "Waiting for Ctrl-C..." line that is now debug logging); the
runner's latency probe and the test assertions read the trace from
stderr.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kov kov force-pushed the cli-affordances branch from 6e90e8a to 6559ee5 Compare June 10, 2026 15:53
@kov kov merged commit b8acfd4 into main Jun 10, 2026
1 check passed
@kov kov deleted the cli-affordances branch June 10, 2026 16:02
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