-rw-r--r-- | library/global.cpp | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/library/global.cpp b/library/global.cpp index d6ba84f..68a3a75 100644 --- a/library/global.cpp +++ b/library/global.cpp @@ -44,2 +44,3 @@ #include <unistd.h> +#include <errno.h> @@ -605,14 +606,56 @@ void Global::invoke(const QString &c) #endif - { - if ( !::vfork() ) { - for ( int fd = 3; fd < 100; fd++ ) - ::close( fd ); - ::setpgid( ::getpid(), ::getppid() ); - // Try bindir first, so that foo/bar works too - ::execv( qpeDir()+"/bin/"+args[0], (char * const *)args ); - ::execvp( args[0], (char * const *)args ); - _exit( -1 ); - } + { + bool success = false; + int pfd [2]; + if ( ::pipe ( pfd ) < 0 ) + pfd [0] = pfd [1] = -1; + + pid_t pid = ::fork ( ); + + if ( pid == 0 ) { // child + for ( int fd = 3; fd < 100; fd++ ) { + if ( fd != pfd [1] ) + ::close ( fd ); + } + ::setpgid ( ::getpid ( ), ::getppid ( )); + + // Closing of fd[1] indicates that the execvp succeeded! + if ( pfd [1] >= 0 ) + ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); + + // Try bindir first, so that foo/bar works too + ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); + ::execvp ( args [0], (char * const *) args ); + + char resultByte = 1; + if ( pfd [1] >= 0 ) + ::write ( pfd [1], &resultByte, 1 ); + ::_exit ( -1 ); + } + else if ( pid > 0 ) { + success = true; + + if ( pfd [1] >= 0 ) + ::close ( pfd [1] ); + if ( pfd [0] >= 0 ) { + while ( true ) { + char resultByte; + int n = ::read ( pfd [0], &resultByte, 1 ); + if ( n == 1 ) { + success = false; + break; + } + if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) + continue; + + break; // success + } + ::close ( pfd [0] ); + } + } + if ( success ) + StartingAppList::add( list[0] ); + else + QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); } - StartingAppList::add( list[0] ); #endif //QT_NO_QWS_MULTIPROCESS |