diff --git a/reaction/code/qcommon/common.c b/reaction/code/qcommon/common.c index 23d8db8c..7d0b7e9b 100644 --- a/reaction/code/qcommon/common.c +++ b/reaction/code/qcommon/common.c @@ -50,6 +50,7 @@ jmp_buf abortframe; // an ERR_DROP occured, exit the entire frame FILE *debuglogfile; +static fileHandle_t pipefile; static fileHandle_t logfile; fileHandle_t com_journalFile; // events are written here fileHandle_t com_journalDataFile; // config files are written here @@ -66,6 +67,7 @@ cvar_t *com_timedemo; cvar_t *com_sv_running; cvar_t *com_cl_running; cvar_t *com_logfile; // 1 = buffer log, 2 = flush after each print +cvar_t *com_pipefile; cvar_t *com_showtrace; cvar_t *com_version; cvar_t *com_blood; @@ -2768,9 +2770,36 @@ void Com_Init( char *commandLine ) { Com_Printf ("Altivec support is %s\n", com_altivec->integer ? "enabled" : "disabled"); #endif + com_pipefile = Cvar_Get( "com_pipefile", "", CVAR_ARCHIVE|CVAR_LATCH ); + if( com_pipefile->string[0] ) + { + pipefile = FS_FCreateOpenPipeFile( com_pipefile->string ); + } + Com_Printf ("--- Common Initialization Complete ---\n"); } +/* +=============== +Com_ReadFromPipe + +Read whatever is in com_pipefile, if anything, and execute it +=============== +*/ +void Com_ReadFromPipe( void ) +{ + char buffer[MAX_STRING_CHARS] = {""}; + qboolean read; + + if( !pipefile ) + return; + + read = FS_Read( buffer, sizeof( buffer ), pipefile ); + if( read ) + Cbuf_ExecuteText( EXEC_APPEND, buffer ); +} + + //================================================================== void Com_WriteConfigToFile( const char *filename ) { @@ -3097,6 +3126,8 @@ void Com_Frame( void ) { c_pointcontents = 0; } + Com_ReadFromPipe( ); + com_frameNumber++; } @@ -3116,6 +3147,11 @@ void Com_Shutdown (void) { com_journalFile = 0; } + if( pipefile ) { + FS_FCloseFile( pipefile ); + FS_HomeRemove( com_pipefile->string ); + } + } //------------------------------------------------------------------------ diff --git a/reaction/code/qcommon/files.c b/reaction/code/qcommon/files.c index e362f2da..2f2120b3 100644 --- a/reaction/code/qcommon/files.c +++ b/reaction/code/qcommon/files.c @@ -905,6 +905,50 @@ fileHandle_t FS_FOpenFileAppend( const char *filename ) { return f; } +/* +=========== +FS_FCreateOpenPipeFile + +=========== +*/ +fileHandle_t FS_FCreateOpenPipeFile( const char *filename ) { + char *ospath; + FILE *fifo; + fileHandle_t f; + + if ( !fs_searchpaths ) { + Com_Error( ERR_FATAL, "Filesystem call made without initialization\n" ); + } + + f = FS_HandleForFile(); + fsh[f].zipFile = qfalse; + + Q_strncpyz( fsh[f].name, filename, sizeof( fsh[f].name ) ); + + // don't let sound stutter + S_ClearSoundBuffer(); + + ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename ); + + if ( fs_debug->integer ) { + Com_Printf( "FS_FCreateOpenPipeFile: %s\n", ospath ); + } + + FS_CheckFilenameIsNotExecutable( ospath, __func__ ); + + fifo = Sys_Mkfifo( ospath ); + if( fifo ) { + fsh[f].handleFiles.file.o = fifo; + fsh[f].handleSync = qfalse; + } + else + { + f = 0; + } + + return f; +} + /* =========== FS_FilenameCompare diff --git a/reaction/code/qcommon/qcommon.h b/reaction/code/qcommon/qcommon.h index 46c14387..1e4da5d2 100644 --- a/reaction/code/qcommon/qcommon.h +++ b/reaction/code/qcommon/qcommon.h @@ -626,6 +626,7 @@ int FS_GetModList( char *listbuf, int bufsize ); fileHandle_t FS_FOpenFileWrite( const char *qpath ); fileHandle_t FS_FOpenFileAppend( const char *filename ); +fileHandle_t FS_FCreateOpenPipeFile( const char *filename ); // will properly create any needed paths and deal with seperater character issues fileHandle_t FS_SV_FOpenFileWrite( const char *filename ); @@ -1094,6 +1095,7 @@ qboolean Sys_IsLANAddress (netadr_t adr); void Sys_ShowIP(void); qboolean Sys_Mkdir( const char *path ); +FILE *Sys_Mkfifo( const char *ospath ); char *Sys_Cwd( void ); void Sys_SetDefaultInstallPath(const char *path); char *Sys_DefaultInstallPath(void); diff --git a/reaction/code/sys/sys_unix.c b/reaction/code/sys/sys_unix.c index 199715a2..ff77e8a1 100644 --- a/reaction/code/sys/sys_unix.c +++ b/reaction/code/sys/sys_unix.c @@ -247,6 +247,31 @@ qboolean Sys_Mkdir( const char *path ) return qtrue; } +/* +================== +Sys_Mkfifo +================== +*/ +FILE *Sys_Mkfifo( const char *ospath ) +{ + FILE *fifo; + int result; + int fn; + + result = mkfifo( ospath, 0600 ); + if( result != 0 ) + return NULL; + + fifo = fopen( ospath, "w+" ); + if( fifo ) + { + fn = fileno( fifo ); + fcntl( fn, F_SETFL, O_NONBLOCK ); + } + + return fifo; +} + /* ================== Sys_Cwd diff --git a/reaction/code/sys/sys_win32.c b/reaction/code/sys/sys_win32.c index ef3b03a4..0d213409 100644 --- a/reaction/code/sys/sys_win32.c +++ b/reaction/code/sys/sys_win32.c @@ -320,6 +320,17 @@ qboolean Sys_Mkdir( const char *path ) return qtrue; } +/* +================== +Sys_Mkfifo +Noop on windows because named pipes do not function the same way +================== +*/ +FILE *Sys_Mkfifo( const char *ospath ) +{ + return NULL; +} + /* ============== Sys_Cwd