Skip to content

Report errors and exit statuses, add ping and an end marker for scripted runs - #26

Merged
fjtrujy merged 2 commits into
ps2dev:masterfrom
rickgaiser:runner-improvements
Oct 25, 2026
Merged

fjtrujy merged 2 commits into
ps2dev:masterfrom
rickgaiser:runner-improvements

Conversation

@rickgaiser

Copy link
Copy Markdown
Member

This makes ps2client usable from scripts and test runners: it now says what went wrong, with an exit status, instead of silently waiting for the timeout.

Fixes

  • Connection failures are reported. ps2link_connect always returned 0, so a ps2 that was off or not running ps2link only showed up as a timeout. ps2client now exits with an error, and connecting gives up after 3 s instead of the kernel's ~2 minutes. An unknown hostname no longer crashes it.
  • Console port in use is an error. If another ps2client already has UDP 0x4712, the bind failed silently and the run printed nothing. Now it exits with a message.
  • Lost connection is detected. When ps2link closes the request connection (reset, reboot, crash), recv returned 0 forever and the request thread spun at 100% CPU. Now ps2client exits. SIGPIPE is ignored, so a send on a closed connection no longer kills it.
  • Console output is byte-exact. Packets are not null-terminated, but were printed with printf("%s") from an uninitialized buffer. Packets over 1 KB were cut off by the receive buffer.
  • Argument checks. execee/execiop arguments longer than the 256-byte packet field overflowed the stack. Missing arguments (e.g. dumpmem with one argument) dereferenced NULL. Numbers accept 0x.
  • gsexec sent its size with htonl into a short, so it was always 0 on little-endian hosts.
  • Bounds checks for request packet lengths and directory descriptors; getstat no longer sends uninitialized data when stat fails.

Additions

  • Exit statuses: 0 ok, 64 usage, 69 ps2link not answering, 74 ps2link closed the connection, 75 console port in use, 124 idle timeout before the -e marker. Error messages go to stderr, so stdout carries only the ps2 console.
  • -e <marker>: exit when a console line contains the marker. The exit status is the number after status= on that line, e.g. a test printing @@END@@ status=1 as its last line.
  • ping: checks that ps2link answers through a host: request (EE side, IOP side and host connection), without writing a file. Exit 0 with the round trip time, or 69.
  • Commands that use host: files do the same check before sending the command, instead of the fixed sleep(1).
  • dumpreg accepts register type names (dma, intc, ..., vu1) as well as numbers.

Behaviour changes

  • Exit statuses are no longer always 0, and errors go to stderr.
  • reset, poweroff and the other commands that exit right away no longer open the request connection or bind the console port.
  • Note for ping: ps2link serves one host connection and a new client replaces the old one. Like any ps2client command, a ping cuts off the host: files of a program that is running.

Testing

  • tests/run-tests.sh runs ps2client against a fake ps2link (tests/fake_ps2link.py) in unprivileged Linux network namespaces, so no ps2 is needed. 36 checks: error paths, exit statuses, ping, the end marker, console packets, host: reads and the handshake retry.
  • Tested on a real ps2 with consecutive test runs (execee with arguments and host: files, -e, ping).
  • Built on Linux only; the Windows and macOS builds rely on CI.

🤖 Generated with Claude Code

Fixes:
- Report a failed connection instead of waiting for the timeout; connect
  with a 3 s timeout; do not crash on an unknown hostname.
- Fail when the console port is in use (another ps2client) instead of
  running without console output.
- Exit with meaningful statuses: 64 usage, 69 ps2link not answering,
  74 ps2link closed the connection, 75 console port in use.
- Detect ps2link closing the connection instead of spinning at 100% CPU;
  ignore SIGPIPE.
- Print console packets byte-exact (they are not null-terminated) and
  receive packets up to 64 KB instead of cutting them off at 1 KB.
- Check the length of execee/execiop arguments and the number of
  arguments of each command; parse 0x numbers.
- gsexec sent its size with htonl into a short (always 0).
- Bounds checks for request packets and directory descriptors;
  initialize getstat data when stat fails.
- Error messages go to stderr, so stdout is only the ps2 console.

Features:
- ping: check that ps2link answers through a host: request (EE side,
  IOP side and host connection), without writing a file.
- -e <marker>: exit when a console line contains the marker, with the
  number after "status=" as exit status (124 on idle timeout first).
- Commands that use host: files first wait until ps2link answers that
  check, instead of a fixed 1 s sleep.
- dumpreg accepts register type names.
tests/run-tests.sh runs ps2client against tests/fake_ps2link.py in
unprivileged Linux network namespaces, so no ps2 is needed. It covers
the error paths, exit statuses, ping, the end marker, console packets,
host: file reads and the handshake retry.

@fjtrujy fjtrujy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Amazing improvements

@fjtrujy
fjtrujy merged commit e154231 into ps2dev:master Oct 25, 2026
7 checks passed
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