summaryrefslogtreecommitdiff
Unidiff
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
@@ -1,724 +1,724 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
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 <opie2/oglobal.h> 30#include <opie2/oglobal.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 64
65const int AppLauncher::RAISE_TIMEOUT_MS = 5000; 65const int AppLauncher::RAISE_TIMEOUT_MS = 5000;
66 66
67//--------------------------------------------------------------------------- 67//---------------------------------------------------------------------------
68 68
69static AppLauncher* appLauncherPtr; 69static AppLauncher* appLauncherPtr;
70 70
71const int appStopEventID = 1290; 71const int appStopEventID = 1290;
72 72
73class AppStoppedEvent : public QCustomEvent 73class AppStoppedEvent : public QCustomEvent
74{ 74{
75public: 75public:
76 AppStoppedEvent(int pid, int status) 76 AppStoppedEvent(int pid, int status)
77 : QCustomEvent( appStopEventID ), mPid(pid), mStatus(status) { } 77 : QCustomEvent( appStopEventID ), mPid(pid), mStatus(status) { }
78 78
79 int pid() { return mPid; } 79 int pid() { return mPid; }
80 int status() { return mStatus; } 80 int status() { return mStatus; }
81 81
82private: 82private:
83 int mPid, mStatus; 83 int mPid, mStatus;
84}; 84};
85 85
86AppLauncher::AppLauncher(QObject *parent, const char *name) 86AppLauncher::AppLauncher(QObject *parent, const char *name)
87 : QObject(parent, name), qlPid(0), qlReady(FALSE), 87 : QObject(parent, name), qlPid(0), qlReady(FALSE),
88 appKillerBox(0) 88 appKillerBox(0)
89{ 89{
90 connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&))); 90 connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&)));
91 connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&))); 91 connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&)));
92 QCopChannel* channel = new QCopChannel( "QPE/System", this ); 92 QCopChannel* channel = new QCopChannel( "QPE/System", this );
93 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), 93 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
94 this, SLOT(received(const QCString&, const QByteArray&)) ); 94 this, SLOT(received(const QCString&, const QByteArray&)) );
95 95
96 channel = new QCopChannel( "QPE/Server", this ); 96 channel = new QCopChannel( "QPE/Server", this );
97 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), 97 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
98 this, SLOT(received(const QCString&, const QByteArray&)) ); 98 this, SLOT(received(const QCString&, const QByteArray&)) );
99 99
100#ifndef Q_OS_WIN32 100#ifndef Q_OS_WIN32
101 signal(SIGCHLD, signalHandler); 101 signal(SIGCHLD, signalHandler);
102#else 102#else
103 runningAppsProc.setAutoDelete( TRUE ); 103 runningAppsProc.setAutoDelete( TRUE );
104#endif 104#endif
105 QString tmp = qApp->argv()[0]; 105 QString tmp = qApp->argv()[0];
106 int pos = tmp.findRev('/'); 106 int pos = tmp.findRev('/');
107 if ( pos > -1 ) 107 if ( pos > -1 )
108 tmp = tmp.mid(++pos); 108 tmp = tmp.mid(++pos);
109 runningApps[::getpid()] = tmp; 109 runningApps[::getpid()] = tmp;
110 110
111 appLauncherPtr = this; 111 appLauncherPtr = this;
112 112
113 QTimer::singleShot( 1000, this, SLOT(createQuickLauncher()) ); 113 QTimer::singleShot( 1000, this, SLOT(createQuickLauncher()) );
114} 114}
115 115
116AppLauncher::~AppLauncher() 116AppLauncher::~AppLauncher()
117{ 117{
118 appLauncherPtr = 0; 118 appLauncherPtr = 0;
119#ifndef Q_OS_WIN32 119#ifndef Q_OS_WIN32
120 signal(SIGCHLD, SIG_DFL); 120 signal(SIGCHLD, SIG_DFL);
121#endif 121#endif
122 if ( qlPid ) { 122 if ( qlPid ) {
123 int status; 123 int status;
124 ::kill( qlPid, SIGTERM ); 124 ::kill( qlPid, SIGTERM );
125 waitpid( qlPid, &status, 0 ); 125 waitpid( qlPid, &status, 0 );
126 } 126 }
127} 127}
128 128
129/* We use the QCopChannel of the app as an indicator of when it has been launched 129/* 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 */ 130 so that we can disable the busy indicators */
131void AppLauncher::newQcopChannel(const QString& channelName) 131void AppLauncher::newQcopChannel(const QString& channelName)
132{ 132{
133// qDebug("channel %s added", channelName.data() ); 133// qDebug("channel %s added", channelName.data() );
134 QString prefix("QPE/Application/"); 134 QString prefix("QPE/Application/");
135 if (channelName.startsWith(prefix)) { 135 if (channelName.startsWith(prefix)) {
136 { 136 {
137 QCopEnvelope e("QPE/System", "newChannel(QString)"); 137 QCopEnvelope e("QPE/System", "newChannel(QString)");
138 e << channelName; 138 e << channelName;
139 } 139 }
140 QString appName = channelName.mid(prefix.length()); 140 QString appName = channelName.mid(prefix.length());
141 if ( appName != "quicklauncher" ) { 141 if ( appName != "quicklauncher" ) {
142 emit connected( appName ); 142 emit connected( appName );
143 QCopEnvelope e("QPE/System", "notBusy(QString)"); 143 QCopEnvelope e("QPE/System", "notBusy(QString)");
144 e << appName; 144 e << appName;
145 } 145 }
146 } else if (channelName.startsWith("QPE/QuickLauncher-")) { 146 } else if (channelName.startsWith("QPE/QuickLauncher-")) {
147 qDebug("Registered %s", channelName.latin1()); 147 qDebug("Registered %s", channelName.latin1());
148 int pid = channelName.mid(18).toInt(); 148 int pid = channelName.mid(18).toInt();
149 if (pid == qlPid) 149 if (pid == qlPid)
150 qlReady = TRUE; 150 qlReady = TRUE;
151 } 151 }
152} 152}
153 153
154void AppLauncher::removedQcopChannel(const QString& channelName) 154void AppLauncher::removedQcopChannel(const QString& channelName)
155{ 155{
156 if (channelName.startsWith("QPE/Application/")) { 156 if (channelName.startsWith("QPE/Application/")) {
157 QCopEnvelope e("QPE/System", "removedChannel(QString)"); 157 QCopEnvelope e("QPE/System", "removedChannel(QString)");
158 e << channelName; 158 e << channelName;
159 } 159 }
160} 160}
161 161
162void AppLauncher::received(const QCString& msg, const QByteArray& data) 162void AppLauncher::received(const QCString& msg, const QByteArray& data)
163{ 163{
164 QDataStream stream( data, IO_ReadOnly ); 164 QDataStream stream( data, IO_ReadOnly );
165 if ( msg == "execute(QString)" ) { 165 if ( msg == "execute(QString)" ) {
166 QString t; 166 QString t;
167 stream >> t; 167 stream >> t;
168 if ( !executeBuiltin( t, QString::null ) ) 168 if ( !executeBuiltin( t, QString::null ) )
169 execute(t, QString::null); 169 execute(t, QString::null);
170 } else if ( msg == "execute(QString,QString)" ) { 170 } else if ( msg == "execute(QString,QString)" ) {
171 QString t,d; 171 QString t,d;
172 stream >> t >> d; 172 stream >> t >> d;
173 if ( !executeBuiltin( t, d ) ) 173 if ( !executeBuiltin( t, d ) )
174 execute( t, d ); 174 execute( t, d );
175 } else if ( msg == "processQCop(QString)" ) { // from QPE/Server 175 } else if ( msg == "processQCop(QString)" ) { // from QPE/Server
176 QString t; 176 QString t;
177 stream >> t; 177 stream >> t;
178 if ( !executeBuiltin( t, QString::null ) ) 178 if ( !executeBuiltin( t, QString::null ) )
179 execute( t, QString::null, TRUE); 179 execute( t, QString::null, TRUE);
180 } else if ( msg == "raise(QString)" ) { 180 } else if ( msg == "raise(QString)" ) {
181 QString appName; 181 QString appName;
182 stream >> appName; 182 stream >> appName;
183 183
184 if ( !executeBuiltin( appName, QString::null ) ) { 184 if ( !executeBuiltin( appName, QString::null ) ) {
185 if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) { 185 if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) {
186 //qDebug( "Raising: %s", appName.latin1() ); 186 //qDebug( "Raising: %s", appName.latin1() );
187 QCString channel = "QPE/Application/"; 187 QCString channel = "QPE/Application/";
188 channel += appName.latin1(); 188 channel += appName.latin1();
189 189
190 // Need to lock it to avoid race conditions with QPEApplication::processQCopFile 190 // Need to lock it to avoid race conditions with QPEApplication::processQCopFile
191 QFile f("/tmp/qcop-msg-" + appName); 191 QFile f("/tmp/qcop-msg-" + appName);
192 if ( f.open(IO_WriteOnly | IO_Append) ) { 192 if ( f.open(IO_WriteOnly | IO_Append) ) {
193#ifndef Q_OS_WIN32 193#ifndef Q_OS_WIN32
194 flock(f.handle(), LOCK_EX); 194 flock(f.handle(), LOCK_EX);
195#endif 195#endif
196 QDataStream ds(&f); 196 QDataStream ds(&f);
197 QByteArray b; 197 QByteArray b;
198 QDataStream bstream(b, IO_WriteOnly); 198 QDataStream bstream(b, IO_WriteOnly);
199 ds << channel << QCString("raise()") << b; 199 ds << channel << QCString("raise()") << b;
200 f.flush(); 200 f.flush();
201#ifndef Q_OS_WIN32 201#ifndef Q_OS_WIN32
202 flock(f.handle(), LOCK_UN); 202 flock(f.handle(), LOCK_UN);
203#endif 203#endif
204 f.close(); 204 f.close();
205 } 205 }
206 bool alreadyRunning = isRunning( appName ); 206 bool alreadyRunning = isRunning( appName );
207 if ( execute(appName, QString::null) ) { 207 if ( execute(appName, QString::null) ) {
208 int id = startTimer(RAISE_TIMEOUT_MS + alreadyRunning?2000:0); 208 int id = startTimer(RAISE_TIMEOUT_MS + alreadyRunning?2000:0);
209 waitingHeartbeat.insert( appName, id ); 209 waitingHeartbeat.insert( appName, id );
210 } 210 }
211 } 211 }
212 } 212 }
213 } else if ( msg == "sendRunningApps()" ) { 213 } else if ( msg == "sendRunningApps()" ) {
214 QStringList apps; 214 QStringList apps;
215 QMap<int,QString>::Iterator it; 215 QMap<int,QString>::Iterator it;
216 for( it = runningApps.begin(); it != runningApps.end(); ++it ) 216 for( it = runningApps.begin(); it != runningApps.end(); ++it )
217 apps.append( *it ); 217 apps.append( *it );
218 QCopEnvelope e( "QPE/Desktop", "runningApps(QStringList)" ); 218 QCopEnvelope e( "QPE/Desktop", "runningApps(QStringList)" );
219 e << apps; 219 e << apps;
220 } else if ( msg == "appRaised(QString)" ) { 220 } else if ( msg == "appRaised(QString)" ) {
221 QString appName; 221 QString appName;
222 stream >> appName; 222 stream >> appName;
223 qDebug("Got a heartbeat from %s", appName.latin1()); 223 qDebug("Got a heartbeat from %s", appName.latin1());
224 QMap<QString,int>::Iterator it = waitingHeartbeat.find(appName); 224 QMap<QString,int>::Iterator it = waitingHeartbeat.find(appName);
225 if ( it != waitingHeartbeat.end() ) { 225 if ( it != waitingHeartbeat.end() ) {
226 killTimer( *it ); 226 killTimer( *it );
227 waitingHeartbeat.remove(it); 227 waitingHeartbeat.remove(it);
228 } 228 }
229 // Check to make sure we're not waiting on user input... 229 // Check to make sure we're not waiting on user input...
230 if ( appKillerBox && appName == appKillerName ) { 230 if ( appKillerBox && appName == appKillerName ) {
231 // If we are, we kill the dialog box, and the code waiting on the result 231 // If we are, we kill the dialog box, and the code waiting on the result
232 // will clean us up (basically the user said "no"). 232 // will clean us up (basically the user said "no").
233 delete appKillerBox; 233 delete appKillerBox;
234 appKillerBox = 0; 234 appKillerBox = 0;
235 appKillerName = QString::null; 235 appKillerName = QString::null;
236 } 236 }
237 } 237 }
238} 238}
239 239
240void AppLauncher::signalHandler(int) 240void AppLauncher::signalHandler(int)
241{ 241{
242#ifndef Q_OS_WIN32 242#ifndef Q_OS_WIN32
243 int status; 243 int status;
244 pid_t pid = waitpid(-1, &status, WNOHANG); 244 pid_t pid = waitpid(-1, &status, WNOHANG);
245/* if (pid == 0 || &status == 0 ) { 245/* if (pid == 0 || &status == 0 ) {
246 qDebug("hmm, could not get return value from signal"); 246 qDebug("hmm, could not get return value from signal");
247 } 247 }
248*/ 248*/
249 QApplication::postEvent(appLauncherPtr, new AppStoppedEvent(pid, status) ); 249 QApplication::postEvent(appLauncherPtr, new AppStoppedEvent(pid, status) );
250#else 250#else
251 qDebug("Unhandled signal see by AppLauncher::signalHandler(int)"); 251 qDebug("Unhandled signal see by AppLauncher::signalHandler(int)");
252#endif 252#endif
253} 253}
254 254
255bool AppLauncher::event(QEvent *e) 255bool AppLauncher::event(QEvent *e)
256{ 256{
257 if ( e->type() == appStopEventID ) { 257 if ( e->type() == appStopEventID ) {
258 AppStoppedEvent *ae = (AppStoppedEvent *) e; 258 AppStoppedEvent *ae = (AppStoppedEvent *) e;
259 sigStopped(ae->pid(), ae->status() ); 259 sigStopped(ae->pid(), ae->status() );
260 return TRUE; 260 return TRUE;
261 } 261 }
262 262
263 return QObject::event(e); 263 return QObject::event(e);
264} 264}
265 265
266void AppLauncher::timerEvent( QTimerEvent *e ) 266void AppLauncher::timerEvent( QTimerEvent *e )
267{ 267{
268 int id = e->timerId(); 268 int id = e->timerId();
269 QMap<QString,int>::Iterator it; 269 QMap<QString,int>::Iterator it;
270 for ( it = waitingHeartbeat.begin(); it != waitingHeartbeat.end(); ++it ) { 270 for ( it = waitingHeartbeat.begin(); it != waitingHeartbeat.end(); ++it ) {
271 if ( *it == id ) { 271 if ( *it == id ) {
272 if ( appKillerBox ) // we're already dealing with one 272 if ( appKillerBox ) // we're already dealing with one
273 return; 273 return;
274 274
275 appKillerName = it.key(); 275 appKillerName = it.key();
276 killTimer( id ); 276 killTimer( id );
277 waitingHeartbeat.remove( it ); 277 waitingHeartbeat.remove( it );
278 278
279 // qDebug("Checking in on %s", appKillerName.latin1()); 279 // qDebug("Checking in on %s", appKillerName.latin1());
280 280
281 // We store this incase the application responds while we're 281 // We store this incase the application responds while we're
282 // waiting for user input so we know not to delete ourselves. 282 // waiting for user input so we know not to delete ourselves.
283 appKillerBox = new QMessageBox(tr("Application Problem"), 283 appKillerBox = new QMessageBox(tr("Application Problem"),
284 tr("<p>%1 is not responding.</p>").arg(appKillerName) + 284 tr("<p>%1 is not responding.</p>").arg(appKillerName) +
285 tr("<p>Would you like to force the application to exit?</p>"), 285 tr("<p>Would you like to force the application to exit?</p>"),
286 QMessageBox::Warning, QMessageBox::Yes, 286 QMessageBox::Warning, QMessageBox::Yes,
287 QMessageBox::No | QMessageBox::Default, 287 QMessageBox::No | QMessageBox::Default,
288 QMessageBox::NoButton); 288 QMessageBox::NoButton);
289 if (appKillerBox->exec() == QMessageBox::Yes) { 289 if (appKillerBox->exec() == QMessageBox::Yes) {
290 // qDebug("Killing the app!!! Bwuhahahaha!"); 290 // qDebug("Killing the app!!! Bwuhahahaha!");
291 int pid = pidForName(appKillerName); 291 int pid = pidForName(appKillerName);
292 if ( pid > 0 ) 292 if ( pid > 0 )
293 kill( pid ); 293 kill( pid );
294 } 294 }
295 appKillerName = QString::null; 295 appKillerName = QString::null;
296 delete appKillerBox; 296 delete appKillerBox;
297 appKillerBox = 0; 297 appKillerBox = 0;
298 return; 298 return;
299 } 299 }
300 } 300 }
301 301
302 QObject::timerEvent( e ); 302 QObject::timerEvent( e );
303} 303}
304 304
305#ifndef Q_OS_WIN32 305#ifndef Q_OS_WIN32
306void AppLauncher::sigStopped(int sigPid, int sigStatus) 306void AppLauncher::sigStopped(int sigPid, int sigStatus)
307{ 307{
308 int exitStatus = 0; 308 int exitStatus = 0;
309 309
310 bool crashed = WIFSIGNALED(sigStatus); 310 bool crashed = WIFSIGNALED(sigStatus);
311 if ( !crashed ) { 311 if ( !crashed ) {
312 if ( WIFEXITED(sigStatus) ) 312 if ( WIFEXITED(sigStatus) )
313 exitStatus = WEXITSTATUS(sigStatus); 313 exitStatus = WEXITSTATUS(sigStatus);
314 } else { 314 } else {
315 exitStatus = WTERMSIG(sigStatus); 315 exitStatus = WTERMSIG(sigStatus);
316 } 316 }
317 317
318 QMap<int,QString>::Iterator it = runningApps.find( sigPid ); 318 QMap<int,QString>::Iterator it = runningApps.find( sigPid );
319 if ( it == runningApps.end() ) { 319 if ( it == runningApps.end() ) {
320 if ( sigPid == qlPid ) { 320 if ( sigPid == qlPid ) {
321 qDebug( "quicklauncher stopped" ); 321 qDebug( "quicklauncher stopped" );
322 qlPid = 0; 322 qlPid = 0;
323 qlReady = FALSE; 323 qlReady = FALSE;
324 QFile::remove("/tmp/qcop-msg-quicklauncher" ); 324 QFile::remove("/tmp/qcop-msg-quicklauncher" );
325 QTimer::singleShot( 2000, this, SLOT(createQuickLauncher()) ); 325 QTimer::singleShot( 2000, this, SLOT(createQuickLauncher()) );
326 } 326 }
327/* 327/*
328 if ( sigPid == -1 ) 328 if ( sigPid == -1 )
329 qDebug("non-qtopia application exited (disregarded)"); 329 qDebug("non-qtopia application exited (disregarded)");
330 else 330 else
331 qDebug("==== no pid matching %d in list, definite bug", sigPid); 331 qDebug("==== no pid matching %d in list, definite bug", sigPid);
332*/ 332*/
333 return; 333 return;
334 } 334 }
335 QString appName = *it; 335 QString appName = *it;
336 runningApps.remove(it); 336 runningApps.remove(it);
337 337
338 QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName); 338 QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName);
339 if ( hbit != waitingHeartbeat.end() ) { 339 if ( hbit != waitingHeartbeat.end() ) {
340 killTimer( *hbit ); 340 killTimer( *hbit );
341 waitingHeartbeat.remove( hbit ); 341 waitingHeartbeat.remove( hbit );
342 } 342 }
343 if ( appName == appKillerName ) { 343 if ( appName == appKillerName ) {
344 appKillerName = QString::null; 344 appKillerName = QString::null;
345 delete appKillerBox; 345 delete appKillerBox;
346 appKillerBox = 0; 346 appKillerBox = 0;
347 } 347 }
348 348
349 /* we must disable preload for an app that crashes as the system logic relies on preloaded apps 349 /* 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 350 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) 351 the app (withouth some timeout value for eg. 3 tries (which I think is a bad solution)
352 */ 352 */
353 bool preloadDisabled = FALSE; 353 bool preloadDisabled = FALSE;
354 if ( !DocumentList::appLnkSet ) return; 354 if ( !DocumentList::appLnkSet ) return;
355 const AppLnk* app = DocumentList::appLnkSet->findExec( appName ); 355 const AppLnk* app = DocumentList::appLnkSet->findExec( appName );
356 if ( !app ) return; // QCop messages processed to slow? 356 if ( !app ) return; // QCop messages processed to slow?
357 if ( crashed && app->isPreloaded() ) { 357 if ( crashed && app->isPreloaded() ) {
358 Config cfg("Launcher"); 358 Config cfg("Launcher");
359 cfg.setGroup("Preload"); 359 cfg.setGroup("Preload");
360 QStringList apps = cfg.readListEntry("Apps",','); 360 QStringList apps = cfg.readListEntry("Apps",',');
361 QString exe = app->exec(); 361 QString exe = app->exec();
362 apps.remove(exe); 362 apps.remove(exe);
363 cfg.writeEntry("Apps",apps,','); 363 cfg.writeEntry("Apps",apps,',');
364 preloadDisabled = TRUE; 364 preloadDisabled = TRUE;
365 } 365 }
366 366
367 // clean up 367 // clean up
368 if ( exitStatus ) { 368 if ( exitStatus ) {
369 QCopEnvelope e("QPE/System", "notBusy(QString)"); 369 QCopEnvelope e("QPE/System", "notBusy(QString)");
370 e << app->exec(); 370 e << app->exec();
371 } 371 }
372/* 372/*
373 // debug info 373 // debug info
374 for (it = runningApps.begin(); it != runningApps.end(); ++it) { 374 for (it = runningApps.begin(); it != runningApps.end(); ++it) {
375 qDebug("running according to internal list: %s, with pid %d", (*it).data(), it.key() ); 375 qDebug("running according to internal list: %s, with pid %d", (*it).data(), it.key() );
376 } 376 }
377*/ 377*/
378 378
379#ifdef QTOPIA_PROGRAM_MONITOR 379#ifdef QTOPIA_PROGRAM_MONITOR
380 if ( crashed ) { 380 if ( crashed ) {
381 QString sig; 381 QString sig;
382 switch( exitStatus ) { 382 switch( exitStatus ) {
383 case SIGABRT: sig = "SIGABRT"; break; 383 case SIGABRT: sig = "SIGABRT"; break;
384 case SIGALRM: sig = "SIGALRM"; break; 384 case SIGALRM: sig = "SIGALRM"; break;
385 case SIGBUS: sig = "SIGBUS"; break; 385 case SIGBUS: sig = "SIGBUS"; break;
386 case SIGFPE: sig = "SIGFPE"; break; 386 case SIGFPE: sig = "SIGFPE"; break;
387 case SIGHUP: sig = "SIGHUP"; break; 387 case SIGHUP: sig = "SIGHUP"; break;
388 case SIGILL: sig = "SIGILL"; break; 388 case SIGILL: sig = "SIGILL"; break;
389 case SIGKILL: sig = "SIGKILL"; break; 389 case SIGKILL: sig = "SIGKILL"; break;
390 case SIGPIPE: sig = "SIGPIPE"; break; 390 case SIGPIPE: sig = "SIGPIPE"; break;
391 case SIGQUIT: sig = "SIGQUIT"; break; 391 case SIGQUIT: sig = "SIGQUIT"; break;
392 case SIGSEGV: sig = "SIGSEGV"; break; 392 case SIGSEGV: sig = "SIGSEGV"; break;
393 case SIGTERM: sig = "SIGTERM"; break; 393 case SIGTERM: sig = "SIGTERM"; break;
394 case SIGTRAP: sig = "SIGTRAP"; break; 394 case SIGTRAP: sig = "SIGTRAP"; break;
395 default: sig = QString("Unkown %1").arg(exitStatus); 395 default: sig = QString("Unkown %1").arg(exitStatus);
396 } 396 }
397 if ( preloadDisabled ) 397 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>"); 398 sig += tr("<qt><p>Fast loading has been disabled for this application. Tap and hold the application icon to reenable it.</qt>");
399 399
400 QString str = tr("<qt><b>%1</b> was terminated due to signal code %2</qt>").arg( app->name() ).arg( sig ); 400 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 ); 401 QMessageBox::information(0, tr("Application terminated"), str );
402 } else { 402 } else {
403 if ( exitStatus == 255 ) { //could not find app (because global returns -1) 403 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() ) ); 404 QMessageBox::information(0, tr("Application not found"), tr("<qt>Could not locate application <b>%1</b></qt>").arg( app->exec() ) );
405 } else { 405 } else {
406 QFileInfo fi(QString::fromLatin1("/tmp/qcop-msg-") + appName); 406 QFileInfo fi(QString::fromLatin1("/tmp/qcop-msg-") + appName);
407 if ( fi.exists() && fi.size() ) { 407 if ( fi.exists() && fi.size() ) {
408 emit terminated(sigPid, appName); 408 emit terminated(sigPid, appName);
409 qWarning("Re executing obmitted for %s", appName.latin1() ); 409 qWarning("Re executing obmitted for %s", appName.latin1() );
410 // execute( appName, QString::null ); 410 // execute( appName, QString::null );
411 return; 411 return;
412 } 412 }
413 } 413 }
414 } 414 }
415 415
416#endif 416#endif
417 417
418 emit terminated(sigPid, appName); 418 emit terminated(sigPid, appName);
419} 419}
420#else 420#else
421void AppLauncher::sigStopped(int sigPid, int sigStatus) 421void AppLauncher::sigStopped(int sigPid, int sigStatus)
422{ 422{
423 qDebug("Unhandled signal : AppLauncher::sigStopped(int sigPid, int sigStatus)"); 423 qDebug("Unhandled signal : AppLauncher::sigStopped(int sigPid, int sigStatus)");
424} 424}
425#endif // Q_OS_WIN32 425#endif // Q_OS_WIN32
426 426
427bool AppLauncher::isRunning(const QString &app) 427bool AppLauncher::isRunning(const QString &app)
428{ 428{
429 for (QMap<int,QString>::ConstIterator it = runningApps.begin(); it != runningApps.end(); ++it) { 429 for (QMap<int,QString>::ConstIterator it = runningApps.begin(); it != runningApps.end(); ++it) {
430 if ( *it == app ) { 430 if ( *it == app ) {
431#ifdef Q_OS_UNIX 431#ifdef Q_OS_UNIX
432 pid_t t = ::__getpgid( it.key() ); 432 pid_t t = ::__getpgid( it.key() );
433 if ( t == -1 ) { 433 if ( t == -1 ) {
434 qDebug("appLauncher bug, %s believed running, but pid %d is not existing", app.data(), it.key() ); 434 qDebug("appLauncher bug, %s believed running, but pid %d is not existing", app.data(), it.key() );
435 runningApps.remove( it.key() ); 435 runningApps.remove( it.key() );
436 return FALSE; 436 return FALSE;
437 } 437 }
438#endif 438#endif
439 return TRUE; 439 return TRUE;
440 } 440 }
441 } 441 }
442 442
443 return FALSE; 443 return FALSE;
444} 444}
445 445
446bool AppLauncher::executeBuiltin(const QString &c, const QString &document) 446bool AppLauncher::executeBuiltin(const QString &c, const QString &document)
447{ 447{
448 Global::Command* builtin = OGlobal::builtinCommands(); 448 Global::Command* builtin = OGlobal::builtinCommands();
449 QGuardedPtr<QWidget> *running = OGlobal::builtinRunning(); 449 QGuardedPtr<QWidget> *running = OGlobal::builtinRunning();
450 450
451 // Attempt to execute the app using a builtin class for the app 451 // Attempt to execute the app using a builtin class for the app
452 if (builtin) { 452 if (builtin) {
453 for (int i = 0; builtin[i].file; i++) { 453 for (int i = 0; builtin[i].file; i++) {
454 if ( builtin[i].file == c ) { 454 if ( builtin[i].file == c ) {
455 if ( running[i] ) { 455 if ( running[i] ) {
456 if ( !document.isNull() && builtin[i].documentary ) 456 if ( !document.isNull() && builtin[i].documentary )
457 Global::setDocument(running[i], document); 457 Global::setDocument(running[i], document);
458 running[i]->raise(); 458 running[i]->raise();
459 running[i]->show(); 459 running[i]->show();
460 running[i]->setActiveWindow(); 460 running[i]->setActiveWindow();
461 } else { 461 } else {
462 running[i] = builtin[i].func( builtin[i].maximized ); 462 running[i] = builtin[i].func( builtin[i].maximized );
463 } 463 }
464#ifndef QT_NO_COP 464#ifndef QT_NO_COP
465 QCopEnvelope e("QPE/System", "notBusy(QString)" ); 465 QCopEnvelope e("QPE/System", "notBusy(QString)" );
466 e << c; // that was quick ;-) 466 e << c; // that was quick ;-)
467#endif 467#endif
468 return TRUE; 468 return TRUE;
469 } 469 }
470 } 470 }
471 } 471 }
472 472
473 // Convert the command line in to a list of arguments 473 // Convert the command line in to a list of arguments
474 QStringList list = QStringList::split(QRegExp(" *"),c); 474 QStringList list = QStringList::split(QRegExp(" *"),c);
475 QString ap=list[0]; 475 QString ap=list[0];
476 476
477 if ( ap == "suspend" ) { // No tr 477 if ( ap == "suspend" ) { // No tr
478 QWSServer::processKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); 478 QWSServer::processKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE );
479 return TRUE; 479 return TRUE;
480 } 480 }
481 481
482 return FALSE; 482 return FALSE;
483} 483}
484 484
485bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise) 485bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise)
486{ 486{
487 qWarning("AppLauncher::execute"); 487 qWarning("AppLauncher::execute '%s' '%s'", (const char*) c, (const char*) docParam );
488 // Convert the command line in to a list of arguments 488 // Convert the command line in to a list of arguments
489 QStringList list = QStringList::split(QRegExp(" *"),c); 489 QStringList list = QStringList::split(QRegExp(" *"),c);
490 if ( !docParam.isEmpty() ) 490 if ( !docParam.isEmpty() )
491 list.append( docParam ); 491 list.append( docParam );
492 492
493 QString appName = list[0]; 493 QString appName = list[0];
494 if ( isRunning(appName) ) { 494 if ( isRunning(appName) ) {
495 QCString channel = "QPE/Application/"; 495 QCString channel = "QPE/Application/";
496 channel += appName.latin1(); 496 channel += appName.latin1();
497 497
498 // Need to lock it to avoid race conditions with QPEApplication::processQCopFile 498 // Need to lock it to avoid race conditions with QPEApplication::processQCopFile
499 QFile f(QString::fromLatin1("/tmp/qcop-msg-") + appName); 499 QFile f(QString::fromLatin1("/tmp/qcop-msg-") + appName);
500 if ( !noRaise && f.open(IO_WriteOnly | IO_Append) ) { 500 if ( !noRaise && f.open(IO_WriteOnly | IO_Append) ) {
501#ifndef Q_OS_WIN32 501#ifndef Q_OS_WIN32
502 flock(f.handle(), LOCK_EX); 502 flock(f.handle(), LOCK_EX);
503#endif 503#endif
504 504
505 QDataStream ds(&f); 505 QDataStream ds(&f);
506 QByteArray b; 506 QByteArray b;
507 QDataStream bstream(b, IO_WriteOnly); 507 QDataStream bstream(b, IO_WriteOnly);
508 if ( !f.size() ) { 508 if ( !f.size() ) {
509 ds << channel << QCString("raise()") << b; 509 ds << channel << QCString("raise()") << b;
510 if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) { 510 if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) {
511 int id = startTimer(RAISE_TIMEOUT_MS); 511 int id = startTimer(RAISE_TIMEOUT_MS);
512 waitingHeartbeat.insert( appName, id ); 512 waitingHeartbeat.insert( appName, id );
513 } 513 }
514 } 514 }
515 if ( !docParam.isEmpty() ) { 515 if ( !docParam.isEmpty() ) {
516 bstream << docParam; 516 bstream << docParam;
517 ds << channel << QCString("setDocument(QString)") << b; 517 ds << channel << QCString("setDocument(QString)") << b;
518 } 518 }
519 519
520 f.flush(); 520 f.flush();
521#ifndef Q_OS_WIN32 521#ifndef Q_OS_WIN32
522 flock(f.handle(), LOCK_UN); 522 flock(f.handle(), LOCK_UN);
523#endif 523#endif
524 f.close(); 524 f.close();
525 } 525 }
526 if ( QCopChannel::isRegistered(channel) ) // avoid unnecessary warnings 526 if ( QCopChannel::isRegistered(channel) ) // avoid unnecessary warnings
527 QCopChannel::send(channel,"QPEProcessQCop()"); 527 QCopChannel::send(channel,"QPEProcessQCop()");
528 528
529 return TRUE; 529 return TRUE;
530 } 530 }
531 531
532#ifdef QT_NO_QWS_MULTIPROCESS 532#ifdef QT_NO_QWS_MULTIPROCESS
533 QMessageBox::warning( 0, tr("Error"), tr("<qt>Could not find the application %1</qt>").arg(c), 533 QMessageBox::warning( 0, tr("Error"), tr("<qt>Could not find the application %1</qt>").arg(c),
534 tr("OK"), 0, 0, 0, 1 ); 534 tr("OK"), 0, 0, 0, 1 );
535#else 535#else
536 536
537 QStrList slist; 537 QStrList slist;
538 unsigned j; 538 unsigned j;
539 for ( j = 0; j < list.count(); j++ ) 539 for ( j = 0; j < list.count(); j++ )
540 slist.append( list[j].utf8() ); 540 slist.append( list[j].utf8() );
541 541
542 const char **args = new const char *[slist.count() + 1]; 542 const char **args = new const char *[slist.count() + 1];
543 for ( j = 0; j < slist.count(); j++ ) 543 for ( j = 0; j < slist.count(); j++ )
544 args[j] = slist.at(j); 544 args[j] = slist.at(j);
545 args[j] = NULL; 545 args[j] = NULL;
546 546
547#ifndef Q_OS_WIN32 547#ifndef Q_OS_WIN32
548#ifdef Q_OS_MACX 548#ifdef Q_OS_MACX
549 if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".dylib" ) ) { 549 if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".dylib" ) ) {
550#else 550#else
551 if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".so" ) ) { 551 if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".so" ) ) {
552#endif /* Q_OS_MACX */ 552#endif /* Q_OS_MACX */
553 qDebug( "Quick launching: %s", args[0] ); 553 qDebug( "Quick launching: %s", args[0] );
554 if ( getuid() == 0 ) 554 if ( getuid() == 0 )
555 setpriority( PRIO_PROCESS, qlPid, 0 ); 555 setpriority( PRIO_PROCESS, qlPid, 0 );
556 QCString qlch("QPE/QuickLauncher-"); 556 QCString qlch("QPE/QuickLauncher-");
557 qlch += QString::number(qlPid); 557 qlch += QString::number(qlPid);
558 QCopEnvelope env( qlch, "execute(QStrList)" ); 558 QCopEnvelope env( qlch, "execute(QStrList)" );
559 env << slist; 559 env << slist;
560 runningApps[qlPid] = QString(args[0]); 560 runningApps[qlPid] = QString(args[0]);
561 emit launched(qlPid, QString(args[0])); 561 emit launched(qlPid, QString(args[0]));
562 QCopEnvelope e("QPE/System", "busy()"); 562 QCopEnvelope e("QPE/System", "busy()");
563 qlPid = 0; 563 qlPid = 0;
564 qlReady = FALSE; 564 qlReady = FALSE;
565 QTimer::singleShot( getuid() == 0 ? 800 : 1500, this, SLOT(createQuickLauncher()) ); 565 QTimer::singleShot( getuid() == 0 ? 800 : 1500, this, SLOT(createQuickLauncher()) );
566 } else { 566 } else {
567 int pid = ::vfork(); 567 int pid = ::vfork();
568 if ( !pid ) { 568 if ( !pid ) {
569 for ( int fd = 3; fd < 100; fd++ ) 569 for ( int fd = 3; fd < 100; fd++ )
570 ::close( fd ); 570 ::close( fd );
571 ::setpgid( ::getpid(), ::getppid() ); 571 ::setpgid( ::getpid(), ::getppid() );
572 // Try bindir first, so that foo/bar works too 572 // Try bindir first, so that foo/bar works too
573 ::execv( QPEApplication::qpeDir()+"bin/"+args[0], (char * const *)args ); 573 ::execv( QPEApplication::qpeDir()+"bin/"+args[0], (char * const *)args );
574 ::execvp( args[0], (char * const *)args ); 574 ::execvp( args[0], (char * const *)args );
575 _exit( -1 ); 575 _exit( -1 );
576 } 576 }
577 577
578 runningApps[pid] = QString(args[0]); 578 runningApps[pid] = QString(args[0]);
579 emit launched(pid, QString(args[0])); 579 emit launched(pid, QString(args[0]));
580 QCopEnvelope e("QPE/System", "busy()"); 580 QCopEnvelope e("QPE/System", "busy()");
581 } 581 }
582#else 582#else
583 QProcess *proc = new QProcess(this); 583 QProcess *proc = new QProcess(this);
584 if (proc){ 584 if (proc){
585 for (int i=0; i < slist.count(); i++) 585 for (int i=0; i < slist.count(); i++)
586 proc->addArgument(args[i]); 586 proc->addArgument(args[i]);
587 connect(proc, SIGNAL(processExited()), this, SLOT(processExited())); 587 connect(proc, SIGNAL(processExited()), this, SLOT(processExited()));
588 if (!proc->start()){ 588 if (!proc->start()){
589 qDebug("Unable to start application %s", args[0]); 589 qDebug("Unable to start application %s", args[0]);
590 }else{ 590 }else{
591 PROCESS_INFORMATION *procInfo = (PROCESS_INFORMATION *)proc->processIdentifier(); 591 PROCESS_INFORMATION *procInfo = (PROCESS_INFORMATION *)proc->processIdentifier();
592 if (procInfo){ 592 if (procInfo){
593 DWORD pid = procInfo->dwProcessId; 593 DWORD pid = procInfo->dwProcessId;
594 runningApps[pid] = QString(args[0]); 594 runningApps[pid] = QString(args[0]);
595 runningAppsProc.append(proc); 595 runningAppsProc.append(proc);
596 emit launched(pid, QString(args[0])); 596 emit launched(pid, QString(args[0]));
597 QCopEnvelope e("QPE/System", "busy()"); 597 QCopEnvelope e("QPE/System", "busy()");
598 }else{ 598 }else{
599 qDebug("Unable to read process inforation #1 for %s", args[0]); 599 qDebug("Unable to read process inforation #1 for %s", args[0]);
600 } 600 }
601 } 601 }
602 }else{ 602 }else{
603 qDebug("Unable to create process for application %s", args[0]); 603 qDebug("Unable to create process for application %s", args[0]);
604 return FALSE; 604 return FALSE;
605 } 605 }
606#endif 606#endif
607#endif //QT_NO_QWS_MULTIPROCESS 607#endif //QT_NO_QWS_MULTIPROCESS
608 608
609 delete [] args; 609 delete [] args;
610 return TRUE; 610 return TRUE;
611} 611}
612 612
613void AppLauncher::kill( int pid ) 613void AppLauncher::kill( int pid )
614{ 614{
615#ifndef Q_OS_WIN32 615#ifndef Q_OS_WIN32
616 ::kill( pid, SIGTERM ); 616 ::kill( pid, SIGTERM );
617#else 617#else
618 for ( QProcess *proc = runningAppsProc.first(); proc; proc = runningAppsProc.next() ) { 618 for ( QProcess *proc = runningAppsProc.first(); proc; proc = runningAppsProc.next() ) {
619 if ( proc->processIdentifier() == pid ) { 619 if ( proc->processIdentifier() == pid ) {
620 proc->kill(); 620 proc->kill();
621 break; 621 break;
622 } 622 }
623 } 623 }
624#endif 624#endif
625} 625}
626 626
627int AppLauncher::pidForName( const QString &appName ) 627int AppLauncher::pidForName( const QString &appName )
628{ 628{
629 int pid = -1; 629 int pid = -1;
630 630
631 QMap<int, QString>::Iterator it; 631 QMap<int, QString>::Iterator it;
632 for (it = runningApps.begin(); it!= runningApps.end(); ++it) { 632 for (it = runningApps.begin(); it!= runningApps.end(); ++it) {
633 if (*it == appName) { 633 if (*it == appName) {
634 pid = it.key(); 634 pid = it.key();
635 break; 635 break;
636 } 636 }
637 } 637 }
638 638
639 return pid; 639 return pid;
640} 640}
641 641
642void AppLauncher::createQuickLauncher() 642void AppLauncher::createQuickLauncher()
643{ 643{
644 static bool disabled = FALSE; 644 static bool disabled = FALSE;
645 if (disabled) 645 if (disabled)
646 return; 646 return;
647 647
648 qlReady = FALSE; 648 qlReady = FALSE;
649 qlPid = ::vfork(); 649 qlPid = ::vfork();
650 if ( !qlPid ) { 650 if ( !qlPid ) {
651 char **args = new char *[2]; 651 char **args = new char *[2];
652 args[0] = "quicklauncher"; 652 args[0] = "quicklauncher";
653 args[1] = 0; 653 args[1] = 0;
654 for ( int fd = 3; fd < 100; fd++ ) 654 for ( int fd = 3; fd < 100; fd++ )
655 ::close( fd ); 655 ::close( fd );
656 ::setpgid( ::getpid(), ::getppid() ); 656 ::setpgid( ::getpid(), ::getppid() );
657 // Try bindir first, so that foo/bar works too 657 // Try bindir first, so that foo/bar works too
658 /* 658 /*
659 * LD_BIND_NOW will change the behaviour of ld.so and dlopen 659 * LD_BIND_NOW will change the behaviour of ld.so and dlopen
660 * RTLD_LAZY will be made RTLD_NOW which leads to problem 660 * RTLD_LAZY will be made RTLD_NOW which leads to problem
661 * with miscompiled libraries... if LD_BIND_NOW is set.. there 661 * with miscompiled libraries... if LD_BIND_NOW is set.. there
662 * is no way back.. We will wait for numbers from TT to see 662 * is no way back.. We will wait for numbers from TT to see
663 * if using LD_BIND_NOW is worth it - zecke 663 * if using LD_BIND_NOW is worth it - zecke
664 */ 664 */
665 //setenv( "LD_BIND_NOW", "1", 1 ); 665 //setenv( "LD_BIND_NOW", "1", 1 );
666 ::execv( QPEApplication::qpeDir()+"bin/quicklauncher", args ); 666 ::execv( QPEApplication::qpeDir()+"bin/quicklauncher", args );
667 ::execvp( "quicklauncher", args ); 667 ::execvp( "quicklauncher", args );
668 delete []args; 668 delete []args;
669 disabled = TRUE; 669 disabled = TRUE;
670 _exit( -1 ); 670 _exit( -1 );
671 } else if ( qlPid == -1 ) { 671 } else if ( qlPid == -1 ) {
672 qlPid = 0; 672 qlPid = 0;
673 } else { 673 } else {
674 if ( getuid() == 0 ) 674 if ( getuid() == 0 )
675 setpriority( PRIO_PROCESS, qlPid, 19 ); 675 setpriority( PRIO_PROCESS, qlPid, 19 );
676 } 676 }
677} 677}
678 678
679// Used only by Win32 679// Used only by Win32
680void AppLauncher::processExited() 680void AppLauncher::processExited()
681{ 681{
682#ifdef Q_OS_WIN32 682#ifdef Q_OS_WIN32
683 qDebug("AppLauncher::processExited()"); 683 qDebug("AppLauncher::processExited()");
684 bool found = FALSE; 684 bool found = FALSE;
685 QProcess *proc = (QProcess *) sender(); 685 QProcess *proc = (QProcess *) sender();
686 if (!proc){ 686 if (!proc){
687 qDebug("Interanl error NULL proc"); 687 qDebug("Interanl error NULL proc");
688 return; 688 return;
689 } 689 }
690 690
691 QString appName = proc->arguments()[0]; 691 QString appName = proc->arguments()[0];
692 qDebug("Removing application %s", appName.latin1()); 692 qDebug("Removing application %s", appName.latin1());
693 runningAppsProc.remove(proc); 693 runningAppsProc.remove(proc);
694 694
695 QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName); 695 QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName);
696 if ( hbit != waitingHeartbeat.end() ) { 696 if ( hbit != waitingHeartbeat.end() ) {
697 killTimer( *hbit ); 697 killTimer( *hbit );
698 waitingHeartbeat.remove( hbit ); 698 waitingHeartbeat.remove( hbit );
699 } 699 }
700 if ( appName == appKillerName ) { 700 if ( appName == appKillerName ) {
701 appKillerName = QString::null; 701 appKillerName = QString::null;
702 delete appKillerBox; 702 delete appKillerBox;
703 appKillerBox = 0; 703 appKillerBox = 0;
704 } 704 }
705 705
706 // Search for the app to find its PID 706 // Search for the app to find its PID
707 QMap<int, QString>::Iterator it; 707 QMap<int, QString>::Iterator it;
708 for (it = runningApps.begin(); it!= runningApps.end(); ++it){ 708 for (it = runningApps.begin(); it!= runningApps.end(); ++it){
709 if (it.data() == appName){ 709 if (it.data() == appName){
710 found = TRUE; 710 found = TRUE;
711 break; 711 break;
712 } 712 }
713 } 713 }
714 714
715 if (found){ 715 if (found){
716 emit terminated(it.key(), it.data()); 716 emit terminated(it.key(), it.data());
717 runningApps.remove(it.key()); 717 runningApps.remove(it.key());
718 }else{ 718 }else{
719 qDebug("Internal error application %s not listed as running", appName.latin1()); 719 qDebug("Internal error application %s not listed as running", appName.latin1());
720 } 720 }
721 721
722#endif 722#endif
723} 723}
724 724