-rw-r--r-- | core/launcher/applauncher.cpp | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/core/launcher/applauncher.cpp b/core/launcher/applauncher.cpp index a8779a5..c3584ad 100644 --- a/core/launcher/applauncher.cpp +++ b/core/launcher/applauncher.cpp @@ -295,385 +295,385 @@ void AppLauncher::timerEvent( QTimerEvent *e ) appKillerName = QString::null; delete appKillerBox; appKillerBox = 0; return; } } QObject::timerEvent( e ); } #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); } QMap<int,QString>::Iterator it = runningApps.find( sigPid ); if ( it == runningApps.end() ) { if ( sigPid == qlPid ) { qDebug( "quicklauncher stopped" ); qlPid = 0; qlReady = FALSE; QFile::remove("/tmp/qcop-msg-quicklauncher" ); QTimer::singleShot( 2000, this, SLOT(createQuickLauncher()) ); } /* if ( sigPid == -1 ) qDebug("non-qtopia application exited (disregarded)"); else qDebug("==== no pid matching %d in list, definite bug", sigPid); */ return; } QString appName = *it; runningApps.remove(it); QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName); if ( hbit != waitingHeartbeat.end() ) { killTimer( *hbit ); waitingHeartbeat.remove( hbit ); } if ( appName == appKillerName ) { appKillerName = QString::null; delete appKillerBox; appKillerBox = 0; } /* we must disable preload for an app that crashes as the system logic relies on preloaded apps actually being loaded. If eg. the crash happened in the constructor, we can't automatically reload the app (withouth some timeout value for eg. 3 tries (which I think is a bad solution) */ bool preloadDisabled = FALSE; if ( !DocumentList::appLnkSet ) return; const AppLnk* app = DocumentList::appLnkSet->findExec( appName ); if ( !app ) return; // QCop messages processed to slow? if ( crashed && app->isPreloaded() ) { Config cfg("Launcher"); cfg.setGroup("Preload"); QStringList apps = cfg.readListEntry("Apps",','); QString exe = app->exec(); apps.remove(exe); cfg.writeEntry("Apps",apps,','); preloadDisabled = TRUE; } // 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 ) { QString sig; switch( exitStatus ) { case SIGABRT: sig = "SIGABRT"; break; case SIGALRM: sig = "SIGALRM"; break; case SIGBUS: sig = "SIGBUS"; break; case SIGFPE: sig = "SIGFPE"; break; case SIGHUP: sig = "SIGHUP"; break; case SIGILL: sig = "SIGILL"; break; case SIGKILL: sig = "SIGKILL"; break; case SIGPIPE: sig = "SIGPIPE"; break; 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(QString::fromLatin1("/tmp/qcop-msg-") + appName); if ( fi.exists() && fi.size() ) { emit terminated(sigPid, appName); 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 bool AppLauncher::isRunning(const QString &app) { for (QMap<int,QString>::ConstIterator it = runningApps.begin(); it != runningApps.end(); ++it) { if ( *it == app ) { #ifdef Q_OS_UNIX pid_t t = ::__getpgid( it.key() ); if ( t == -1 ) { qDebug("appLauncher bug, %s believed running, but pid %d is not existing", app.data(), it.key() ); runningApps.remove( it.key() ); return FALSE; } #endif return TRUE; } } return FALSE; } bool AppLauncher::executeBuiltin(const QString &c, const QString &document) { Global::Command* builtin = OGlobal::builtinCommands(); QGuardedPtr<QWidget> *running = OGlobal::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(); running[i]->show(); running[i]->setActiveWindow(); } else { running[i] = builtin[i].func( builtin[i].maximized ); } #ifndef QT_NO_COP QCopEnvelope e("QPE/System", "notBusy(QString)" ); e << c; // that was quick ;-) #endif return TRUE; } } } // Convert the command line in to a list of arguments QStringList list = QStringList::split(QRegExp(" *"),c); QString ap=list[0]; if ( ap == "suspend" ) { // No tr QWSServer::processKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); return TRUE; } return FALSE; } bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise) { - qWarning("AppLauncher::execute"); + qWarning("AppLauncher::execute '%s' '%s'", (const char*) c, (const char*) docParam ); // 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(QString::fromLatin1("/tmp/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 ); } } if ( !docParam.isEmpty() ) { bstream << docParam; ds << channel << QCString("setDocument(QString)") << b; } 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("<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() ); const char **args = new const char *[slist.count() + 1]; for ( j = 0; j < slist.count(); j++ ) args[j] = slist.at(j); args[j] = NULL; #ifndef Q_OS_WIN32 #ifdef Q_OS_MACX if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".dylib" ) ) { #else if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".so" ) ) { #endif /* Q_OS_MACX */ qDebug( "Quick launching: %s", args[0] ); if ( getuid() == 0 ) setpriority( PRIO_PROCESS, qlPid, 0 ); QCString qlch("QPE/QuickLauncher-"); qlch += QString::number(qlPid); QCopEnvelope env( qlch, "execute(QStrList)" ); env << slist; runningApps[qlPid] = QString(args[0]); emit launched(qlPid, QString(args[0])); QCopEnvelope e("QPE/System", "busy()"); qlPid = 0; qlReady = FALSE; QTimer::singleShot( getuid() == 0 ? 800 : 1500, this, SLOT(createQuickLauncher()) ); } else { int pid = ::vfork(); if ( !pid ) { for ( int fd = 3; fd < 100; fd++ ) ::close( fd ); ::setpgid( ::getpid(), ::getppid() ); // Try bindir first, so that foo/bar works too ::execv( QPEApplication::qpeDir()+"bin/"+args[0], (char * const *)args ); ::execvp( args[0], (char * const *)args ); _exit( -1 ); } runningApps[pid] = QString(args[0]); emit launched(pid, QString(args[0])); QCopEnvelope e("QPE/System", "busy()"); } #else QProcess *proc = new QProcess(this); if (proc){ for (int i=0; i < slist.count(); i++) 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]); 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{ qDebug("Unable to create process for application %s", args[0]); return FALSE; } #endif #endif //QT_NO_QWS_MULTIPROCESS delete [] args; return TRUE; } void AppLauncher::kill( int pid ) { #ifndef Q_OS_WIN32 ::kill( pid, SIGTERM ); #else for ( QProcess *proc = runningAppsProc.first(); proc; proc = runningAppsProc.next() ) { if ( proc->processIdentifier() == pid ) { proc->kill(); break; } } #endif } int AppLauncher::pidForName( const QString &appName ) { int pid = -1; QMap<int, QString>::Iterator it; for (it = runningApps.begin(); it!= runningApps.end(); ++it) { if (*it == appName) { pid = it.key(); break; } } 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 /* * LD_BIND_NOW will change the behaviour of ld.so and dlopen * RTLD_LAZY will be made RTLD_NOW which leads to problem * with miscompiled libraries... if LD_BIND_NOW is set.. there * is no way back.. We will wait for numbers from TT to see * if using LD_BIND_NOW is worth it - zecke */ // 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 ); } } // Used only by Win32 |