-rw-r--r-- | core/launcher/applauncher.cpp | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/core/launcher/applauncher.cpp b/core/launcher/applauncher.cpp index 50c1b71..d6f93da 100644 --- a/core/launcher/applauncher.cpp +++ b/core/launcher/applauncher.cpp @@ -22,17 +22,17 @@ #define QTOPIA_INTERNAL_PRELOADACCESS #endif #ifndef QTOPIA_INTERNAL_FILEOPERATIONS #define QTOPIA_INTERNAL_FILEOPERATIONS #endif #ifndef QTOPIA_PROGRAM_MONITOR #define QTOPIA_PROGRAM_MONITOR #endif -#include <qtopia/qpeglobal.h> +#include <qtopia/global.h> #ifndef Q_OS_WIN32 #include <sys/stat.h> #include <sys/wait.h> #include <sys/file.h> #include <unistd.h> #include <sys/time.h> #include <sys/resource.h> @@ -56,31 +56,32 @@ #include <qtopia/qcopenvelope_qws.h> #include <qtopia/applnk.h> #include <qtopia/qpeapplication.h> #include <qtopia/config.h> #include <qtopia/global.h> #include "applauncher.h" #include "documentlist.h" +#include "launcherglobal.h" const int AppLauncher::RAISE_TIMEOUT_MS = 5000; //--------------------------------------------------------------------------- static AppLauncher* appLauncherPtr; const int appStopEventID = 1290; class AppStoppedEvent : public QCustomEvent { public: AppStoppedEvent(int pid, int status) : QCustomEvent( appStopEventID ), mPid(pid), mStatus(status) { } - + int pid() { return mPid; } int status() { return mStatus; } private: int mPid, mStatus; }; AppLauncher::AppLauncher(QObject *parent, const char *name) @@ -91,28 +92,28 @@ AppLauncher::AppLauncher(QObject *parent, const char *name) connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&))); QCopChannel* channel = new QCopChannel( "QPE/System", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(received(const QCString&, const QByteArray&)) ); channel = new QCopChannel( "QPE/Server", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(received(const QCString&, const QByteArray&)) ); - + #ifndef Q_OS_WIN32 signal(SIGCHLD, signalHandler); #else runningAppsProc.setAutoDelete( TRUE ); #endif QString tmp = qApp->argv()[0]; int pos = tmp.findRev('/'); if ( pos > -1 ) tmp = tmp.mid(++pos); runningApps[::getpid()] = tmp; - + appLauncherPtr = this; QTimer::singleShot( 1000, this, SLOT(createQuickLauncher()) ); } AppLauncher::~AppLauncher() { appLauncherPtr = 0; @@ -123,17 +124,17 @@ AppLauncher::~AppLauncher() int status; ::kill( qlPid, SIGTERM ); waitpid( qlPid, &status, 0 ); } } /* We use the QCopChannel of the app as an indicator of when it has been launched so that we can disable the busy indicators */ -void AppLauncher::newQcopChannel(const QString& channelName) +void AppLauncher::newQcopChannel(const QString& channelName) { // qDebug("channel %s added", channelName.data() ); QString prefix("QPE/Application/"); if (channelName.startsWith(prefix)) { { QCopEnvelope e("QPE/System", "newChannel(QString)"); e << channelName; } @@ -146,17 +147,17 @@ void AppLauncher::newQcopChannel(const QString& channelName) } else if (channelName.startsWith("QPE/QuickLauncher-")) { qDebug("Registered %s", channelName.latin1()); int pid = channelName.mid(18).toInt(); if (pid == qlPid) qlReady = TRUE; } } -void AppLauncher::removedQcopChannel(const QString& channelName) +void AppLauncher::removedQcopChannel(const QString& channelName) { if (channelName.startsWith("QPE/Application/")) { QCopEnvelope e("QPE/System", "removedChannel(QString)"); e << channelName; } } void AppLauncher::received(const QCString& msg, const QByteArray& data) @@ -254,17 +255,17 @@ void AppLauncher::signalHandler(int) bool AppLauncher::event(QEvent *e) { if ( e->type() == appStopEventID ) { AppStoppedEvent *ae = (AppStoppedEvent *) e; sigStopped(ae->pid(), ae->status() ); return TRUE; } - + return QObject::event(e); } void AppLauncher::timerEvent( QTimerEvent *e ) { int id = e->timerId(); QMap<QString,int>::Iterator it; for ( it = waitingHeartbeat.begin(); it != waitingHeartbeat.end(); ++it ) { @@ -277,41 +278,41 @@ void AppLauncher::timerEvent( QTimerEvent *e ) waitingHeartbeat.remove( it ); // qDebug("Checking in on %s", appKillerName.latin1()); // We store this incase the application responds while we're // waiting for user input so we know not to delete ourselves. appKillerBox = new QMessageBox(tr("Application Problem"), tr("<p>%1 is not responding.</p>").arg(appKillerName) + - tr("<p>Would you like to force the application to exit?</p>"), - QMessageBox::Warning, QMessageBox::Yes, - QMessageBox::No | QMessageBox::Default, + tr("<p>Would you like to force the application to exit?</p>"), + QMessageBox::Warning, QMessageBox::Yes, + QMessageBox::No | QMessageBox::Default, QMessageBox::NoButton); - if (appKillerBox->exec() == QMessageBox::Yes) { + if (appKillerBox->exec() == QMessageBox::Yes) { // qDebug("Killing the app!!! Bwuhahahaha!"); int pid = pidForName(appKillerName); if ( pid > 0 ) kill( pid ); } appKillerName = QString::null; delete appKillerBox; appKillerBox = 0; return; } } QObject::timerEvent( e ); } -#ifndef Q_OS_WIN32 +#ifndef Q_OS_WIN32 void AppLauncher::sigStopped(int sigPid, int sigStatus) { int exitStatus = 0; - + bool crashed = WIFSIGNALED(sigStatus); if ( !crashed ) { if ( WIFEXITED(sigStatus) ) exitStatus = WEXITSTATUS(sigStatus); } else { exitStatus = WTERMSIG(sigStatus); } @@ -359,22 +360,22 @@ void AppLauncher::sigStopped(int sigPid, int sigStatus) cfg.setGroup("Preload"); QStringList apps = cfg.readListEntry("Apps",','); QString exe = app->exec(); apps.remove(exe); cfg.writeEntry("Apps",apps,','); preloadDisabled = TRUE; } - // clean up + // clean up if ( exitStatus ) { QCopEnvelope e("QPE/System", "notBusy(QString)"); e << app->exec(); } -/* +/* // debug info for (it = runningApps.begin(); it != runningApps.end(); ++it) { qDebug("running according to internal list: %s, with pid %d", (*it).data(), it.key() ); } */ #ifdef QTOPIA_PROGRAM_MONITOR if ( crashed ) { @@ -391,34 +392,35 @@ void AppLauncher::sigStopped(int sigPid, int sigStatus) case SIGQUIT: sig = "SIGQUIT"; break; case SIGSEGV: sig = "SIGSEGV"; break; case SIGTERM: sig = "SIGTERM"; break; case SIGTRAP: sig = "SIGTRAP"; break; default: sig = QString("Unkown %1").arg(exitStatus); } if ( preloadDisabled ) sig += tr("<qt><p>Fast loading has been disabled for this application. Tap and hold the application icon to reenable it.</qt>"); - + QString str = tr("<qt><b>%1</b> was terminated due to signal code %2</qt>").arg( app->name() ).arg( sig ); QMessageBox::information(0, tr("Application terminated"), str ); } else { if ( exitStatus == 255 ) { //could not find app (because global returns -1) QMessageBox::information(0, tr("Application not found"), tr("<qt>Could not locate application <b>%1</b></qt>").arg( app->exec() ) ); } else { - QFileInfo fi(Global::tempDir() + "qcop-msg-" + appName); + QFileInfo fi(Opie::Global::tempDir() + "qcop-msg-" + appName); if ( fi.exists() && fi.size() ) { emit terminated(sigPid, appName); - execute( appName, QString::null ); + qWarning("Re executing obmitted for %s", appName.latin1() ); +// execute( appName, QString::null ); return; } } } #endif - + emit terminated(sigPid, appName); } #else void AppLauncher::sigStopped(int sigPid, int sigStatus) { qDebug("Unhandled signal : AppLauncher::sigStopped(int sigPid, int sigStatus)"); } #endif // Q_OS_WIN32 @@ -439,19 +441,19 @@ bool AppLauncher::isRunning(const QString &app) } } return FALSE; } bool AppLauncher::executeBuiltin(const QString &c, const QString &document) { - Global::Command* builtin = Global::builtinCommands(); - QGuardedPtr<QWidget> *running = Global::builtinRunning(); - + Global::Command* builtin = Opie::Global::builtinCommands(); + QGuardedPtr<QWidget> *running = Opie::Global::builtinRunning(); + // Attempt to execute the app using a builtin class for the app if (builtin) { for (int i = 0; builtin[i].file; i++) { if ( builtin[i].file == c ) { if ( running[i] ) { if ( !document.isNull() && builtin[i].documentary ) Global::setDocument(running[i], document); running[i]->raise(); @@ -478,33 +480,34 @@ bool AppLauncher::executeBuiltin(const QString &c, const QString &document) return TRUE; } return FALSE; } bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise) { + qWarning("AppLauncher::execute"); // Convert the command line in to a list of arguments QStringList list = QStringList::split(QRegExp(" *"),c); if ( !docParam.isEmpty() ) list.append( docParam ); QString appName = list[0]; if ( isRunning(appName) ) { QCString channel = "QPE/Application/"; channel += appName.latin1(); - + // Need to lock it to avoid race conditions with QPEApplication::processQCopFile - QFile f(Global::tempDir() + "qcop-msg-" + appName); + QFile f(Opie::Global::tempDir() + "qcop-msg-" + appName); if ( !noRaise && f.open(IO_WriteOnly | IO_Append) ) { #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_EX); #endif - + QDataStream ds(&f); QByteArray b; QDataStream bstream(b, IO_WriteOnly); if ( !f.size() ) { ds << channel << QCString("raise()") << b; if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) { int id = startTimer(RAISE_TIMEOUT_MS); waitingHeartbeat.insert( appName, id ); @@ -518,22 +521,22 @@ bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRais f.flush(); #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_UN); #endif f.close(); } if ( QCopChannel::isRegistered(channel) ) // avoid unnecessary warnings QCopChannel::send(channel,"QPEProcessQCop()"); - + return TRUE; } #ifdef QT_NO_QWS_MULTIPROCESS - QMessageBox::warning( 0, tr("Error"), tr("Could not find the application %1").arg(c), + QMessageBox::warning( 0, tr("Error"), tr("<qt>Could not find the application %1</qt>").arg(c), tr("OK"), 0, 0, 0, 1 ); #else QStrList slist; unsigned j; for ( j = 0; j < list.count(); j++ ) slist.append( list[j].utf8() ); @@ -580,17 +583,17 @@ bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRais proc->addArgument(args[i]); connect(proc, SIGNAL(processExited()), this, SLOT(processExited())); if (!proc->start()){ qDebug("Unable to start application %s", args[0]); }else{ PROCESS_INFORMATION *procInfo = (PROCESS_INFORMATION *)proc->processIdentifier(); if (procInfo){ DWORD pid = procInfo->dwProcessId; - runningApps[pid] = QString(args[0]); + runningApps[pid] = QString(args[0]); runningAppsProc.append(proc); emit launched(pid, QString(args[0])); QCopEnvelope e("QPE/System", "busy()"); }else{ qDebug("Unable to read process inforation #1 for %s", args[0]); } } }else{ @@ -630,29 +633,35 @@ int AppLauncher::pidForName( const QString &appName ) } } return pid; } void AppLauncher::createQuickLauncher() { + static bool disabled = FALSE; + if (disabled) + return; + qlReady = FALSE; qlPid = ::vfork(); if ( !qlPid ) { char **args = new char *[2]; args[0] = "quicklauncher"; args[1] = 0; for ( int fd = 3; fd < 100; fd++ ) ::close( fd ); ::setpgid( ::getpid(), ::getppid() ); // Try bindir first, so that foo/bar works too setenv( "LD_BIND_NOW", "1", 1 ); ::execv( QPEApplication::qpeDir()+"bin/quicklauncher", args ); ::execvp( "quicklauncher", args ); + delete []args; + disabled = TRUE; _exit( -1 ); } else if ( qlPid == -1 ) { qlPid = 0; } else { if ( getuid() == 0 ) setpriority( PRIO_PROCESS, qlPid, 19 ); } } @@ -666,17 +675,17 @@ void AppLauncher::processExited() QProcess *proc = (QProcess *) sender(); if (!proc){ qDebug("Interanl error NULL proc"); return; } QString appName = proc->arguments()[0]; qDebug("Removing application %s", appName.latin1()); - runningAppsProc.remove(proc); + runningAppsProc.remove(proc); QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName); if ( hbit != waitingHeartbeat.end() ) { killTimer( *hbit ); waitingHeartbeat.remove( hbit ); } if ( appName == appKillerName ) { appKillerName = QString::null; @@ -694,12 +703,12 @@ void AppLauncher::processExited() } if (found){ emit terminated(it.key(), it.data()); runningApps.remove(it.key()); }else{ qDebug("Internal error application %s not listed as running", appName.latin1()); } - + #endif } |