summaryrefslogtreecommitdiff
authorsandman <sandman>2002-12-17 00:29:22 (UTC)
committer sandman <sandman>2002-12-17 00:29:22 (UTC)
commit2d39ff65b27c1a680a56c1b70b534e3cb767e08f (patch) (unidiff)
tree09e5cc3f7157681fe51fe83bb54ebbaa548d8c64
parent70090722d240bed8c390281e072c9bcfc5ba7782 (diff)
downloadopie-2d39ff65b27c1a680a56c1b70b534e3cb767e08f.zip
opie-2d39ff65b27c1a680a56c1b70b534e3cb767e08f.tar.gz
opie-2d39ff65b27c1a680a56c1b70b534e3cb767e08f.tar.bz2
replaced the simple fork and execv method of starting applications with a
more sophisticated method (mostly taken from K/OProcess, because we can't use libopie in libqpe). We can detect now, if apps can not be started.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/global.cpp65
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
@@ -33,24 +33,25 @@
33#include <qmap.h> 33#include <qmap.h>
34#include <qdict.h> 34#include <qdict.h>
35#include <qdir.h> 35#include <qdir.h>
36#include <qmessagebox.h> 36#include <qmessagebox.h>
37#include <qregexp.h> 37#include <qregexp.h>
38 38
39#include <stdlib.h> 39#include <stdlib.h>
40#include <sys/stat.h> 40#include <sys/stat.h>
41#include <sys/wait.h> 41#include <sys/wait.h>
42#include <sys/types.h> 42#include <sys/types.h>
43#include <fcntl.h> 43#include <fcntl.h>
44#include <unistd.h> 44#include <unistd.h>
45#include <errno.h>
45 46
46#include <qwindowsystem_qws.h> // for qwsServer 47#include <qwindowsystem_qws.h> // for qwsServer
47#include <qdatetime.h> 48#include <qdatetime.h>
48 49
49#include <qfile.h> 50#include <qfile.h>
50 51
51namespace { 52namespace {
52 // checks if the storage should be searched 53 // checks if the storage should be searched
53 bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke 54 bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke
54 QFile file(path ); 55 QFile file(path );
55 if(!file.open(IO_ReadOnly ) ) 56 if(!file.open(IO_ReadOnly ) )
56 return true; 57 return true;
@@ -594,36 +595,78 @@ void Global::invoke(const QString &c)
594 // more logic should be used, but this will be fine for the moment... 595 // more logic should be used, but this will be fine for the moment...
595 QCopEnvelope ( "QPE/System", "busy()" ); 596 QCopEnvelope ( "QPE/System", "busy()" );
596#endif 597#endif
597 598
598#ifdef HAVE_QUICKEXEC 599#ifdef HAVE_QUICKEXEC
599 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; 600 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so";
600 qDebug("libfile = %s", libexe.latin1() ); 601 qDebug("libfile = %s", libexe.latin1() );
601 if ( QFile::exists( libexe ) ) { 602 if ( QFile::exists( libexe ) ) {
602 qDebug("calling quickexec %s", libexe.latin1() ); 603 qDebug("calling quickexec %s", libexe.latin1() );
603 quickexecv( libexe.utf8().data(), (const char **)args ); 604 quickexecv( libexe.utf8().data(), (const char **)args );
604 } else 605 } else
605#endif 606#endif
606 { 607 {
607 if ( !::vfork() ) { 608 bool success = false;
608 for ( int fd = 3; fd < 100; fd++ ) 609 int pfd [2];
609 ::close( fd ); 610 if ( ::pipe ( pfd ) < 0 )
610 ::setpgid( ::getpid(), ::getppid() ); 611 pfd [0] = pfd [1] = -1;
611 // Try bindir first, so that foo/bar works too 612
612 ::execv( qpeDir()+"/bin/"+args[0], (char * const *)args ); 613 pid_t pid = ::fork ( );
613 ::execvp( args[0], (char * const *)args ); 614
614 _exit( -1 ); 615 if ( pid == 0 ) { // child
615 } 616 for ( int fd = 3; fd < 100; fd++ ) {
617 if ( fd != pfd [1] )
618 ::close ( fd );
619 }
620 ::setpgid ( ::getpid ( ), ::getppid ( ));
621
622 // Closing of fd[1] indicates that the execvp succeeded!
623 if ( pfd [1] >= 0 )
624 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC );
625
626 // Try bindir first, so that foo/bar works too
627 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args );
628 ::execvp ( args [0], (char * const *) args );
629
630 char resultByte = 1;
631 if ( pfd [1] >= 0 )
632 ::write ( pfd [1], &resultByte, 1 );
633 ::_exit ( -1 );
634 }
635 else if ( pid > 0 ) {
636 success = true;
637
638 if ( pfd [1] >= 0 )
639 ::close ( pfd [1] );
640 if ( pfd [0] >= 0 ) {
641 while ( true ) {
642 char resultByte;
643 int n = ::read ( pfd [0], &resultByte, 1 );
644 if ( n == 1 ) {
645 success = false;
646 break;
647 }
648 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR )))
649 continue;
650
651 break; // success
652 }
653 ::close ( pfd [0] );
654 }
655 }
656 if ( success )
657 StartingAppList::add( list[0] );
658 else
659 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
616 } 660 }
617 StartingAppList::add( list[0] );
618#endif //QT_NO_QWS_MULTIPROCESS 661#endif //QT_NO_QWS_MULTIPROCESS
619} 662}
620 663
621 664
622/*! 665/*!
623 Executes the application identfied by \a c, passing \a 666 Executes the application identfied by \a c, passing \a
624 document if it isn't null. 667 document if it isn't null.
625 668
626 Note that a better approach might be to send a QCop message to the 669 Note that a better approach might be to send a QCop message to the
627 application's QPE/Application/\e{appname} channel. 670 application's QPE/Application/\e{appname} channel.
628*/ 671*/
629void Global::execute( const QString &c, const QString& document ) 672void Global::execute( const QString &c, const QString& document )