From 47f052e7b8a1e65c04245b3f8943170ba4c3d25d Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Fri, 2 Feb 2007 03:07:47 +0000 Subject: [PATCH] yet more hangup (trunk only) From two weeks ago: > The last of my intended hangup overhaul. Once hangup is detected, > replace currently loaded windowing routines with stubs that never do any > terminal I/O. Real interface routines call their siblings directly rather > than via the windowprocs pointers, so this shouldn't pull the rug out from > under them, but it also can't prevent whatever they have in progress at > the time of hangup from attempting further I/O once the handler returns. hangup_nhwindows() shouldn't call exit_nhwindows() prior to replacing windowprocs with no-ops. Even though the original intgerface can still access its own routines directly, the exit_nhwindows() routine probably releases its dynamic data structures. And those could be in active use if the hangup occurs while an interface routine is executing. --- src/windows.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/windows.c b/src/windows.c index fca68e07d..36a92b10b 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)windows.c 3.5 2007/01/17 */ +/* SCCS Id: @(#)windows.c 3.5 2007/02/01 */ /* Copyright (c) D. Cohrs, 1993. */ /* NetHack may be freely redistributed. See license for details. */ @@ -304,12 +304,33 @@ static struct window_procs hup_procs = { # endif /* STATUS_VIA_WINDOWPORT */ }; +static void FDECL((*previnterface_exit_nhwindows), (const char *)) = 0; + +/* hangup has occurred; switch to no-op user interface */ void nhwindows_hangup() { - if (iflags.window_inited) exit_nhwindows((char *)0); + /* don't call exit_nhwindows() directly here; if a hangup occurs + while interface code is executing, exit_nhwindows could knock + the interface's active data structures out from under itself */ + if (iflags.window_inited) + previnterface_exit_nhwindows = exit_nhwindows; windowprocs = hup_procs; - /* hup_init_nhwindows((int *)0, (char **)0); */ +} + +static void +hup_exit_nhwindows(lastgasp) +const char *lastgasp; +{ + /* core has called exit_nhwindows(); call the previous interface's + shutdown routine now; xxx_exit_nhwindows() needs to call other + xxx_ routines directly rather than through windowprocs pointers */ + if (previnterface_exit_nhwindows) { + lastgasp = 0; /* don't want exit routine to attempt extra output */ + (*previnterface_exit_nhwindows)(lastgasp); + previnterface_exit_nhwindows = 0; + } + iflags.window_inited = 0; } static int @@ -354,14 +375,6 @@ char **argv; iflags.window_inited = 1; } -/*ARGUSED*/ -static void -hup_exit_nhwindows(dummy) -const char *dummy; -{ - iflags.window_inited = 0; -} - /*ARGSUSED*/ static winid hup_create_nhwindow(type)