From 9ce3949248e40302b8474b49a42f778e933b0627 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Tue, 28 Jul 2009 05:40:26 +0000 Subject: Generalized solution to the "disconnect at --more--" problem (e.g., disconnect at the more after "You have lost your religion!" to avoid the negative consequences of excommunication): when a HUP signal is received, instead of immediately saving the game, close the stdin stream, which will cause all of the Curses calls which normal block on key-presses to unblock, so that the code after a more() call will execute before the disconnected game is saved (which will happen in _input() in acr.cc). This only affects Curses (non-tiles/console) UNIX builds which have both USE_UNIX_SIGNALS and SIGHUP_SAVE defined. Exceptions to the above: * If HUP is received during a call to yesno() with safeanswer == 0, then the game will be saved immediately, since there's no way for the function to tell which answer is safe to give automatically. * If HUP is received while selecting the target for a controlled teleport then the teleport will be canceled, since otherwise a target other than the intended one might be the one under the cursor when the disconnect happened. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10443 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/stuff.cc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'crawl-ref/source/stuff.cc') diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index bb949801dd..b9b55300eb 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -790,7 +790,7 @@ void end(int exit_code, bool print_error, const char *format, ...) } #if defined(WIN32CONSOLE) || defined(DOS) || defined(DGL_PAUSE_AFTER_ERROR) - if (exit_code && !crawl_state.arena) + if (exit_code && !crawl_state.arena && !crawl_state.seen_hups) { fprintf(stderr, "Hit Enter to continue...\n"); getchar(); @@ -1080,12 +1080,21 @@ bool yesno( const char *str, bool safe, int safeanswer, bool clear_after, int tmp = getchm(KMC_CONFIRM); +#if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE) && defined(USE_CURSES) + // Prevent infinite loop if Curses HUP signal handling happens; + // if there is no safe answer, then just save-and-exit immediately, + // since there's no way to know if it would be better to return + // true or false. + if (crawl_state.seen_hups && !safeanswer) + sighup_save_and_exit(); +#endif + if (map && map->find(tmp) != map->end()) tmp = map->find(tmp)->second; if (safeanswer && (tmp == ' ' || tmp == ESCAPE || tmp == CONTROL('G') - || tmp == '\r' || tmp == '\n')) + || tmp == '\r' || tmp == '\n' || crawl_state.seen_hups)) { tmp = safeanswer; } @@ -1181,8 +1190,11 @@ int yesnoquit( const char* str, bool safe, int safeanswer, bool allow_all, int tmp = getchm(KMC_CONFIRM); - if (tmp == CK_ESCAPE || tmp == CONTROL('G') || tmp == 'q' || tmp == 'Q') + if (tmp == CK_ESCAPE || tmp == CONTROL('G') || tmp == 'q' || tmp == 'Q' + || crawl_state.seen_hups) + { return -1; + } if ((tmp == ' ' || tmp == '\r' || tmp == '\n') && safeanswer) tmp = safeanswer; -- cgit v1.2.3-54-g00ecf