summaryrefslogtreecommitdiff
authorzecke <zecke>2003-08-28 14:32:22 (UTC)
committer zecke <zecke>2003-08-28 14:32:22 (UTC)
commitf3c6caca7e96488ad9e1873e9c853f11b17a944e (patch) (unidiff)
tree4a83c306c573d5185f20c0f96f89aeffa24e2e1d
parenta069f32d9339fad02af60ac8aa991c3dee011039 (diff)
downloadopie-f3c6caca7e96488ad9e1873e9c853f11b17a944e.zip
opie-f3c6caca7e96488ad9e1873e9c853f11b17a944e.tar.gz
opie-f3c6caca7e96488ad9e1873e9c853f11b17a944e.tar.bz2
Make conpile with Opie
If QuickApps exec fails don't try to start it anytime soon If application fails to start and /tmp/qcop-msg- is present don't try to restart
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/applauncher.cpp69
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
@@ -6,173 +6,174 @@
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#ifndef QTOPIA_INTERNAL_PRELOADACCESS 21#ifndef QTOPIA_INTERNAL_PRELOADACCESS
22#define QTOPIA_INTERNAL_PRELOADACCESS 22#define QTOPIA_INTERNAL_PRELOADACCESS
23#endif 23#endif
24#ifndef QTOPIA_INTERNAL_FILEOPERATIONS 24#ifndef QTOPIA_INTERNAL_FILEOPERATIONS
25#define QTOPIA_INTERNAL_FILEOPERATIONS 25#define QTOPIA_INTERNAL_FILEOPERATIONS
26#endif 26#endif
27#ifndef QTOPIA_PROGRAM_MONITOR 27#ifndef QTOPIA_PROGRAM_MONITOR
28#define QTOPIA_PROGRAM_MONITOR 28#define QTOPIA_PROGRAM_MONITOR
29#endif 29#endif
30#include <qtopia/qpeglobal.h> 30#include <qtopia/global.h>
31 31
32#ifndef Q_OS_WIN32 32#ifndef Q_OS_WIN32
33#include <sys/stat.h> 33#include <sys/stat.h>
34#include <sys/wait.h> 34#include <sys/wait.h>
35#include <sys/file.h> 35#include <sys/file.h>
36#include <unistd.h> 36#include <unistd.h>
37#include <sys/time.h> 37#include <sys/time.h>
38#include <sys/resource.h> 38#include <sys/resource.h>
39#include <errno.h> 39#include <errno.h>
40#else 40#else
41#include <process.h> 41#include <process.h>
42#include <windows.h> 42#include <windows.h>
43#include <winbase.h> 43#include <winbase.h>
44#endif 44#endif
45 45
46#include <signal.h> 46#include <signal.h>
47#include <sys/types.h> 47#include <sys/types.h>
48#include <stdlib.h> 48#include <stdlib.h>
49 49
50#include <qtimer.h> 50#include <qtimer.h>
51#include <qwindowsystem_qws.h> 51#include <qwindowsystem_qws.h>
52#include <qmessagebox.h> 52#include <qmessagebox.h>
53#include <qfile.h> 53#include <qfile.h>
54#include <qfileinfo.h> 54#include <qfileinfo.h>
55 55
56#include <qtopia/qcopenvelope_qws.h> 56#include <qtopia/qcopenvelope_qws.h>
57#include <qtopia/applnk.h> 57#include <qtopia/applnk.h>
58#include <qtopia/qpeapplication.h> 58#include <qtopia/qpeapplication.h>
59#include <qtopia/config.h> 59#include <qtopia/config.h>
60#include <qtopia/global.h> 60#include <qtopia/global.h>
61 61
62#include "applauncher.h" 62#include "applauncher.h"
63#include "documentlist.h" 63#include "documentlist.h"
64#include "launcherglobal.h"
64 65
65const int AppLauncher::RAISE_TIMEOUT_MS = 5000; 66const int AppLauncher::RAISE_TIMEOUT_MS = 5000;
66 67
67//--------------------------------------------------------------------------- 68//---------------------------------------------------------------------------
68 69
69static AppLauncher* appLauncherPtr; 70static AppLauncher* appLauncherPtr;
70 71
71const int appStopEventID = 1290; 72const int appStopEventID = 1290;
72 73
73class AppStoppedEvent : public QCustomEvent 74class AppStoppedEvent : public QCustomEvent
74{ 75{
75public: 76public:
76 AppStoppedEvent(int pid, int status) 77 AppStoppedEvent(int pid, int status)
77 : QCustomEvent( appStopEventID ), mPid(pid), mStatus(status) { } 78 : QCustomEvent( appStopEventID ), mPid(pid), mStatus(status) { }
78 79
79 int pid() { return mPid; } 80 int pid() { return mPid; }
80 int status() { return mStatus; } 81 int status() { return mStatus; }
81 82
82private: 83private:
83 int mPid, mStatus; 84 int mPid, mStatus;
84}; 85};
85 86
86AppLauncher::AppLauncher(QObject *parent, const char *name) 87AppLauncher::AppLauncher(QObject *parent, const char *name)
87 : QObject(parent, name), qlPid(0), qlReady(FALSE), 88 : QObject(parent, name), qlPid(0), qlReady(FALSE),
88 appKillerBox(0) 89 appKillerBox(0)
89{ 90{
90 connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&))); 91 connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&)));
91 connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&))); 92 connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&)));
92 QCopChannel* channel = new QCopChannel( "QPE/System", this ); 93 QCopChannel* channel = new QCopChannel( "QPE/System", this );
93 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), 94 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
94 this, SLOT(received(const QCString&, const QByteArray&)) ); 95 this, SLOT(received(const QCString&, const QByteArray&)) );
95 96
96 channel = new QCopChannel( "QPE/Server", this ); 97 channel = new QCopChannel( "QPE/Server", this );
97 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), 98 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
98 this, SLOT(received(const QCString&, const QByteArray&)) ); 99 this, SLOT(received(const QCString&, const QByteArray&)) );
99 100
100#ifndef Q_OS_WIN32 101#ifndef Q_OS_WIN32
101 signal(SIGCHLD, signalHandler); 102 signal(SIGCHLD, signalHandler);
102#else 103#else
103 runningAppsProc.setAutoDelete( TRUE ); 104 runningAppsProc.setAutoDelete( TRUE );
104#endif 105#endif
105 QString tmp = qApp->argv()[0]; 106 QString tmp = qApp->argv()[0];
106 int pos = tmp.findRev('/'); 107 int pos = tmp.findRev('/');
107 if ( pos > -1 ) 108 if ( pos > -1 )
108 tmp = tmp.mid(++pos); 109 tmp = tmp.mid(++pos);
109 runningApps[::getpid()] = tmp; 110 runningApps[::getpid()] = tmp;
110 111
111 appLauncherPtr = this; 112 appLauncherPtr = this;
112 113
113 QTimer::singleShot( 1000, this, SLOT(createQuickLauncher()) ); 114 QTimer::singleShot( 1000, this, SLOT(createQuickLauncher()) );
114} 115}
115 116
116AppLauncher::~AppLauncher() 117AppLauncher::~AppLauncher()
117{ 118{
118 appLauncherPtr = 0; 119 appLauncherPtr = 0;
119#ifndef Q_OS_WIN32 120#ifndef Q_OS_WIN32
120 signal(SIGCHLD, SIG_DFL); 121 signal(SIGCHLD, SIG_DFL);
121#endif 122#endif
122 if ( qlPid ) { 123 if ( qlPid ) {
123 int status; 124 int status;
124 ::kill( qlPid, SIGTERM ); 125 ::kill( qlPid, SIGTERM );
125 waitpid( qlPid, &status, 0 ); 126 waitpid( qlPid, &status, 0 );
126 } 127 }
127} 128}
128 129
129/* We use the QCopChannel of the app as an indicator of when it has been launched 130/* We use the QCopChannel of the app as an indicator of when it has been launched
130 so that we can disable the busy indicators */ 131 so that we can disable the busy indicators */
131void AppLauncher::newQcopChannel(const QString& channelName) 132void AppLauncher::newQcopChannel(const QString& channelName)
132{ 133{
133// qDebug("channel %s added", channelName.data() ); 134// qDebug("channel %s added", channelName.data() );
134 QString prefix("QPE/Application/"); 135 QString prefix("QPE/Application/");
135 if (channelName.startsWith(prefix)) { 136 if (channelName.startsWith(prefix)) {
136 { 137 {
137 QCopEnvelope e("QPE/System", "newChannel(QString)"); 138 QCopEnvelope e("QPE/System", "newChannel(QString)");
138 e << channelName; 139 e << channelName;
139 } 140 }
140 QString appName = channelName.mid(prefix.length()); 141 QString appName = channelName.mid(prefix.length());
141 if ( appName != "quicklauncher" ) { 142 if ( appName != "quicklauncher" ) {
142 emit connected( appName ); 143 emit connected( appName );
143 QCopEnvelope e("QPE/System", "notBusy(QString)"); 144 QCopEnvelope e("QPE/System", "notBusy(QString)");
144 e << appName; 145 e << appName;
145 } 146 }
146 } else if (channelName.startsWith("QPE/QuickLauncher-")) { 147 } else if (channelName.startsWith("QPE/QuickLauncher-")) {
147 qDebug("Registered %s", channelName.latin1()); 148 qDebug("Registered %s", channelName.latin1());
148 int pid = channelName.mid(18).toInt(); 149 int pid = channelName.mid(18).toInt();
149 if (pid == qlPid) 150 if (pid == qlPid)
150 qlReady = TRUE; 151 qlReady = TRUE;
151 } 152 }
152} 153}
153 154
154void AppLauncher::removedQcopChannel(const QString& channelName) 155void AppLauncher::removedQcopChannel(const QString& channelName)
155{ 156{
156 if (channelName.startsWith("QPE/Application/")) { 157 if (channelName.startsWith("QPE/Application/")) {
157 QCopEnvelope e("QPE/System", "removedChannel(QString)"); 158 QCopEnvelope e("QPE/System", "removedChannel(QString)");
158 e << channelName; 159 e << channelName;
159 } 160 }
160} 161}
161 162
162void AppLauncher::received(const QCString& msg, const QByteArray& data) 163void AppLauncher::received(const QCString& msg, const QByteArray& data)
163{ 164{
164 QDataStream stream( data, IO_ReadOnly ); 165 QDataStream stream( data, IO_ReadOnly );
165 if ( msg == "execute(QString)" ) { 166 if ( msg == "execute(QString)" ) {
166 QString t; 167 QString t;
167 stream >> t; 168 stream >> t;
168 if ( !executeBuiltin( t, QString::null ) ) 169 if ( !executeBuiltin( t, QString::null ) )
169 execute(t, QString::null); 170 execute(t, QString::null);
170 } else if ( msg == "execute(QString,QString)" ) { 171 } else if ( msg == "execute(QString,QString)" ) {
171 QString t,d; 172 QString t,d;
172 stream >> t >> d; 173 stream >> t >> d;
173 if ( !executeBuiltin( t, d ) ) 174 if ( !executeBuiltin( t, d ) )
174 execute( t, d ); 175 execute( t, d );
175 } else if ( msg == "processQCop(QString)" ) { // from QPE/Server 176 } else if ( msg == "processQCop(QString)" ) { // from QPE/Server
176 QString t; 177 QString t;
177 stream >> t; 178 stream >> t;
178 if ( !executeBuiltin( t, QString::null ) ) 179 if ( !executeBuiltin( t, QString::null ) )
@@ -238,96 +239,96 @@ void AppLauncher::received(const QCString& msg, const QByteArray& data)
238} 239}
239 240
240void AppLauncher::signalHandler(int) 241void AppLauncher::signalHandler(int)
241{ 242{
242#ifndef Q_OS_WIN32 243#ifndef Q_OS_WIN32
243 int status; 244 int status;
244 pid_t pid = waitpid(-1, &status, WNOHANG); 245 pid_t pid = waitpid(-1, &status, WNOHANG);
245/* if (pid == 0 || &status == 0 ) { 246/* if (pid == 0 || &status == 0 ) {
246 qDebug("hmm, could not get return value from signal"); 247 qDebug("hmm, could not get return value from signal");
247 } 248 }
248*/ 249*/
249 QApplication::postEvent(appLauncherPtr, new AppStoppedEvent(pid, status) ); 250 QApplication::postEvent(appLauncherPtr, new AppStoppedEvent(pid, status) );
250#else 251#else
251 qDebug("Unhandled signal see by AppLauncher::signalHandler(int)"); 252 qDebug("Unhandled signal see by AppLauncher::signalHandler(int)");
252#endif 253#endif
253} 254}
254 255
255bool AppLauncher::event(QEvent *e) 256bool AppLauncher::event(QEvent *e)
256{ 257{
257 if ( e->type() == appStopEventID ) { 258 if ( e->type() == appStopEventID ) {
258 AppStoppedEvent *ae = (AppStoppedEvent *) e; 259 AppStoppedEvent *ae = (AppStoppedEvent *) e;
259 sigStopped(ae->pid(), ae->status() ); 260 sigStopped(ae->pid(), ae->status() );
260 return TRUE; 261 return TRUE;
261 } 262 }
262 263
263 return QObject::event(e); 264 return QObject::event(e);
264} 265}
265 266
266void AppLauncher::timerEvent( QTimerEvent *e ) 267void AppLauncher::timerEvent( QTimerEvent *e )
267{ 268{
268 int id = e->timerId(); 269 int id = e->timerId();
269 QMap<QString,int>::Iterator it; 270 QMap<QString,int>::Iterator it;
270 for ( it = waitingHeartbeat.begin(); it != waitingHeartbeat.end(); ++it ) { 271 for ( it = waitingHeartbeat.begin(); it != waitingHeartbeat.end(); ++it ) {
271 if ( *it == id ) { 272 if ( *it == id ) {
272 if ( appKillerBox ) // we're already dealing with one 273 if ( appKillerBox ) // we're already dealing with one
273 return; 274 return;
274 275
275 appKillerName = it.key(); 276 appKillerName = it.key();
276 killTimer( id ); 277 killTimer( id );
277 waitingHeartbeat.remove( it ); 278 waitingHeartbeat.remove( it );
278 279
279 // qDebug("Checking in on %s", appKillerName.latin1()); 280 // qDebug("Checking in on %s", appKillerName.latin1());
280 281
281 // We store this incase the application responds while we're 282 // We store this incase the application responds while we're
282 // waiting for user input so we know not to delete ourselves. 283 // waiting for user input so we know not to delete ourselves.
283 appKillerBox = new QMessageBox(tr("Application Problem"), 284 appKillerBox = new QMessageBox(tr("Application Problem"),
284 tr("<p>%1 is not responding.</p>").arg(appKillerName) + 285 tr("<p>%1 is not responding.</p>").arg(appKillerName) +
285 tr("<p>Would you like to force the application to exit?</p>"), 286 tr("<p>Would you like to force the application to exit?</p>"),
286 QMessageBox::Warning, QMessageBox::Yes, 287 QMessageBox::Warning, QMessageBox::Yes,
287 QMessageBox::No | QMessageBox::Default, 288 QMessageBox::No | QMessageBox::Default,
288 QMessageBox::NoButton); 289 QMessageBox::NoButton);
289 if (appKillerBox->exec() == QMessageBox::Yes) { 290 if (appKillerBox->exec() == QMessageBox::Yes) {
290 // qDebug("Killing the app!!! Bwuhahahaha!"); 291 // qDebug("Killing the app!!! Bwuhahahaha!");
291 int pid = pidForName(appKillerName); 292 int pid = pidForName(appKillerName);
292 if ( pid > 0 ) 293 if ( pid > 0 )
293 kill( pid ); 294 kill( pid );
294 } 295 }
295 appKillerName = QString::null; 296 appKillerName = QString::null;
296 delete appKillerBox; 297 delete appKillerBox;
297 appKillerBox = 0; 298 appKillerBox = 0;
298 return; 299 return;
299 } 300 }
300 } 301 }
301 302
302 QObject::timerEvent( e ); 303 QObject::timerEvent( e );
303} 304}
304 305
305#ifndef Q_OS_WIN32 306#ifndef Q_OS_WIN32
306void AppLauncher::sigStopped(int sigPid, int sigStatus) 307void AppLauncher::sigStopped(int sigPid, int sigStatus)
307{ 308{
308 int exitStatus = 0; 309 int exitStatus = 0;
309 310
310 bool crashed = WIFSIGNALED(sigStatus); 311 bool crashed = WIFSIGNALED(sigStatus);
311 if ( !crashed ) { 312 if ( !crashed ) {
312 if ( WIFEXITED(sigStatus) ) 313 if ( WIFEXITED(sigStatus) )
313 exitStatus = WEXITSTATUS(sigStatus); 314 exitStatus = WEXITSTATUS(sigStatus);
314 } else { 315 } else {
315 exitStatus = WTERMSIG(sigStatus); 316 exitStatus = WTERMSIG(sigStatus);
316 } 317 }
317 318
318 QMap<int,QString>::Iterator it = runningApps.find( sigPid ); 319 QMap<int,QString>::Iterator it = runningApps.find( sigPid );
319 if ( it == runningApps.end() ) { 320 if ( it == runningApps.end() ) {
320 if ( sigPid == qlPid ) { 321 if ( sigPid == qlPid ) {
321 qDebug( "quicklauncher stopped" ); 322 qDebug( "quicklauncher stopped" );
322 qlPid = 0; 323 qlPid = 0;
323 qlReady = FALSE; 324 qlReady = FALSE;
324 QFile::remove("/tmp/qcop-msg-quicklauncher" ); 325 QFile::remove("/tmp/qcop-msg-quicklauncher" );
325 QTimer::singleShot( 2000, this, SLOT(createQuickLauncher()) ); 326 QTimer::singleShot( 2000, this, SLOT(createQuickLauncher()) );
326 } 327 }
327/* 328/*
328 if ( sigPid == -1 ) 329 if ( sigPid == -1 )
329 qDebug("non-qtopia application exited (disregarded)"); 330 qDebug("non-qtopia application exited (disregarded)");
330 else 331 else
331 qDebug("==== no pid matching %d in list, definite bug", sigPid); 332 qDebug("==== no pid matching %d in list, definite bug", sigPid);
332*/ 333*/
333 return; 334 return;
@@ -343,213 +344,215 @@ void AppLauncher::sigStopped(int sigPid, int sigStatus)
343 if ( appName == appKillerName ) { 344 if ( appName == appKillerName ) {
344 appKillerName = QString::null; 345 appKillerName = QString::null;
345 delete appKillerBox; 346 delete appKillerBox;
346 appKillerBox = 0; 347 appKillerBox = 0;
347 } 348 }
348 349
349 /* we must disable preload for an app that crashes as the system logic relies on preloaded apps 350 /* we must disable preload for an app that crashes as the system logic relies on preloaded apps
350 actually being loaded. If eg. the crash happened in the constructor, we can't automatically reload 351 actually being loaded. If eg. the crash happened in the constructor, we can't automatically reload
351 the app (withouth some timeout value for eg. 3 tries (which I think is a bad solution) 352 the app (withouth some timeout value for eg. 3 tries (which I think is a bad solution)
352 */ 353 */
353 bool preloadDisabled = FALSE; 354 bool preloadDisabled = FALSE;
354 if ( !DocumentList::appLnkSet ) return; 355 if ( !DocumentList::appLnkSet ) return;
355 const AppLnk* app = DocumentList::appLnkSet->findExec( appName ); 356 const AppLnk* app = DocumentList::appLnkSet->findExec( appName );
356 if ( !app ) return; // QCop messages processed to slow? 357 if ( !app ) return; // QCop messages processed to slow?
357 if ( crashed && app->isPreloaded() ) { 358 if ( crashed && app->isPreloaded() ) {
358 Config cfg("Launcher"); 359 Config cfg("Launcher");
359 cfg.setGroup("Preload"); 360 cfg.setGroup("Preload");
360 QStringList apps = cfg.readListEntry("Apps",','); 361 QStringList apps = cfg.readListEntry("Apps",',');
361 QString exe = app->exec(); 362 QString exe = app->exec();
362 apps.remove(exe); 363 apps.remove(exe);
363 cfg.writeEntry("Apps",apps,','); 364 cfg.writeEntry("Apps",apps,',');
364 preloadDisabled = TRUE; 365 preloadDisabled = TRUE;
365 } 366 }
366 367
367 // clean up 368 // clean up
368 if ( exitStatus ) { 369 if ( exitStatus ) {
369 QCopEnvelope e("QPE/System", "notBusy(QString)"); 370 QCopEnvelope e("QPE/System", "notBusy(QString)");
370 e << app->exec(); 371 e << app->exec();
371 } 372 }
372/* 373/*
373 // debug info 374 // debug info
374 for (it = runningApps.begin(); it != runningApps.end(); ++it) { 375 for (it = runningApps.begin(); it != runningApps.end(); ++it) {
375 qDebug("running according to internal list: %s, with pid %d", (*it).data(), it.key() ); 376 qDebug("running according to internal list: %s, with pid %d", (*it).data(), it.key() );
376 } 377 }
377*/ 378*/
378 379
379#ifdef QTOPIA_PROGRAM_MONITOR 380#ifdef QTOPIA_PROGRAM_MONITOR
380 if ( crashed ) { 381 if ( crashed ) {
381 QString sig; 382 QString sig;
382 switch( exitStatus ) { 383 switch( exitStatus ) {
383 case SIGABRT: sig = "SIGABRT"; break; 384 case SIGABRT: sig = "SIGABRT"; break;
384 case SIGALRM: sig = "SIGALRM"; break; 385 case SIGALRM: sig = "SIGALRM"; break;
385 case SIGBUS: sig = "SIGBUS"; break; 386 case SIGBUS: sig = "SIGBUS"; break;
386 case SIGFPE: sig = "SIGFPE"; break; 387 case SIGFPE: sig = "SIGFPE"; break;
387 case SIGHUP: sig = "SIGHUP"; break; 388 case SIGHUP: sig = "SIGHUP"; break;
388 case SIGILL: sig = "SIGILL"; break; 389 case SIGILL: sig = "SIGILL"; break;
389 case SIGKILL: sig = "SIGKILL"; break; 390 case SIGKILL: sig = "SIGKILL"; break;
390 case SIGPIPE: sig = "SIGPIPE"; break; 391 case SIGPIPE: sig = "SIGPIPE"; break;
391 case SIGQUIT: sig = "SIGQUIT"; break; 392 case SIGQUIT: sig = "SIGQUIT"; break;
392 case SIGSEGV: sig = "SIGSEGV"; break; 393 case SIGSEGV: sig = "SIGSEGV"; break;
393 case SIGTERM: sig = "SIGTERM"; break; 394 case SIGTERM: sig = "SIGTERM"; break;
394 case SIGTRAP: sig = "SIGTRAP"; break; 395 case SIGTRAP: sig = "SIGTRAP"; break;
395 default: sig = QString("Unkown %1").arg(exitStatus); 396 default: sig = QString("Unkown %1").arg(exitStatus);
396 } 397 }
397 if ( preloadDisabled ) 398 if ( preloadDisabled )
398 sig += tr("<qt><p>Fast loading has been disabled for this application. Tap and hold the application icon to reenable it.</qt>"); 399 sig += tr("<qt><p>Fast loading has been disabled for this application. Tap and hold the application icon to reenable it.</qt>");
399 400
400 QString str = tr("<qt><b>%1</b> was terminated due to signal code %2</qt>").arg( app->name() ).arg( sig ); 401 QString str = tr("<qt><b>%1</b> was terminated due to signal code %2</qt>").arg( app->name() ).arg( sig );
401 QMessageBox::information(0, tr("Application terminated"), str ); 402 QMessageBox::information(0, tr("Application terminated"), str );
402 } else { 403 } else {
403 if ( exitStatus == 255 ) { //could not find app (because global returns -1) 404 if ( exitStatus == 255 ) { //could not find app (because global returns -1)
404 QMessageBox::information(0, tr("Application not found"), tr("<qt>Could not locate application <b>%1</b></qt>").arg( app->exec() ) ); 405 QMessageBox::information(0, tr("Application not found"), tr("<qt>Could not locate application <b>%1</b></qt>").arg( app->exec() ) );
405 } else { 406 } else {
406 QFileInfo fi(Global::tempDir() + "qcop-msg-" + appName); 407 QFileInfo fi(Opie::Global::tempDir() + "qcop-msg-" + appName);
407 if ( fi.exists() && fi.size() ) { 408 if ( fi.exists() && fi.size() ) {
408 emit terminated(sigPid, appName); 409 emit terminated(sigPid, appName);
409 execute( appName, QString::null ); 410 qWarning("Re executing obmitted for %s", appName.latin1() );
411 // execute( appName, QString::null );
410 return; 412 return;
411 } 413 }
412 } 414 }
413 } 415 }
414 416
415#endif 417#endif
416 418
417 emit terminated(sigPid, appName); 419 emit terminated(sigPid, appName);
418} 420}
419#else 421#else
420void AppLauncher::sigStopped(int sigPid, int sigStatus) 422void AppLauncher::sigStopped(int sigPid, int sigStatus)
421{ 423{
422 qDebug("Unhandled signal : AppLauncher::sigStopped(int sigPid, int sigStatus)"); 424 qDebug("Unhandled signal : AppLauncher::sigStopped(int sigPid, int sigStatus)");
423} 425}
424#endif // Q_OS_WIN32 426#endif // Q_OS_WIN32
425 427
426bool AppLauncher::isRunning(const QString &app) 428bool AppLauncher::isRunning(const QString &app)
427{ 429{
428 for (QMap<int,QString>::ConstIterator it = runningApps.begin(); it != runningApps.end(); ++it) { 430 for (QMap<int,QString>::ConstIterator it = runningApps.begin(); it != runningApps.end(); ++it) {
429 if ( *it == app ) { 431 if ( *it == app ) {
430#ifdef Q_OS_UNIX 432#ifdef Q_OS_UNIX
431 pid_t t = ::__getpgid( it.key() ); 433 pid_t t = ::__getpgid( it.key() );
432 if ( t == -1 ) { 434 if ( t == -1 ) {
433 qDebug("appLauncher bug, %s believed running, but pid %d is not existing", app.data(), it.key() ); 435 qDebug("appLauncher bug, %s believed running, but pid %d is not existing", app.data(), it.key() );
434 runningApps.remove( it.key() ); 436 runningApps.remove( it.key() );
435 return FALSE; 437 return FALSE;
436 } 438 }
437#endif 439#endif
438 return TRUE; 440 return TRUE;
439 } 441 }
440 } 442 }
441 443
442 return FALSE; 444 return FALSE;
443} 445}
444 446
445bool AppLauncher::executeBuiltin(const QString &c, const QString &document) 447bool AppLauncher::executeBuiltin(const QString &c, const QString &document)
446{ 448{
447 Global::Command* builtin = Global::builtinCommands(); 449 Global::Command* builtin = Opie::Global::builtinCommands();
448 QGuardedPtr<QWidget> *running = Global::builtinRunning(); 450 QGuardedPtr<QWidget> *running = Opie::Global::builtinRunning();
449 451
450 // Attempt to execute the app using a builtin class for the app 452 // Attempt to execute the app using a builtin class for the app
451 if (builtin) { 453 if (builtin) {
452 for (int i = 0; builtin[i].file; i++) { 454 for (int i = 0; builtin[i].file; i++) {
453 if ( builtin[i].file == c ) { 455 if ( builtin[i].file == c ) {
454 if ( running[i] ) { 456 if ( running[i] ) {
455 if ( !document.isNull() && builtin[i].documentary ) 457 if ( !document.isNull() && builtin[i].documentary )
456 Global::setDocument(running[i], document); 458 Global::setDocument(running[i], document);
457 running[i]->raise(); 459 running[i]->raise();
458 running[i]->show(); 460 running[i]->show();
459 running[i]->setActiveWindow(); 461 running[i]->setActiveWindow();
460 } else { 462 } else {
461 running[i] = builtin[i].func( builtin[i].maximized ); 463 running[i] = builtin[i].func( builtin[i].maximized );
462 } 464 }
463#ifndef QT_NO_COP 465#ifndef QT_NO_COP
464 QCopEnvelope e("QPE/System", "notBusy(QString)" ); 466 QCopEnvelope e("QPE/System", "notBusy(QString)" );
465 e << c; // that was quick ;-) 467 e << c; // that was quick ;-)
466#endif 468#endif
467 return TRUE; 469 return TRUE;
468 } 470 }
469 } 471 }
470 } 472 }
471 473
472 // Convert the command line in to a list of arguments 474 // Convert the command line in to a list of arguments
473 QStringList list = QStringList::split(QRegExp(" *"),c); 475 QStringList list = QStringList::split(QRegExp(" *"),c);
474 QString ap=list[0]; 476 QString ap=list[0];
475 477
476 if ( ap == "suspend" ) { // No tr 478 if ( ap == "suspend" ) { // No tr
477 QWSServer::processKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); 479 QWSServer::processKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE );
478 return TRUE; 480 return TRUE;
479 } 481 }
480 482
481 return FALSE; 483 return FALSE;
482} 484}
483 485
484bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise) 486bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise)
485{ 487{
488 qWarning("AppLauncher::execute");
486 // Convert the command line in to a list of arguments 489 // Convert the command line in to a list of arguments
487 QStringList list = QStringList::split(QRegExp(" *"),c); 490 QStringList list = QStringList::split(QRegExp(" *"),c);
488 if ( !docParam.isEmpty() ) 491 if ( !docParam.isEmpty() )
489 list.append( docParam ); 492 list.append( docParam );
490 493
491 QString appName = list[0]; 494 QString appName = list[0];
492 if ( isRunning(appName) ) { 495 if ( isRunning(appName) ) {
493 QCString channel = "QPE/Application/"; 496 QCString channel = "QPE/Application/";
494 channel += appName.latin1(); 497 channel += appName.latin1();
495 498
496 // Need to lock it to avoid race conditions with QPEApplication::processQCopFile 499 // Need to lock it to avoid race conditions with QPEApplication::processQCopFile
497 QFile f(Global::tempDir() + "qcop-msg-" + appName); 500 QFile f(Opie::Global::tempDir() + "qcop-msg-" + appName);
498 if ( !noRaise && f.open(IO_WriteOnly | IO_Append) ) { 501 if ( !noRaise && f.open(IO_WriteOnly | IO_Append) ) {
499#ifndef Q_OS_WIN32 502#ifndef Q_OS_WIN32
500 flock(f.handle(), LOCK_EX); 503 flock(f.handle(), LOCK_EX);
501#endif 504#endif
502 505
503 QDataStream ds(&f); 506 QDataStream ds(&f);
504 QByteArray b; 507 QByteArray b;
505 QDataStream bstream(b, IO_WriteOnly); 508 QDataStream bstream(b, IO_WriteOnly);
506 if ( !f.size() ) { 509 if ( !f.size() ) {
507 ds << channel << QCString("raise()") << b; 510 ds << channel << QCString("raise()") << b;
508 if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) { 511 if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) {
509 int id = startTimer(RAISE_TIMEOUT_MS); 512 int id = startTimer(RAISE_TIMEOUT_MS);
510 waitingHeartbeat.insert( appName, id ); 513 waitingHeartbeat.insert( appName, id );
511 } 514 }
512 } 515 }
513 if ( !docParam.isEmpty() ) { 516 if ( !docParam.isEmpty() ) {
514 bstream << docParam; 517 bstream << docParam;
515 ds << channel << QCString("setDocument(QString)") << b; 518 ds << channel << QCString("setDocument(QString)") << b;
516 } 519 }
517 520
518 f.flush(); 521 f.flush();
519#ifndef Q_OS_WIN32 522#ifndef Q_OS_WIN32
520 flock(f.handle(), LOCK_UN); 523 flock(f.handle(), LOCK_UN);
521#endif 524#endif
522 f.close(); 525 f.close();
523 } 526 }
524 if ( QCopChannel::isRegistered(channel) ) // avoid unnecessary warnings 527 if ( QCopChannel::isRegistered(channel) ) // avoid unnecessary warnings
525 QCopChannel::send(channel,"QPEProcessQCop()"); 528 QCopChannel::send(channel,"QPEProcessQCop()");
526 529
527 return TRUE; 530 return TRUE;
528 } 531 }
529 532
530#ifdef QT_NO_QWS_MULTIPROCESS 533#ifdef QT_NO_QWS_MULTIPROCESS
531 QMessageBox::warning( 0, tr("Error"), tr("Could not find the application %1").arg(c), 534 QMessageBox::warning( 0, tr("Error"), tr("<qt>Could not find the application %1</qt>").arg(c),
532 tr("OK"), 0, 0, 0, 1 ); 535 tr("OK"), 0, 0, 0, 1 );
533#else 536#else
534 537
535 QStrList slist; 538 QStrList slist;
536 unsigned j; 539 unsigned j;
537 for ( j = 0; j < list.count(); j++ ) 540 for ( j = 0; j < list.count(); j++ )
538 slist.append( list[j].utf8() ); 541 slist.append( list[j].utf8() );
539 542
540 const char **args = new const char *[slist.count() + 1]; 543 const char **args = new const char *[slist.count() + 1];
541 for ( j = 0; j < slist.count(); j++ ) 544 for ( j = 0; j < slist.count(); j++ )
542 args[j] = slist.at(j); 545 args[j] = slist.at(j);
543 args[j] = NULL; 546 args[j] = NULL;
544 547
545#ifndef Q_OS_WIN32 548#ifndef Q_OS_WIN32
546 if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".so" ) ) { 549 if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".so" ) ) {
547 qDebug( "Quick launching: %s", args[0] ); 550 qDebug( "Quick launching: %s", args[0] );
548 if ( getuid() == 0 ) 551 if ( getuid() == 0 )
549 setpriority( PRIO_PROCESS, qlPid, 0 ); 552 setpriority( PRIO_PROCESS, qlPid, 0 );
550 QCString qlch("QPE/QuickLauncher-"); 553 QCString qlch("QPE/QuickLauncher-");
551 qlch += QString::number(qlPid); 554 qlch += QString::number(qlPid);
552 QCopEnvelope env( qlch, "execute(QStrList)" ); 555 QCopEnvelope env( qlch, "execute(QStrList)" );
553 env << slist; 556 env << slist;
554 runningApps[qlPid] = QString(args[0]); 557 runningApps[qlPid] = QString(args[0]);
555 emit launched(qlPid, QString(args[0])); 558 emit launched(qlPid, QString(args[0]));
@@ -564,49 +567,49 @@ bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRais
564 ::close( fd ); 567 ::close( fd );
565 ::setpgid( ::getpid(), ::getppid() ); 568 ::setpgid( ::getpid(), ::getppid() );
566 // Try bindir first, so that foo/bar works too 569 // Try bindir first, so that foo/bar works too
567 ::execv( QPEApplication::qpeDir()+"bin/"+args[0], (char * const *)args ); 570 ::execv( QPEApplication::qpeDir()+"bin/"+args[0], (char * const *)args );
568 ::execvp( args[0], (char * const *)args ); 571 ::execvp( args[0], (char * const *)args );
569 _exit( -1 ); 572 _exit( -1 );
570 } 573 }
571 574
572 runningApps[pid] = QString(args[0]); 575 runningApps[pid] = QString(args[0]);
573 emit launched(pid, QString(args[0])); 576 emit launched(pid, QString(args[0]));
574 QCopEnvelope e("QPE/System", "busy()"); 577 QCopEnvelope e("QPE/System", "busy()");
575 } 578 }
576#else 579#else
577 QProcess *proc = new QProcess(this); 580 QProcess *proc = new QProcess(this);
578 if (proc){ 581 if (proc){
579 for (int i=0; i < slist.count(); i++) 582 for (int i=0; i < slist.count(); i++)
580 proc->addArgument(args[i]); 583 proc->addArgument(args[i]);
581 connect(proc, SIGNAL(processExited()), this, SLOT(processExited())); 584 connect(proc, SIGNAL(processExited()), this, SLOT(processExited()));
582 if (!proc->start()){ 585 if (!proc->start()){
583 qDebug("Unable to start application %s", args[0]); 586 qDebug("Unable to start application %s", args[0]);
584 }else{ 587 }else{
585 PROCESS_INFORMATION *procInfo = (PROCESS_INFORMATION *)proc->processIdentifier(); 588 PROCESS_INFORMATION *procInfo = (PROCESS_INFORMATION *)proc->processIdentifier();
586 if (procInfo){ 589 if (procInfo){
587 DWORD pid = procInfo->dwProcessId; 590 DWORD pid = procInfo->dwProcessId;
588 runningApps[pid] = QString(args[0]); 591 runningApps[pid] = QString(args[0]);
589 runningAppsProc.append(proc); 592 runningAppsProc.append(proc);
590 emit launched(pid, QString(args[0])); 593 emit launched(pid, QString(args[0]));
591 QCopEnvelope e("QPE/System", "busy()"); 594 QCopEnvelope e("QPE/System", "busy()");
592 }else{ 595 }else{
593 qDebug("Unable to read process inforation #1 for %s", args[0]); 596 qDebug("Unable to read process inforation #1 for %s", args[0]);
594 } 597 }
595 } 598 }
596 }else{ 599 }else{
597 qDebug("Unable to create process for application %s", args[0]); 600 qDebug("Unable to create process for application %s", args[0]);
598 return FALSE; 601 return FALSE;
599 } 602 }
600#endif 603#endif
601#endif //QT_NO_QWS_MULTIPROCESS 604#endif //QT_NO_QWS_MULTIPROCESS
602 605
603 delete [] args; 606 delete [] args;
604 return TRUE; 607 return TRUE;
605} 608}
606 609
607void AppLauncher::kill( int pid ) 610void AppLauncher::kill( int pid )
608{ 611{
609#ifndef Q_OS_WIN32 612#ifndef Q_OS_WIN32
610 ::kill( pid, SIGTERM ); 613 ::kill( pid, SIGTERM );
611#else 614#else
612 for ( QProcess *proc = runningAppsProc.first(); proc; proc = runningAppsProc.next() ) { 615 for ( QProcess *proc = runningAppsProc.first(); proc; proc = runningAppsProc.next() ) {
@@ -614,92 +617,98 @@ void AppLauncher::kill( int pid )
614 proc->kill(); 617 proc->kill();
615 break; 618 break;
616 } 619 }
617 } 620 }
618#endif 621#endif
619} 622}
620 623
621int AppLauncher::pidForName( const QString &appName ) 624int AppLauncher::pidForName( const QString &appName )
622{ 625{
623 int pid = -1; 626 int pid = -1;
624 627
625 QMap<int, QString>::Iterator it; 628 QMap<int, QString>::Iterator it;
626 for (it = runningApps.begin(); it!= runningApps.end(); ++it) { 629 for (it = runningApps.begin(); it!= runningApps.end(); ++it) {
627 if (*it == appName) { 630 if (*it == appName) {
628 pid = it.key(); 631 pid = it.key();
629 break; 632 break;
630 } 633 }
631 } 634 }
632 635
633 return pid; 636 return pid;
634} 637}
635 638
636void AppLauncher::createQuickLauncher() 639void AppLauncher::createQuickLauncher()
637{ 640{
641 static bool disabled = FALSE;
642 if (disabled)
643 return;
644
638 qlReady = FALSE; 645 qlReady = FALSE;
639 qlPid = ::vfork(); 646 qlPid = ::vfork();
640 if ( !qlPid ) { 647 if ( !qlPid ) {
641 char **args = new char *[2]; 648 char **args = new char *[2];
642 args[0] = "quicklauncher"; 649 args[0] = "quicklauncher";
643 args[1] = 0; 650 args[1] = 0;
644 for ( int fd = 3; fd < 100; fd++ ) 651 for ( int fd = 3; fd < 100; fd++ )
645 ::close( fd ); 652 ::close( fd );
646 ::setpgid( ::getpid(), ::getppid() ); 653 ::setpgid( ::getpid(), ::getppid() );
647 // Try bindir first, so that foo/bar works too 654 // Try bindir first, so that foo/bar works too
648 setenv( "LD_BIND_NOW", "1", 1 ); 655 setenv( "LD_BIND_NOW", "1", 1 );
649 ::execv( QPEApplication::qpeDir()+"bin/quicklauncher", args ); 656 ::execv( QPEApplication::qpeDir()+"bin/quicklauncher", args );
650 ::execvp( "quicklauncher", args ); 657 ::execvp( "quicklauncher", args );
658 delete []args;
659 disabled = TRUE;
651 _exit( -1 ); 660 _exit( -1 );
652 } else if ( qlPid == -1 ) { 661 } else if ( qlPid == -1 ) {
653 qlPid = 0; 662 qlPid = 0;
654 } else { 663 } else {
655 if ( getuid() == 0 ) 664 if ( getuid() == 0 )
656 setpriority( PRIO_PROCESS, qlPid, 19 ); 665 setpriority( PRIO_PROCESS, qlPid, 19 );
657 } 666 }
658} 667}
659 668
660// Used only by Win32 669// Used only by Win32
661void AppLauncher::processExited() 670void AppLauncher::processExited()
662{ 671{
663#ifdef Q_OS_WIN32 672#ifdef Q_OS_WIN32
664 qDebug("AppLauncher::processExited()"); 673 qDebug("AppLauncher::processExited()");
665 bool found = FALSE; 674 bool found = FALSE;
666 QProcess *proc = (QProcess *) sender(); 675 QProcess *proc = (QProcess *) sender();
667 if (!proc){ 676 if (!proc){
668 qDebug("Interanl error NULL proc"); 677 qDebug("Interanl error NULL proc");
669 return; 678 return;
670 } 679 }
671 680
672 QString appName = proc->arguments()[0]; 681 QString appName = proc->arguments()[0];
673 qDebug("Removing application %s", appName.latin1()); 682 qDebug("Removing application %s", appName.latin1());
674 runningAppsProc.remove(proc); 683 runningAppsProc.remove(proc);
675 684
676 QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName); 685 QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName);
677 if ( hbit != waitingHeartbeat.end() ) { 686 if ( hbit != waitingHeartbeat.end() ) {
678 killTimer( *hbit ); 687 killTimer( *hbit );
679 waitingHeartbeat.remove( hbit ); 688 waitingHeartbeat.remove( hbit );
680 } 689 }
681 if ( appName == appKillerName ) { 690 if ( appName == appKillerName ) {
682 appKillerName = QString::null; 691 appKillerName = QString::null;
683 delete appKillerBox; 692 delete appKillerBox;
684 appKillerBox = 0; 693 appKillerBox = 0;
685 } 694 }
686 695
687 // Search for the app to find its PID 696 // Search for the app to find its PID
688 QMap<int, QString>::Iterator it; 697 QMap<int, QString>::Iterator it;
689 for (it = runningApps.begin(); it!= runningApps.end(); ++it){ 698 for (it = runningApps.begin(); it!= runningApps.end(); ++it){
690 if (it.data() == appName){ 699 if (it.data() == appName){
691 found = TRUE; 700 found = TRUE;
692 break; 701 break;
693 } 702 }
694 } 703 }
695 704
696 if (found){ 705 if (found){
697 emit terminated(it.key(), it.data()); 706 emit terminated(it.key(), it.data());
698 runningApps.remove(it.key()); 707 runningApps.remove(it.key());
699 }else{ 708 }else{
700 qDebug("Internal error application %s not listed as running", appName.latin1()); 709 qDebug("Internal error application %s not listed as running", appName.latin1());
701 } 710 }
702 711
703#endif 712#endif
704} 713}
705 714