summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/libutil.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2013-10-29 22:51:26 +0100
committerAdam Borowski <kilobyte@angband.pl>2013-10-29 22:51:26 +0100
commit8452be9eac2991b02cbb71ccb4827b48070e9243 (patch)
tree60f97e91468a5472432b68f7cedfe285f89b37d7 /crawl-ref/source/libutil.cc
parent15fdb53f75a829c72a08e10b654277c2c737d64a (diff)
downloadcrawl-ref-8452be9eac2991b02cbb71ccb4827b48070e9243.tar.gz
crawl-ref-8452be9eac2991b02cbb71ccb4827b48070e9243.zip
Add big fat (but not fat or scary enough) warnings about save corruption.
On a modern computer, crawl tends to process commands fast enough that closing the game is likely to happen during some waiting for event loop, and thus typically not cause not cause a lock-up or memory corruption but "merely" allow cheating. This is not acceptable, and once in a while you get more classical results of doing naughty stuff from a signal handler. One way of fixing this would be setting a flag (seen_hups) and killing any functions that wait for an event. This can be tricky because: * ncurses like to sabotage EINTR. We need to abort it both on SIGHUP and on SIGWINCH, without race conditions. The documentation says SIGWINCH is supposed to return a pseudo key code, KEY_RESIZE but this doesn't seem to be working. Not sure how to abort it on HUP. * win32's console functions don't have an equivalent to EINTR. Perhaps injecting a fake key with WriteConsoleInput would work? * same for tiles and Android. * yesno() without a safeanswer will loop forever
Diffstat (limited to 'crawl-ref/source/libutil.cc')
-rw-r--r--crawl-ref/source/libutil.cc10
1 files changed, 10 insertions, 0 deletions
diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc
index 294c88857f..40ccac81d0 100644
--- a/crawl-ref/source/libutil.cc
+++ b/crawl-ref/source/libutil.cc
@@ -1197,6 +1197,11 @@ static BOOL WINAPI console_handler(DWORD sig)
if (crawl_state.seen_hups++)
return true;
+ // SAVE CORRUPTING BUG!!! We're in a sort-of-a-signal-handler here,
+ // unlike Unix which processes signals as an interrupt, Windows spawns
+ // a new thread to handle them. This function will try to save the
+ // game when it is likely to be in an inconsistent state -- and even
+ // worse, the main thread is actively changing data structures.
sighup_save_and_exit();
return true;
}
@@ -1243,6 +1248,11 @@ static void handle_hangup(int)
// before the disconnected game is saved, thus (for example) preventing
// the hack of avoiding excomunication consesquences because of the
// more() after "You have lost your religion!"
+
+ // SAVE CORRUPTING BUG!!! We're in a signal handler, calling free()
+ // when closing the FILE object is likely to lead to lock-ups, and even
+ // if it were a plain kernel-side descriptor, calling functions such
+ // as select() or read() is undefined behaviour.
fclose(stdin);
}
# endif