diff options
author | Adam Borowski <kilobyte@angband.pl> | 2013-10-29 22:51:26 +0100 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2013-10-29 22:51:26 +0100 |
commit | 8452be9eac2991b02cbb71ccb4827b48070e9243 (patch) | |
tree | 60f97e91468a5472432b68f7cedfe285f89b37d7 /crawl-ref/source/libutil.cc | |
parent | 15fdb53f75a829c72a08e10b654277c2c737d64a (diff) | |
download | crawl-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.cc | 10 |
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 |