(svn r1154) -Add: [Network] Forked dedicated server (start openttd with -Df) (GeniusDex)
authortruelight
Sat, 18 Dec 2004 14:19:21 +0000
changeset 704 e843dd369938
parent 703 3f64a428fcbc
child 705 71cf9f0d7e7f
(svn r1154) -Add: [Network] Forked dedicated server (start openttd with -Df) (GeniusDex)
dedicated.c
ttd.c
unix.c
variables.h
win32.c
--- a/dedicated.c	Sat Dec 18 13:38:27 2004 +0000
+++ b/dedicated.c	Sat Dec 18 14:19:21 2004 +0000
@@ -26,8 +26,44 @@
 static void *_dedicated_video_mem;
 
 #ifdef UNIX
+/* We want to fork our dedicated server */
+void DedicatedFork()
+{
+	/* Fork the program */
+	_dedicated_pid = fork();
+	switch (_dedicated_pid) {
+		case -1:
+			perror("Unable to fork");
+			exit(1);
+		case 0:
+			// We're the child
+
+			/* Open the log-file to log all stuff too */
+			_log_file_fd = fopen(_log_file, "a");
+			if (!_log_file_fd) {
+				perror("Unable to open logfile");
+				exit(1);
+			}
+			/* Redirect stdout and stderr to log-file */
+			if (dup2(fileno(_log_file_fd), fileno(stdout)) == -1) {
+				perror("Re-routing stdout");
+				exit(1);
+			}
+			if (dup2(fileno(_log_file_fd), fileno(stderr)) == -1) {
+				perror("Re-routing stderr");
+				exit(1);
+			}
+			break;
+		default:
+			// We're the parent
+			printf("Loading dedicated server...\n");
+			printf("  - Forked to background with pid %d\n", _dedicated_pid);
+			exit(0);
+	}
+}
+
 /* Signal handlers */
