summaryrefslogtreecommitdiff
authorzecke <zecke>2003-12-20 13:06:29 (UTC)
committer zecke <zecke>2003-12-20 13:06:29 (UTC)
commitd9ffcee06ec97f4a9e00ff0a9071d7a58e5075a1 (patch) (unidiff)
tree1d808cf09131926e6ab6a00e75d9b92182c49365
parentafabf4e4cb1211dd17e0ba0ff77133335d4735b9 (diff)
downloadopie-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...
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/applauncher.cpp9
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
155void AppLauncher::removedQcopChannel(const QString& channelName) 155void 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
163void AppLauncher::received(const QCString& msg, const QByteArray& data) 163void 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
241void AppLauncher::signalHandler(int) 241void 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
256bool AppLauncher::event(QEvent *e) 256bool 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
267void AppLauncher::timerEvent( QTimerEvent *e ) 267void 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
307void AppLauncher::sigStopped(int sigPid, int sigStatus) 307void 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
422void AppLauncher::sigStopped(int sigPid, int sigStatus) 422void 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
428bool AppLauncher::isRunning(const QString &app) 428bool 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
447bool AppLauncher::executeBuiltin(const QString &c, const QString &document) 447bool 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
486bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise) 486bool 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
614void AppLauncher::kill( int pid ) 614void 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
628int AppLauncher::pidForName( const QString &appName ) 628int 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
643void AppLauncher::createQuickLauncher() 643void 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
674void AppLauncher::processExited() 681void 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