Host control socket: a client that disconnects early kills vphone-cli with SIGPIPE

Open Beginner friendly
#472 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
74/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
swift

Research direction

Start in sources/vphone-cli/VPhoneHostControl.swift at VPhoneHostControl.writeResponse and the client setup after accept. Run the Python UNIX-socket reproduction from the issue, then verify that an early-disconnecting client no longer terminates vphone-cli. Also inspect the file’s command documentation and screenshot handling to resolve the stated screen:false discrepancy.

Written by the indexing model from the issue text.

Description

What happens

The VM exits when a host-control client disconnects before it has read the whole reply. The process exits silently: there is no crash report, and the launch log shows only the wrapper's exit diagnosis. The next connection to vphone.sock is refused.

This happened four times on 2026-09-17, each time right after a {"t":"screenshot","path":...} request.

Cause

VPhoneHostControl.writeResponse (sources/vphone-cli/VPhoneHostControl.swift, at 87f796c) calls write(2) in a loop on the client socket. Nothing in the process ignores SIGPIPE, and the socket does not set SO_NOSIGPIPE. When the peer has already closed the socket, the next write raises SIGPIPE, which kills vphone-cli and the VM with it.

The reply to a screenshot request is large, because the handler always attaches the base64 compact image (result.imageBase64 = await controller.captureCompactScreenshot()). A client that calls recv(4096) once and then closes is therefore enough to kill the VM:

s = socket.socket(socket.AF_UNIX)
s.connect(os.path.expanduser("~/.vphone/VMs/vphone/vphone.sock"))
s.sendall(b'{"t":"screenshot","path":"/tmp/x.png","screen":false}\n')
s.recv(4096)
s.close()

The cause was found by reading the code; no crash was captured during the failures.

Suggested fix

  • Set setsockopt(clientFD, SOL_SOCKET, SO_NOSIGPIPE, ...) after accept, or call signal(SIGPIPE, SIG_IGN) once at startup. writeResponse already stops when write returns a value <= 0, so an EPIPE there would end the request quietly.
  • The screenshot command ignores "screen":false, although the doc comment at the top of the file says every command respects it. Either honor the flag for screenshot or state in the doc comment that this command ignores it.
Dominant language
Swift
Stars
14k
Forks
1.7k
Avg merge
2d 10h
Merged PRs (30d)
9

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Lakr233/vphone-cli

All issues in Lakr233/vphone-cli

Similar issues

More Swift issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.