[quake3-commits] r2097 - trunk/code/sys

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Jul 24 18:01:51 EDT 2011


Author: tma
Date: 2011-07-24 18:01:50 -0400 (Sun, 24 Jul 2011)
New Revision: 2097

Modified:
   trunk/code/sys/sys_unix.c
Log:
* Replace usage of system with fork/exec

Modified: trunk/code/sys/sys_unix.c
===================================================================
--- trunk/code/sys/sys_unix.c	2011-07-22 16:43:27 UTC (rev 2096)
+++ trunk/code/sys/sys_unix.c	2011-07-24 22:01:50 UTC (rev 2097)
@@ -37,6 +37,7 @@
 #include <libgen.h>
 #include <fcntl.h>
 #include <fenv.h>
+#include <sys/wait.h>
 
 qboolean stdinIsATTY;
 
@@ -550,28 +551,106 @@
 }
 
 #ifndef MACOS_X
+static char execBuffer[ 1024 ];
+static char *execBufferPointer;
+static char *execArgv[ 16 ];
+static int execArgc;
+
 /*
 ==============
+Sys_ClearExecBuffer
+==============
+*/
+static void Sys_ClearExecBuffer( void )
+{
+	execBufferPointer = execBuffer;
+	Com_Memset( execArgv, 0, sizeof( execArgv ) );
+	execArgc = 0;
+}
+
+/*
+==============
+Sys_AppendToExecBuffer
+==============
+*/
+static void Sys_AppendToExecBuffer( const char *text )
+{
+	size_t size = sizeof( execBuffer ) - ( execBufferPointer - execBuffer );
+	int length = strlen( text ) + 1;
+
+	if( length > size || execArgc >= ARRAY_LEN( execArgv ) )
+		return;
+
+	Q_strncpyz( execBufferPointer, text, size );
+	execArgv[ execArgc++ ] = execBufferPointer;
+
+	execBufferPointer += length;
+}
+
+/*
+==============
+Sys_Exec
+==============
+*/
+static int Sys_Exec( void )
+{
+	pid_t pid = fork( );
+
+	if( pid < 0 )
+		return -1;
+
+	if( pid )
+	{
+		// Parent
+		int exitCode;
+
+		wait( &exitCode );
+
+		return WEXITSTATUS( exitCode );
+	}
+	else
+	{
+		// Child
+		execvp( execArgv[ 0 ], execArgv );
+
+		// Failed to execute
+		exit( -1 );
+
+		return -1;
+	}
+}
+
+/*
+==============
 Sys_ZenityCommand
 ==============
 */
-static void Sys_ZenityCommand( dialogType_t type, const char *message, const char *title,
-		char *command, size_t commandSize )
+static void Sys_ZenityCommand( dialogType_t type, const char *message, const char *title )
 {
-	const char *options = "";
+	Sys_ClearExecBuffer( );
+	Sys_AppendToExecBuffer( "zenity" );
 
 	switch( type )
 	{
 		default:
-		case DT_INFO:      options = "--info"; break;
-		case DT_WARNING:   options = "--warning"; break;
-		case DT_ERROR:     options = "--error"; break;
-		case DT_YES_NO:    options = "--question --ok-label=\"Yes\" --cancel-label=\"No\""; break;
-		case DT_OK_CANCEL: options = "--question --ok-label=\"OK\" --cancel-label=\"Cancel\""; break;
+		case DT_INFO:      Sys_AppendToExecBuffer( "--info" ); break;
+		case DT_WARNING:   Sys_AppendToExecBuffer( "--warning" ); break;
+		case DT_ERROR:     Sys_AppendToExecBuffer( "--error" ); break;
+		case DT_YES_NO:
+			Sys_AppendToExecBuffer( "--question" );
+			Sys_AppendToExecBuffer( "--ok-label=Yes" );
+			Sys_AppendToExecBuffer( "--cancel-label=No" );
+			break;
+
+		case DT_OK_CANCEL:
+			Sys_AppendToExecBuffer( "--question" );
+			Sys_AppendToExecBuffer( "--ok-label=OK" );
+			Sys_AppendToExecBuffer( "--cancel-label=Cancel" );
+			break;
 	}
 
-	Com_sprintf( command, commandSize, "zenity %s --text=\"%s\" --title=\"%s\" >/dev/null 2>/dev/null",
-		options, message, title );
+	Sys_AppendToExecBuffer( va( "--text=%s", message ) );
+	Sys_AppendToExecBuffer( va( "--title=%s", title ) );
 }
 
 /*
@@ -579,23 +658,23 @@
 Sys_KdialogCommand
 ==============
 */
