#!/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-sdl3-serial.sh - both-directions RS-232 gate for the SDL3 port, and # the close's promise to put the line back. # # Runs SERTEST (examples/sertest: banner, then echo) with JOEYLIB_SERIAL # naming the guest end of a pseudo-terminal pair the host peer # (tests/gate/serialLoopPeer.c) makes: 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) -> termios -> the pty -> the host. Before the run the # guest end is set to 4800 baud with HUPCL on; SERTEST opens it at 9600. The # peer then has SERTEST close the port (its DTR check, which closes it twice # and leaves it closed; a pseudo-terminal has no modem lines, so DTR itself # is not judged here), and once SERTEST no longer holds the pty the line # must read 4800 again, with HUPCL off: the close puts back the speed the # port had and leaves DTR as it was. # # Usage: scripts/verify-sdl3-serial.sh # Requires: stty; build/sdl3/bin/SERTEST (make sdl3). set -uo pipefail repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) source "$repo/scripts/lib/joeyEnv.sh" label=verify-sdl3-serial program=$(joeyExampleProgram sertest sdl3) [ -x "$program" ] || { echo "$label: build SERTEST first (make sdl3)" >&2; exit 2; } wall=40 ptyWaitTries=40 closeWaitTries=40 speedBefore=4800 work=$(mktemp -d -t joeylib-sdl3-serial.XXXXXX) peerPid="" programPid="" cleanup() { touch "$work/release" joeyStop "$programPid" "$peerPid" rm -rf "$work" } trap cleanup EXIT peer=$(joeyTool serialLoopPeer) || exit 1 "$peer" pty "$work/pty.path" "$wall" --close-hold "$work/release" > "$work/peer.log" 2>&1 & peerPid=$! for ((tries = 0; tries < ptyWaitTries; tries++)); do [ -s "$work/pty.path" ] && break sleep 0.25 done [ -s "$work/pty.path" ] || { echo "$label: FAIL - the peer made no pty" >&2; exit 1; } pty=$(cat "$work/pty.path") stty -F "$pty" "$speedBefore" hupcl JOEYLIB_SERIAL="$pty" "$program" > "$work/program.log" 2>&1 & programPid=$! for ((tries = 0; tries < wall * 4; tries++)); do grep -q "^CLOSE \|^LOOP FAIL" "$work/peer.log" && break joeyAlive "$peerPid" || break sleep 0.25 done # The close is done when SERTEST no longer has the pty open. for ((tries = 0; tries < closeWaitTries; tries++)); do stillOpen=no for fd in /proc/"$programPid"/fd/*; do [ "$(readlink "$fd" 2> /dev/null)" = "$pty" ] && stillOpen=yes done [ "$stillOpen" = no ] && break sleep 0.25 done settings=$(stty -F "$pty" -a 2>&1) touch "$work/release" wait "$peerPid" peerPid="" cat "$work/peer.log" if ! grep -q "^LOOP PASS" "$work/peer.log"; then echo "$label: FAIL - the probe was not echoed" >&2 exit 1 fi if ! grep -q "^CLOSE PASS" "$work/peer.log" || [ "$stillOpen" = yes ]; then echo "$label: FAIL - SERTEST did not close the port" >&2 exit 1 fi speedAfter=$(printf '%s\n' "$settings" | sed -n 's/.*speed \([0-9]*\) baud.*/\1/p') if [ "$speedAfter" != "$speedBefore" ]; then echo "$label: FAIL - after the close the line runs at ${speedAfter:-?} baud, not the $speedBefore it had" >&2 exit 1 fi if ! printf '%s\n' "$settings" | grep -qw -- "-hupcl"; then echo "$label: FAIL - the close left HUPCL on, so the last close would drop DTR" >&2 exit 1 fi echo "$label: PASS (banner out, probe echoed through the pty; the close put back $speedBefore baud and left HUPCL off)"