summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--library/global.cpp49
1 files changed, 46 insertions, 3 deletions
diff --git a/library/global.cpp b/library/global.cpp
index d6ba84f..68a3a75 100644
--- a/library/global.cpp
+++ b/library/global.cpp
@@ -42,6 +42,7 @@
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
+#include <errno.h>
#include <qwindowsystem_qws.h> // for qwsServer
#include <qdatetime.h>
@@ -604,17 +605,59 @@ void Global::invoke(const QString &c)
} else
#endif
{
- if ( !::vfork() ) {
- for ( int fd = 3; fd < 100; fd++ )
+ 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 );
- _exit( -1 );
+
+ 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 );
+ }
#endif //QT_NO_QWS_MULTIPROCESS
}