summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-19 13:24:40 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-19 13:24:40 +0000
commitc224298787a61857f6dabe87cdd7cda3be243ec2 (patch)
tree40721574bba1c9e045597d8af79c8c47edbe8d48
parentebbc40658731cd331bb003506c6d5113c778c4d0 (diff)
downloadcrawl-ref-c224298787a61857f6dabe87cdd7cda3be243ec2.tar.gz
crawl-ref-c224298787a61857f6dabe87cdd7cda3be243ec2.zip
SIGHUP handling for 0.1.6.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.1.6@674 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/AppHdr.h4
-rw-r--r--crawl-ref/source/acr.cc10
-rw-r--r--crawl-ref/source/externs.h15
-rw-r--r--crawl-ref/source/files.cc9
-rw-r--r--crawl-ref/source/files.h2
-rw-r--r--crawl-ref/source/hiscores.cc10
-rw-r--r--crawl-ref/source/libunix.cc39
-rw-r--r--crawl-ref/source/libutil.h17
-rw-r--r--crawl-ref/source/misc.cc4
-rw-r--r--crawl-ref/source/ouch.cc17
10 files changed, 111 insertions, 16 deletions
diff --git a/crawl-ref/source/AppHdr.h b/crawl-ref/source/AppHdr.h
index 138915ea2e..5b62182a8c 100644
--- a/crawl-ref/source/AppHdr.h
+++ b/crawl-ref/source/AppHdr.h
@@ -95,6 +95,10 @@
#define MULTIUSER
#define USE_UNIX_SIGNALS
+ // If this is defined, Crawl will attempt to save and exit when it
+ // receives a hangup signal.
+ #define SIGHUP_SAVE
+
#define FILE_SEPARATOR '/'
#define CHARACTER_SET 0
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 134ef99b35..b71211e8f9 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -124,9 +124,10 @@
#include "view.h"
#include "stash.h"
-struct crawl_environment env;
-struct player you;
-struct system_environment SysEnv;
+crawl_environment env;
+player you;
+system_environment SysEnv;
+game_state crawl_state;
std::string init_file_location; // externed in newgame.cc
@@ -2827,6 +2828,9 @@ static bool initialise(void)
viewwindow(1, false); // This just puts the view up for the first turn.
activate_notes(true);
+
+ crawl_state.need_save = true;
+
return (ret);
}
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index dff17a277c..74c51e51aa 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -640,6 +640,21 @@ struct crawl_environment
extern struct crawl_environment env;
+// Track stuff for SIGHUP handling.
+struct game_state
+{
+ bool need_save; // Set to true when game has started.
+ bool saving_game; // Set to true while in save_game.
+ bool updating_scores; // Set to true while updating hiscores.
+
+ int seen_hups; // Set to true if SIGHUP received.
+
+ game_state() : need_save(false), saving_game(false),
+ updating_scores(false), seen_hups(0)
+ {
+ }
+};
+extern game_state crawl_state;
struct ghost_struct
{
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 241a367fb3..cecc2b96aa 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -1177,6 +1177,7 @@ void save_level(int level_saved, bool was_a_labyrinth, char where_were_you)
void save_game(bool leave_game)
{
+ unwind_bool saving_game(crawl_state.saving_game, true);
#ifdef STASH_TRACKING
/* Stashes */
@@ -1276,6 +1277,14 @@ void save_game(bool leave_game)
end(0);
} // end save_game()
+// Saves the game without exiting.
+void save_game_state()
+{
+ save_game(false);
+ if (crawl_state.seen_hups)
+ save_game(true);
+}
+
void load_ghost(void)
{
char majorVersion;
diff --git a/crawl-ref/source/files.h b/crawl-ref/source/files.h
index 93a837b659..ecc900494c 100644
--- a/crawl-ref/source/files.h
+++ b/crawl-ref/source/files.h
@@ -52,6 +52,8 @@ void load( unsigned char stair_taken, int load_mode, bool was_a_labyrinth,
* *********************************************************************** */
void save_game(bool leave_game);
+// Save game without exiting (used when changing levels).
+void save_game_state();
// last updated 12may2000 {dlb}
/* ***********************************************************************
diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc
index c0ccd75e43..27031e7337 100644
--- a/crawl-ref/source/hiscores.cc
+++ b/crawl-ref/source/hiscores.cc
@@ -105,6 +105,8 @@ std::string log_file_name()
void hiscores_new_entry( const scorefile_entry &ne )
{
+ unwind_bool score_update(crawl_state.updating_scores, true);
+
FILE *scores;
int i, total_entries;
bool inserted = false;
@@ -175,6 +177,8 @@ void hiscores_new_entry( const scorefile_entry &ne )
void logfile_new_entry( const scorefile_entry &ne )
{
+ unwind_bool logfile_update(crawl_state.updating_scores, true);
+
FILE *logfile;
scorefile_entry le = ne;
@@ -225,6 +229,8 @@ static void hiscores_print_entry(const scorefile_entry &se,
// Writes all entries in the scorefile to stdout in human-readable form.
void hiscores_print_all(int display_count, int format)
{
+ unwind_bool scorefile_display(crawl_state.updating_scores, true);
+
FILE *scores = hs_open("r", score_file_name());
if (scores == NULL)
{
@@ -249,6 +255,8 @@ void hiscores_print_all(int display_count, int format)
// hiscores_print_all.
void hiscores_print_list( int display_count, int format )
{
+ unwind_bool scorefile_display(crawl_state.updating_scores, true);
+
FILE *scores;
int i, total_entries;
@@ -437,8 +445,6 @@ static bool unlock_file_handle( FILE *handle )
#endif
-
-
FILE *hs_open( const char *mode, const std::string &scores )
{
// allow reading from standard input
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc
index 3aee4c0981..5affa16940 100644
--- a/crawl-ref/source/libunix.cc
+++ b/crawl-ref/source/libunix.cc
@@ -45,6 +45,7 @@
#include "enum.h"
#include "externs.h"
+#include "files.h"
#include <termios.h>
@@ -198,6 +199,35 @@ int getch_ck() {
}
}
+#if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE)
+
+/* [ds] This SIGHUP handling is primitive and far from safe, but it
+ * should be better than nothing. Feel free to get rigorous on this.
+ */
+static void handle_hangup(int)
+{
+ if (crawl_state.seen_hups++)
+ return;
+
+ if (crawl_state.saving_game || crawl_state.updating_scores)
+ return;
+
+ crawl_state.saving_game = true;
+ if (crawl_state.need_save)
+ {
+ // save_game(true) also exits, saving us the trouble of doing so.
+ save_game(true);
+ }
+ else
+ {
+ // CROAK! No attempt to clean up curses. This is probably not an
+ // issue since the term has gone away.
+ exit(1);
+ }
+}
+
+#endif // USE_UNIX_SIGNALS && SIGHUP_SAVE
+
void unixcurses_startup( void )
{
termio_init();
@@ -210,12 +240,14 @@ void unixcurses_startup( void )
#ifdef SIGINT
signal(SIGINT, SIG_IGN);
#endif
-#endif
- //savetty();
+#ifdef SIGHUP_SAVE
+ signal(SIGHUP, handle_hangup);
+#endif
+
+#endif
initscr();
- // cbreak();
raw();
noecho();
@@ -228,7 +260,6 @@ void unixcurses_startup( void )
ESCDELAY = CURSES_SET_ESCDELAY;
#endif
#endif
- //cbreak();
meta(stdscr, TRUE);
start_color();
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index 6b31b93728..0f232baa72 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -125,6 +125,23 @@ enum KEYS
CK_CTRL_PGDN
};
+// Sets a boolean to a new value in the scope of the object instance.
+class unwind_bool
+{
+public:
+ unwind_bool(bool &val_, bool newval) : val(val_), oldval(val_)
+ {
+ val = newval;
+ }
+ ~unwind_bool()
+ {
+ val = oldval;
+ }
+private:
+ bool &val;
+ bool oldval;
+};
+
class cursor_control
{
public:
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index f08840d5bf..33be41d5df 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -634,7 +634,7 @@ void up_stairs(void)
you.turn_is_over = true;
- save_game(false);
+ save_game_state();
new_level();
@@ -1073,7 +1073,7 @@ void down_stairs( bool remove_stairs, int old_level, bool force )
you.turn_is_over = true;
- save_game(false);
+ save_game_state();
new_level();
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 1ee91d02b3..a4e0360e24 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -776,6 +776,9 @@ void ouch( int dam, int death_source, char death_type, const char *aux )
//okay, so you're dead:
+ crawl_state.need_save = false;
+ crawl_state.updating_scores = true;
+
// prevent bogus notes
activate_notes(false);
@@ -870,8 +873,8 @@ void end_game( struct scorefile_entry &se )
const int num_suffixes = sizeof(suffixes) / sizeof(const char*);
for ( i = 0; i < num_suffixes; ++i ) {
- std::string tmpname = basename + suffixes[i];
- unlink( tmpname.c_str() );
+ std::string tmpname = basename + suffixes[i];
+ unlink( tmpname.c_str() );
}
// death message
@@ -880,7 +883,9 @@ void end_game( struct scorefile_entry &se )
mpr("You die..."); // insert player name here? {dlb}
viewwindow(1, false); // don't do this for leaving/winning characters
}
- more();
+
+ if (!crawl_state.seen_hups)
+ more();
for (i = 0; i < ENDOFPACK; i++)
set_ident_flags( you.inv[i], ISFLAG_IDENT_MASK );
@@ -900,7 +905,8 @@ void end_game( struct scorefile_entry &se )
if (!dump_char( morgue_name(), !dead, true ))
{
mpr("Char dump unsuccessful! Sorry about that.");
- more();
+ if (!crawl_state.seen_hups)
+ more();
clrscr();
}
@@ -925,6 +931,7 @@ void end_game( struct scorefile_entry &se )
hiscores_print_list( get_number_of_lines() - lines - 5 );
// just to pause, actual value returned does not matter {dlb}
- get_ch();
+ if (!crawl_state.seen_hups)
+ get_ch();
end(0);
}