summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/applauncher.cpp2
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