Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2001:
[Freeciv-Dev] Patch for civserver: save game on SIGPWR, SIGTERM or SIGHU
Home

[Freeciv-Dev] Patch for civserver: save game on SIGPWR, SIGTERM or SIGHU

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Patch for civserver: save game on SIGPWR, SIGTERM or SIGHUP
From: "Eric R. Smith" <ersmith@xxxxxxxxxxxxxx>
Date: Thu, 03 May 2001 13:32:36 -0300

Attached is a small patch to provide "emergency" saves when certain
signals (like SIGPWR) are received. This means that when your
fancy UPS notices that the power is down, it can shut down the
civserver without any moves or data being lost. It also provides
a way to "gracefully" shut down the server if you can't get
access to the console but can log in remotely -- just send it a
SIGTERM or SIGHUP signal. (Before, doing this just killed the
game with no save file being created.)

The diff is relative to freeciv-1.11.4, but it isn't very large,
so it'll probably apply to the CVS version of freeciv as well.

I've only been able to test this under Linux, but I've tried to
make sure it will compile on any system that has <signal.h>
(which, I think, includes Windows).

Thanks for a great game!
Eric
--- Orig/server/civserver.c     Thu May  3 09:50:51 2001
+++ freeciv-1.11.4/server/civserver.c   Thu May  3 10:10:58 2001
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <assert.h>
 #include <time.h>
+#include <signal.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -100,6 +101,7 @@
 static void ai_start_turn(void);
 static int is_game_over(void);
 static void save_game_auto(void);
+static RETSIGTYPE save_game_signal(int);
 static void generate_ai_players(void);
 static int mark_nation_as_used(int nation);
 static void announce_ai_player(struct player *pplayer);
@@ -475,6 +477,17 @@
 
   send_game_state(0, CLIENT_GAME_RUNNING_STATE);
 
+  /* if we get a termination signal after this point, save the game */
+#ifdef SIGTERM
+  signal(SIGTERM, save_game_signal);
+#endif
+#ifdef SIGPWR
+  signal(SIGPWR, save_game_signal);
+#endif
+#ifdef SIGHUP
+  signal(SIGHUP, save_game_signal);
+#endif
+
   while(server_state==RUN_GAME_STATE) {
     /* absolute beginning of a turn */
     freelog(LOG_DEBUG, "Begin turn");
@@ -977,6 +990,28 @@
              "%s%d.sav", game.save_name, game.year);
   save_game(filename);
   gamelog_save();              /* should this be in save_game()? --dwp */
+}
+
+/**************************************************************************
+Do an emergency save of the game if we lose power or get a TERM or HUP
+signal.
+**************************************************************************/
+static RETSIGTYPE save_game_signal(int signo)
+{
+  char filename[512];
+
+  assert(strlen(game.save_name)<256);
+  
+  my_snprintf(filename, sizeof(filename),
+             "%s%d_panic.sav", game.save_name, game.year);
+  save_game(filename);
+  gamelog_save();              /* should this be in save_game()? --dwp */
+
+  /* OK, let's get out of here */
+  server_close_udp();
+
+  /* anything else we have to do to clean up?? */
+  exit(2);
 }
 
 /**************************************************************************

[Prev in Thread] Current Thread [Next in Thread]