self-exe: address portability review findings
Three fixes from an adversarial review of the new package:
- Cover the argv[0] fallback. The shell-style resolver only runs on
OpenBSD or a failed authoritative syscall, so on Linux/macOS/BSD --
where path() always takes the kernel source -- it had zero coverage,
yet it is the entire answer on OpenBSD. Extract it into an internal
Self_exe_resolve module (sub-library self-exe.resolve, public API
unchanged) and test it directly: absolute, relative, bare-via-PATH,
empty-PATH-entry-is-cwd, bare-name-not-searched-in-cwd, empty argv0,
and unknown name.
- Release the runtime lock across realpath in the C stub. It walks the
filesystem (an lstat per path component) and can block, so other
domains should run meanwhile; no OCaml value is live across the call.
- Build the child environment before fork in the test harness, not
between fork and execve, where only async-signal-safe work is allowed.