]> granicus.if.org Git - nethack/commitdiff
yet more hangup (trunk only)
authornethack.rankin <nethack.rankin>
Fri, 2 Feb 2007 03:07:47 +0000 (03:07 +0000)
committernethack.rankin <nethack.rankin>
Fri, 2 Feb 2007 03:07:47 +0000 (03:07 +0000)
     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

index fca68e07d92d08e348f328ed66aee8839438e030..36a92b10b722cc51b0e30b2342d75a435196ea78 100644 (file)
@@ -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)