-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 @@ -21,48 +21,49 @@ #include <qpe/qpedebug.h> #include <qpe/global.h> #include <qpe/qdawg.h> #include <qpe/qpeapplication.h> #include <qpe/resource.h> #include <qpe/storage.h> #include <qpe/applnk.h> #include <qpe/qcopenvelope_qws.h> #include <qfile.h> #include <qlabel.h> #include <qtimer.h> #include <qmap.h> #include <qdict.h> #include <qdir.h> #include <qmessagebox.h> #include <qregexp.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> +#include <errno.h> #include <qwindowsystem_qws.h> // for qwsServer #include <qdatetime.h> #include <qfile.h> namespace { // checks if the storage should be searched bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke QFile file(path ); if(!file.open(IO_ReadOnly ) ) return true; QByteArray array = file.readAll(); QStringList list = QStringList::split('\n', QString( array ) ); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it ){ if( (*it).startsWith("autocheck = 0" ) ){ return false; }else if( (*it).startsWith("autocheck = 1" ) ){ return true; } } return true; } @@ -582,60 +583,102 @@ void Global::invoke(const QString &c) QStrList slist; unsigned int j; for ( j = 0; j < list.count(); j++ ) slist.append( list[j].utf8() ); const char **args = new (const char *)[slist.count() + 1]; for ( j = 0; j < slist.count(); j++ ) args[j] = slist.at(j); args[j] = NULL; #if !defined(QT_NO_COP) // an attempt to show a wait... // more logic should be used, but this will be fine for the moment... QCopEnvelope ( "QPE/System", "busy()" ); #endif #ifdef HAVE_QUICKEXEC QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; qDebug("libfile = %s", libexe.latin1() ); if ( QFile::exists( libexe ) ) { qDebug("calling quickexec %s", libexe.latin1() ); quickexecv( libexe.utf8().data(), (const char **)args ); } else #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 } /*! Executes the application identfied by \a c, passing \a document if it isn't null. Note that a better approach might be to send a QCop message to the application's QPE/Application/\e{appname} channel. */ void Global::execute( const QString &c, const QString& document ) { if ( qApp->type() != QApplication::GuiServer ) { // ask the server to do the work #if !defined(QT_NO_COP) if ( document.isNull() ) { QCopEnvelope e( "QPE/System", "execute(QString)" ); e << c; } else { QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); e << c << document; } #endif |