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) (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
@@ -39,12 +39,13 @@
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
@@ -601,23 +602,65 @@ void Global::invoke(const QString &c)
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];
610 if ( ::pipe ( pfd ) < 0 )
611 pfd [0] = pfd [1] = -1;
612
613 pid_t pid = ::fork ( );
614
615 if ( pid == 0 ) { // child
616 for ( int fd = 3; fd < 100; fd++ ) {
617 if ( fd != pfd [1] )
609 ::close( fd ); 618 ::close( fd );
619 }
610 ::setpgid( ::getpid(), ::getppid() ); 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
611 // Try bindir first, so that foo/bar works too 626 // Try bindir first, so that foo/bar works too
612 ::execv( qpeDir()+"/bin/"+args[0], (char * const *)args ); 627 ::execv( qpeDir()+"/bin/"+args[0], (char * const *)args );
613 ::execvp( args[0], (char * const *)args ); 628 ::execvp( args[0], (char * const *)args );
614 _exit( -1 ); 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] );
615 } 654 }
616 } 655 }
656 if ( success )
617 StartingAppList::add( list[0] ); 657 StartingAppList::add( list[0] );
658 else
659 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
660 }
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