-void DedicatedSignalHandler(int sig)
+static void DedicatedSignalHandler(int sig)
 {
 		_exit_game = true;
 		signal(sig, DedicatedSignalHandler);
@@ -57,7 +93,7 @@
 
 #ifdef UNIX
 
-bool InputWaiting()
+static bool InputWaiting()
 {
 	struct timeval tv;
 	fd_set readfds;
@@ -77,21 +113,48 @@
 		return false;
 }
 #else
-bool InputWaiting()
+static bool InputWaiting()
 {
 	return kbhit();
 }
 #endif
 
-static int DedicatedVideoMainLoop() {
+static void DedicatedHandleKeyInput()
+{
+#ifdef WIN32
+	char input;
+#endif
+	char input_line[200];
+
+#ifdef UNIX
+	if (InputWaiting()) {
+		fgets(input_line, 200, stdin);
+		// Forget about the final \n (or \r)
+		strtok(input_line, "\r\n");
+		IConsoleCmdExec(input_line);
+	}
+#else
+	if (InputWaiting()) {
+		input = getch();
+		printf("%c", input);
+		if (input != '\r')
+			snprintf(input_line, 200, "%s%c", input_line, input);
+		else {
+			printf("\n");
+			IConsoleCmdExec(input_line);
+			sprintf(input_line, "");
+		}
+	}
+#endif
+}
+
+static int DedicatedVideoMainLoop()
+{
 #ifndef WIN32
 	struct timeval tim;
-#else
-	char input;
 #endif
 	uint32 next_tick;
 	uint32 cur_ticks;
-	char input_line[200];
 
 #ifdef WIN32
 	next_tick = GetTickCount() + 30;
@@ -125,26 +188,8 @@
 
 		if (_exit_game) return ML_QUIT;
 
-#ifdef UNIX
-		if (InputWaiting()) {
-			fgets(input_line, 200, stdin);
-			// Forget about the final \n (or \r)
-			strtok(input_line, "\r\n");
-			IConsoleCmdExec(input_line);
-		}
-#else
-		if (InputWaiting()) {
-			input = getch();
-			printf("%c", input);
-			if (input != '\r')
-				snprintf(input_line, 200, "%s%c", input_line, input);
-			else {
-				printf("\n");
-				IConsoleCmdExec(input_line);
-				sprintf(input_line, "");
-			}
-		}
-#endif
+		if (!_dedicated_forks)
+			DedicatedHandleKeyInput();
 
 #ifdef WIN32
 		cur_ticks = GetTickCount();
--- a/ttd.c	Sat Dec 18 13:38:27 2004 +0000
+++ b/ttd.c	Sat Dec 18 14:19:21 2004 +0000
@@ -314,6 +314,7 @@
 		"  -G seed             = Set random seed\n"
 		"  -n [ip#player:port] = Start networkgame\n"
 		"  -D                  = Start dedicated server\n"
+		"  -f                  = Fork into the background (dedicated only)\n"
 		"  -i                  = Force to use the DOS palette (use this if you see a lot of pink)\n"
 		"  -p #player          = Player as #player (deprecated) (network only)\n"
 	);
@@ -516,6 +517,8 @@
 	if (_music_driver->is_song_playing()) ResetMusic();
 }
 
+extern void DedicatedFork();
+
 int ttd_main(int argc, char* argv[])
 {
 	MyGetOptData mgo;
@@ -531,12 +534,14 @@
 	_game_mode = GM_MENU;
 	_switch_mode = SM_MENU;
 	_switch_mode_errorstr = INVALID_STRING_ID;
+	_dedicated_forks = false;
+	_dedicated_enabled = false;
 
 	// The last param of the following function means this:
 	//   a letter means: it accepts that param (e.g.: -h)
 	//   a ':' behind it means: it need a param (e.g.: -m<driver>)
 	//   a '::' behind it means: it can optional have a param (e.g.: -d<debug>)
-	MyGetOptInit(&mgo, argc-1, argv+1, "m:s:v:hDn::l:eit:d::r:g::G:p:");
+	MyGetOptInit(&mgo, argc-1, argv+1, "m:s:v:hDfn::l:eit:d::r:g::G:p:");
 	while ((i = MyGetOpt(&mgo)) != -1) {
 		switch(i) {
 		case 'm': ttd_strlcpy(musicdriver, mgo.opt, sizeof(musicdriver)); break;
@@ -546,7 +551,11 @@
 				sprintf(musicdriver,"null");
 				sprintf(sounddriver,"null");
 				sprintf(videodriver,"dedicated");
+				_dedicated_enabled = true;
 			} break;
+		case 'f': {
+				_dedicated_forks = true;
+			}; break;
 		case 'n': {
 				network = true;
 				if (mgo.opt)
@@ -595,6 +604,13 @@
 	}
 
 	DeterminePaths();
+
+#ifdef UNIX
+	// We must fork here, or we'll end up without some resources we need (like sockets)
+	if (_dedicated_forks)
+		DedicatedFork();
+#endif
+
 	LoadFromConfig();
 
 	// override config?
@@ -604,6 +620,9 @@
 	if (resolution[0]) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; }
 	if (startdate != -1) _patches.starting_date = startdate;
 
+	if (_dedicated_forks && !_dedicated_enabled)
+		_dedicated_forks = false;
+
 	// enumerate language files
 	InitializeLanguagePacks();
 
--- a/unix.c	Sat Dec 18 13:38:27 2004 +0000
+++ b/unix.c	Sat Dec 18 14:19:21 2004 +0000
@@ -500,6 +500,7 @@
 	_path.gm_dir = str_fmt("%sgm/", _path.game_data_dir);
 	_path.data_dir = str_fmt("%sdata/", _path.game_data_dir);
 	_config_file = str_fmt("%sopenttd.cfg", _path.personal_dir);
+	_log_file = str_fmt("%sopenttd.log", _path.personal_dir);
 	
 #if defined CUSTOM_LANG_DIR
 	// sets the search path for lng files to the custom one
--- a/variables.h	Sat Dec 18 13:38:27 2004 +0000
+++ b/variables.h	Sat Dec 18 14:19:21 2004 +0000
@@ -322,6 +322,8 @@
 VARDEF char _savegame_format[8];
 
 VARDEF char *_config_file;
+VARDEF char *_log_file;
+VARDEF FILE *_log_file_fd;
 
 // NOSAVE: These can be recalculated from InitializeLandscapeVariables
 typedef struct {
@@ -419,6 +421,11 @@
 VARDEF int _debug_ai_level;
 VARDEF int _debug_net_level;
 
+/* Forking stuff */
+VARDEF bool _dedicated_forks;
+VARDEF bool _dedicated_enabled;
+VARDEF pid_t _dedicated_pid;
+
 void CDECL debug(const char *s, ...);
 #ifdef NO_DEBUG_MESSAGES
 	#define DEBUG(name, level)
--- a/win32.c	Sat Dec 18 13:38:27 2004 +0000
+++ b/win32.c	Sat Dec 18 14:19:21 2004 +0000
@@ -2061,6 +2061,7 @@
 	_path.lang_dir = str_fmt("%slang\\", cfg);
 
 	_config_file = str_fmt("%sopenttd.cfg", _path.personal_dir);
+	_log_file = str_fmt("%sopenttd.log", _path.personal_dir);
 
 	// make (auto)save and scenario folder
 	CreateDirectory(_path.save_dir, NULL);