scaffold ptyc — C PTY-spawn helper (libc only)

One-shot helper that opens a PTY, forks a child, execvp's the given
argv with the slave as stdin/stdout/stderr, and hands the master fd
back to the caller over a unix socket via SCM_RIGHTS. Wire contract
is stdin JSON → stdout JSON + fd transfer per D-005; socket fd
defaults to 3 with PTYC_SOCK_FD override for language runtimes whose
subprocess machinery shuffles the low fd numbers.

Minimal JSON parser (no deps) scoped to the exact accepted shape.
Exec-failure pipe (CLOEXEC) reports child-side errors back without
zombies. Window size applied via TIOCSWINSZ before fork; child
becomes session leader + makes the slave its controlling TTY.

Root Makefile PTYX_PRESENT typo fixed → PTYC_PRESENT, and a
ptyc-test target added alongside ptyc-build / ptyc-clean. Eight
smoke tests pass (happy path, env replacement, cwd, window size,
bad argv, type errors, exec failure, unknown keys).

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-04-21 22:27:20 +02:00
co-authored by Claude
parent e2b3f7cff1
commit 0412a2284a
6 changed files with 799 additions and 3 deletions
+11 -3
View File
@@ -132,19 +132,27 @@ endif
# -- ptyc (C supporter tool) --------------------------------------------
# Compiled alongside the main binary. Tiny, no deps beyond libc.
PTYX_PRESENT := $(shell test -f ptyc/Makefile && echo yes || echo no)
PTYC_PRESENT := $(shell test -f ptyc/Makefile && echo yes || echo no)
.PHONY: ptyc-build
ptyc-build: ## Build the ptyc PTY-spawn helper.
ifeq ($(PTYX_PRESENT),yes)
ifeq ($(PTYC_PRESENT),yes)
$(MAKE) -C ptyc
else
@echo "(ptyc/ not scaffolded yet; skipping)"
endif
.PHONY: ptyc-test
ptyc-test: ## Run ptyc smoke tests (SCM_RIGHTS round-trip).
ifeq ($(PTYC_PRESENT),yes)
$(MAKE) -C ptyc test
else
@echo "(ptyc/ not scaffolded yet; skipping)"
endif
.PHONY: ptyc-clean
ptyc-clean: ## Clean ptyc build artefacts.
ifeq ($(PTYX_PRESENT),yes)
ifeq ($(PTYC_PRESENT),yes)
$(MAKE) -C ptyc clean
else
@echo "(ptyc/ not scaffolded yet; skipping)"