https://gitlab.synchro.net/main/sbbs/-/commit/3ad14c32961933b9483230d5
Modified Files:
src/doors/syncconquer/door/door_io.c src/doors/syncduke/syncduke.h syncduke_door.c syncduke_io.c src/doors/syncduke/tests/test_evdev.c test_keymap.c test_kitty.c
Log Message:
doors: restore the terminal on the hangup path, not just on a clean exit
SyncDuke and SyncConquer both _exit(0) straight out of their hangup
handler, on the reasoning that "the socket is already dead". That holds
for a WRITE-side hangup. It does not hold for a read-side one: an EOF on
read leaves the write direction open, which is exactly what happens when
a user closes their client. The door then vanished without undoing what
it had turned on, and the next thing the BBS ran inherited a terminal in SyncTERM physical-key mode -- reports on, translated keys suppressed --
plus mouse tracking, a hidden cursor and no autowrap.
Both now run their terminal restore before _exit(). Each restore is
idempotent and its drain is bounded, so a genuinely dead socket costs a
failed write and nothing more. A re-entrancy guard handles the recursion
this creates on a dead socket, where the restore's flush calls back into
the hangup handler.
This adopts what syncretro (sr_door_hangup) and syncdoom (whose hangup
sets a flag and leaves via exit(), so atexit runs the restore) already
did, so all four doors now hand the terminal back on every exit path.
syncduke_term_restore() loses its static linkage and gains an idempotence guard; the three input tests, which link syncduke_door.c without
syncduke_io.c, stub it.
Verified: syncduke_hangup() provably runs the restore before _exit and
survives the dead-socket recursion (forked probe against the real syncduke_door.c), and a half-close -- client shutdown(SHUT_WR), door
still able to write -- makes a door emit the full restore and exit 0.
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net