#!/usr/bin/env bash # Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. # See LICENSE.md for license information. # SPDX-License-Identifier: MIT # # verify-be-serial.sh - both-directions RS-232 gate for the Be API ports. # # Runs SERTEST (examples/sertest: banner, then echo) in the port's VM # (scripts/lib/beGate.sh) with the machine's second serial port joined to # the host peer (tests/gate/serialLoopPeer.c) over TCP: the peer listens, # QEMU's COM2 connects to it, and JOEYLIB_SERIAL names COM2's device to the # program (Haiku's /dev/ports/pc_serial1; COM1 is the VM's console). The # peer waits for the banner, sends a probe and expects it echoed, so the # chain is JoeyLib's POSIX serial HAL (src/hosted/posix) -> the system's # termios -> its serial driver -> QEMU -> the host. QEMU's TCP serial carries no modem lines: DTR and the close's # settings are gated on SDL3 (verify-sdl3-serial.sh). # # BeOS R5 SKIPs: its serial driver finds the ports through the ISA plug and # play bus, which the VM goes without (installer/lib/beos.sh: it crashes R5 # in the fail-safe video mode), so the machine has none. # # Usage: scripts/verify-be-serial.sh [haiku|haiku32|beos] # Requires: the port's VM (component haikuVm, haikuVm32 or beosVm); # build/PORT/bin/SERTEST (make PORT). set -uo pipefail repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) source "$repo/scripts/lib/joeyEnv.sh" source "$repo/scripts/lib/beGate.sh" port=${1:-haiku} label="verify-be-serial ($port)" if [ "$port" = beos ]; then echo "$label: SKIP (the BeOS R5 VM has no serial ports: R5 finds them through the ISA plug and play bus, which the VM goes without)" exit 2 fi beNeed "$port" program=$(joeyExampleProgram sertest "$port") [ -x "$program" ] || { echo "$label: build SERTEST first (make $port)" >&2; exit 2; } bootSeconds=150 runSeconds=60 # SERTEST echoes until the job ends it peerPortMin=40000 peerPortSpan=20000 device=/dev/ports/pc_serial1 work=$(mktemp -d -t joeylib-be-serial.XXXXXX) peerPid="" cleanup() { beStop joeyStop "$peerPid" rm -rf "$work" } trap cleanup EXIT mkdir -p "$work/job/SERTEST" cp "$program" "$work/job/SERTEST/SERTEST" { printf 'ls /dev/ports > ports.txt\n' printf '(\n' beJobScript SERTEST SERTEST "" "$runSeconds" JOEYLIB_SERIAL="$device" printf ')\n' } > "$work/job/job.sh" beJobDisk "$work/job.img" "$work/job" peerPort=$((peerPortMin + RANDOM % peerPortSpan)) peer=$(joeyTool serialLoopPeer) || exit 1 "$peer" tcp-server "$peerPort" "$((bootSeconds + runSeconds))" > "$work/peer.log" 2>&1 & peerPid=$! sleep 1 beStart "$work" "$work/job.img" -serial "tcp:127.0.0.1:$peerPort" if ! beWaitJob "$work" "$bootSeconds"; then echo "$label: FAIL - the VM did not start the job within ${bootSeconds} s" >&2 exit 1 fi wait "$peerPid" peerStatus=$? peerPid="" beWaitExit "$work" "$((runSeconds + 60))" || true beJobGet "$work/job.img" ports.txt "$work/ports.txt" || true cat "$work/peer.log" if [ "$peerStatus" -eq 0 ]; then echo "$label: PASS (banner out, probe echoed through $device)" else echo "$label: FAIL - the probe did not come back through $device; the machine's ports: $(tr '\n' ' ' < "$work/ports.txt" 2> /dev/null)" >&2 exit 1 fi