mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2025-01-10 12:01:10 +00:00
Poor-man's BSP monitoring on UNIX: capture stdout and stderr for legacy BSP tools, and append to the Radiant console.
This commit is contained in:
parent
10569d4e0c
commit
9760c8c243
2 changed files with 72 additions and 11 deletions
|
@ -31,6 +31,7 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
@ -932,9 +933,6 @@ void QE_ExpandBspString( char *bspaction, GPtrArray *out_array, char *mapname ){
|
||||||
strcpy( src, mapname );
|
strcpy( src, mapname );
|
||||||
strlwr( src );
|
strlwr( src );
|
||||||
in = strstr( src, "maps/" );
|
in = strstr( src, "maps/" );
|
||||||
if ( !in ) {
|
|
||||||
in = strstr( src, "maps/" );
|
|
||||||
}
|
|
||||||
if ( in ) {
|
if ( in ) {
|
||||||
in += 5;
|
in += 5;
|
||||||
strcpy( base, in );
|
strcpy( base, in );
|
||||||
|
@ -1056,6 +1054,58 @@ void SaveWithRegion( char *name ){
|
||||||
Map_SaveFile( name, region_active );
|
Map_SaveFile( name, region_active );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
int pipes[2];
|
||||||
|
} bsp_child_process_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief A gtk_idle monitor for redirecting stdout and stderr of the BSP
|
||||||
|
* compiler process to the Radiant console. This is used on UNIX platforms for
|
||||||
|
* older BSP tools that do not support the XML-based network monitoring found
|
||||||
|
* in watchbsp.cpp and feedback.cpp.
|
||||||
|
*/
|
||||||
|
static gboolean RunBsp_CaptureOutput(void *data) {
|
||||||
|
bsp_child_process_t *process = (bsp_child_process_t *) data;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
// if waitpid returns 0, the child process is alive
|
||||||
|
if ( ( pid = waitpid( process->pid, &process->status, WNOHANG ) ) == 0 ) {
|
||||||
|
char text[1024];
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
if ( (len = read( process->pipes[0], text, sizeof( text ) ) ) > 0 ) {
|
||||||
|
GtkTextView *view = GTK_TEXT_VIEW( g_qeglobals_gui.d_edit );
|
||||||
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer( view );
|
||||||
|
|
||||||
|
if ( buffer ) {
|
||||||
|
GtkTextIter iter;
|
||||||
|
gtk_text_buffer_get_end_iter( buffer, &iter );
|
||||||
|
gtk_text_buffer_insert( buffer, &iter, text, len );
|
||||||
|
|
||||||
|
gtk_text_buffer_get_end_iter( buffer, &iter );
|
||||||
|
gtk_text_view_scroll_to_iter( view, &iter , 0.0, false, 0.0, 0.0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // retain the gtk_idle monitor
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pid == -1 ) {
|
||||||
|
Sys_Printf( "Failed to wait for %d: %s\n", process->pid, strerror( errno ) );
|
||||||
|
} else {
|
||||||
|
Sys_Printf( "Process %d terminated with status %d\n", process->pid, process->status );
|
||||||
|
}
|
||||||
|
|
||||||
|
close( process->pipes[0] );
|
||||||
|
close( process->pipes[1] );
|
||||||
|
|
||||||
|
free( process);
|
||||||
|
|
||||||
|
return false; // cancel the gtk_idle monitor
|
||||||
|
}
|
||||||
|
|
||||||
void RunBsp( char *command ){
|
void RunBsp( char *command ){
|
||||||
GPtrArray *sys;
|
GPtrArray *sys;
|
||||||
char batpath[BIG_PATH_MAX]; //% PATH_MAX
|
char batpath[BIG_PATH_MAX]; //% PATH_MAX
|
||||||
|
@ -1124,7 +1174,6 @@ void RunBsp( char *command ){
|
||||||
// write qe3bsp.sh
|
// write qe3bsp.sh
|
||||||
sprintf( batpath, "%sqe3bsp.sh", temppath );
|
sprintf( batpath, "%sqe3bsp.sh", temppath );
|
||||||
Sys_Printf( "Writing the compile script to '%s'\n", batpath );
|
Sys_Printf( "Writing the compile script to '%s'\n", batpath );
|
||||||
Sys_Printf( "The build output will be saved in '%sjunk.txt'\n", temppath );
|
|
||||||
hFile = fopen( batpath, "w" );
|
hFile = fopen( batpath, "w" );
|
||||||
if ( !hFile ) {
|
if ( !hFile ) {
|
||||||
Error( "Can't write to %s", batpath );
|
Error( "Can't write to %s", batpath );
|
||||||
|
@ -1150,21 +1199,33 @@ void RunBsp( char *command ){
|
||||||
Pointfile_Delete();
|
Pointfile_Delete();
|
||||||
|
|
||||||
#if defined ( __linux__ ) || defined ( __APPLE__ )
|
#if defined ( __linux__ ) || defined ( __APPLE__ )
|
||||||
|
bsp_child_process_t *process = ( bsp_child_process_t *) malloc( sizeof( bsp_child_process_t ) );
|
||||||
|
memset( process, 0, sizeof( *process ) );
|
||||||
|
|
||||||
pid_t pid;
|
pipe( process->pipes );
|
||||||
|
|
||||||
pid = fork();
|
fcntl( process->pipes[0], F_SETFL, O_NONBLOCK );
|
||||||
switch ( pid )
|
fcntl( process->pipes[1], F_SETFL, O_NONBLOCK );
|
||||||
|
|
||||||
|
process->pid = fork();
|
||||||
|
switch ( process->pid )
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
Error( "CreateProcess failed" );
|
Error( "CreateProcess failed" );
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
execlp( batpath, batpath, (char *) NULL );
|
close( process->pipes[0] ); // close reading end in the child
|
||||||
printf( "execlp error !" );
|
|
||||||
_exit( 0 );
|
dup2( process->pipes[1], 1 ); // send stdout to the pipe
|
||||||
|
dup2( process->pipes[1], 2 ); // send stderr to the pipe
|
||||||
|
|
||||||
|
execlp( batpath, batpath, (char *) NULL ); // execute the script
|
||||||
|
|
||||||
|
fprintf( stderr, "Failed to execute %s: %s", batpath, strerror( errno ) );
|
||||||
|
_exit( 1 );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
g_idle_add( RunBsp_CaptureOutput, (void *) process );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1772,7 +1772,7 @@ extern "C" void Sys_FPrintf_VA( int level, const char *text, va_list args ) {
|
||||||
|
|
||||||
gtk_text_view_scroll_mark_onscreen( GTK_TEXT_VIEW( g_qeglobals_gui.d_edit ), end );
|
gtk_text_view_scroll_mark_onscreen( GTK_TEXT_VIEW( g_qeglobals_gui.d_edit ), end );
|
||||||
|
|
||||||
// update console widget immediatly if we're doing something time-consuming
|
// update console widget immediately if we're doing something time-consuming
|
||||||
if ( !g_bScreenUpdates && GTK_WIDGET_REALIZED( g_qeglobals_gui.d_edit ) ) {
|
if ( !g_bScreenUpdates && GTK_WIDGET_REALIZED( g_qeglobals_gui.d_edit ) ) {
|
||||||
gtk_grab_add( g_qeglobals_gui.d_edit );
|
gtk_grab_add( g_qeglobals_gui.d_edit );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue