Offer post-crash safe settings on a per-mod basis

Offer to restore settings when loading a mod that crashed, not the first
mod that gets loaded after a crash. Before the first mod loaded (usually
baseq3) would get the option even if missionpack or some other mod crashed.

- Make pid files separate for each fs_game.
- Remove/write pid every time switching fs_game.
- Create path before writing pid file otherwise it fails on first run.
- Show mod description.txt or fs_game instead of engine name in abnormal
  exit message.
- Check com_fullyInitialized in Com_Error before removing PID,
  otherwise "ioquake3 --version" segfaults when accessing fs_gamevar->string
  (plus not fully initialized isn't really a normal shutdown).
This commit is contained in:
Zack Middleton 2016-10-09 16:55:36 -05:00
parent 1246d16834
commit 755b2f38f0
4 changed files with 87 additions and 41 deletions

View file

@ -167,16 +167,29 @@ char *Sys_GetClipboardData(void)
Sys_PIDFileName
=================
*/
static char *Sys_PIDFileName( void )
static char *Sys_PIDFileName( const char *gamedir )
{
const char *homePath = Cvar_VariableString( "fs_homepath" );
if( *homePath != '\0' )
return va( "%s/%s", homePath, PID_FILENAME );
return va( "%s/%s/%s", homePath, gamedir, PID_FILENAME );
return NULL;
}
/*
=================
Sys_RemovePIDFile
=================
*/
void Sys_RemovePIDFile( const char *gamedir )
{
char *pidFile = Sys_PIDFileName( gamedir );
if( pidFile != NULL )
remove( pidFile );
}
/*
=================
Sys_WritePIDFile
@ -184,9 +197,9 @@ Sys_WritePIDFile
Return qtrue if there is an existing stale PID file
=================
*/
qboolean Sys_WritePIDFile( void )
static qboolean Sys_WritePIDFile( const char *gamedir )
{
char *pidFile = Sys_PIDFileName( );
char *pidFile = Sys_PIDFileName( gamedir );
FILE *f;
qboolean stale = qfalse;
@ -212,6 +225,10 @@ qboolean Sys_WritePIDFile( void )
stale = qtrue;
}
if( FS_CreatePath( pidFile ) ) {
return 0;
}
if( ( f = fopen( pidFile, "w" ) ) != NULL )
{
fprintf( f, "%d", Sys_PID( ) );
@ -223,6 +240,31 @@ qboolean Sys_WritePIDFile( void )
return stale;
}
/*
=================
Sys_InitPIDFile
=================
*/
void Sys_InitPIDFile( const char *gamedir ) {
if( Sys_WritePIDFile( gamedir ) ) {
#ifndef DEDICATED
char message[1024];
char modName[MAX_OSPATH];
FS_GetModDescription( gamedir, modName, sizeof ( modName ) );
Q_CleanStr( modName );
Com_sprintf( message, sizeof (message), "The last time %s ran, "
"it didn't exit properly. This may be due to inappropriate video "
"settings. Would you like to start with \"safe\" video settings?", modName );
if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) {
Cvar_Set( "com_abnormalExit", "1" );
}
#endif
}
}
/*
=================
Sys_Exit
@ -238,13 +280,10 @@ static __attribute__ ((noreturn)) void Sys_Exit( int exitCode )
SDL_Quit( );
#endif
if( exitCode < 2 )
if( exitCode < 2 && com_fullyInitialized )
{
// Normal exit
char *pidFile = Sys_PIDFileName( );
if( pidFile != NULL )
remove( pidFile );
Sys_RemovePIDFile( FS_GetCurrentGameDir() );
}
NET_Shutdown( );