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