-static void Sys_KdialogCommand( dialogType_t type, const char *message, const char *title,
-		char *command, size_t commandSize )
+static void Sys_KdialogCommand( dialogType_t type, const char *message, const char *title )
 {
-	const char *options = "";
+	Sys_ClearExecBuffer( );
+	Sys_AppendToExecBuffer( "kdialog" );
 
 	switch( type )
 	{
 		default:
-		case DT_INFO:      options = "--msgbox"; break;
-		case DT_WARNING:   options = "--sorry"; break;
-		case DT_ERROR:     options = "--error"; break;
-		case DT_YES_NO:    options = "--warningyesno"; break;
-		case DT_OK_CANCEL: options = "--warningcontinuecancel"; break;
+		case DT_INFO:      Sys_AppendToExecBuffer( "--msgbox" ); break;
+		case DT_WARNING:   Sys_AppendToExecBuffer( "--sorry" ); break;
+		case DT_ERROR:     Sys_AppendToExecBuffer( "--error" ); break;
+		case DT_YES_NO:    Sys_AppendToExecBuffer( "--warningyesno" ); break;
+		case DT_OK_CANCEL: Sys_AppendToExecBuffer( "--warningcontinuecancel" ); break;
 	}
 
-	Com_sprintf( command, commandSize, "kdialog %s \"%s\" --title \"%s\" >/dev/null 2>/dev/null",
-		options, message, title );
+	Sys_AppendToExecBuffer( message );
+	Sys_AppendToExecBuffer( va( "--title=%s", title ) );
 }
 
 /*
@@ -603,20 +682,21 @@
 Sys_XmessageCommand
 ==============
 */
-static void Sys_XmessageCommand( dialogType_t type, const char *message, const char *title,
-		char *command, size_t commandSize )
+static void Sys_XmessageCommand( dialogType_t type, const char *message, const char *title )
 {
-	const char *options = "";
+	Sys_ClearExecBuffer( );
+	Sys_AppendToExecBuffer( "xmessage" );
+	Sys_AppendToExecBuffer( "-buttons" );
 
 	switch( type )
 	{
-		default:           options = "-buttons OK:0"; break;
-		case DT_YES_NO:    options = "-buttons Yes:0,No:1"; break;
-		case DT_OK_CANCEL: options = "-buttons OK:0,Cancel:1"; break;
+		default:           Sys_AppendToExecBuffer( "OK:0" ); break;
+		case DT_YES_NO:    Sys_AppendToExecBuffer( "Yes:0,No:1" ); break;
+		case DT_OK_CANCEL: Sys_AppendToExecBuffer( "OK:0,Cancel:1" ); break;
 	}
 
-	Com_sprintf( command, commandSize, "xmessage -center %s \"%s\" >/dev/null 2>/dev/null",
-		options, message );
+	Sys_AppendToExecBuffer( "-center" );
+	Sys_AppendToExecBuffer( message );
 }
 
 /*
@@ -636,7 +716,7 @@
 		XMESSAGE,
 		NUM_DIALOG_PROGRAMS
 	} dialogCommandType_t;
-	typedef void (*dialogCommandBuilder_t)( dialogType_t, const char *, const char *, char *, size_t );
+	typedef void (*dialogCommandBuilder_t)( dialogType_t, const char *, const char * );
 
 	const char              *session = getenv( "DESKTOP_SESSION" );
 	qboolean                tried[ NUM_DIALOG_PROGRAMS ] = { qfalse };
@@ -665,21 +745,16 @@
 			if( !tried[ i ] )
 			{
 				int exitCode;
-				int childSignal;
-				int childCode;
-				char command[ 1024 ];
 
-				commands[ i ]( type, message, title, command, sizeof( command ) );
-				exitCode = system( command );
-				childSignal = exitCode & 127;
-				childCode = exitCode >> 8;
+				commands[ i ]( type, message, title );
+				exitCode = Sys_Exec( );
 
-				if( exitCode != -1 && childSignal == 0 && childCode != 126 && childCode != 127 )
+				if( exitCode >= 0 )
 				{
 					switch( type )
 					{
-						case DT_YES_NO:    return childCode ? DR_NO : DR_YES;
-						case DT_OK_CANCEL: return childCode ? DR_CANCEL : DR_OK;
+						case DT_YES_NO:    return exitCode ? DR_NO : DR_YES;
+						case DT_OK_CANCEL: return exitCode ? DR_CANCEL : DR_OK;
 						default:           return DR_OK;
 					}
 				}



More information about the quake3-commits mailing list