summaryrefslogtreecommitdiff
authorkergoth <kergoth>2003-03-14 19:22:43 (UTC)
committer kergoth <kergoth>2003-03-14 19:22:43 (UTC)
commit4f483f13e3c624a0ce6161e6ddd6923b4d101f0e (patch) (side-by-side diff)
tree40598ac7ae56246fd2875967345f6eccb13339b7
parent52c72efc3bcc6b57c6960b5da3393b57182b5ee6 (diff)
downloadopie-4f483f13e3c624a0ce6161e6ddd6923b4d101f0e.zip
opie-4f483f13e3c624a0ce6161e6ddd6923b4d101f0e.tar.gz
opie-4f483f13e3c624a0ce6161e6ddd6923b4d101f0e.tar.bz2
Two bugs fixed:
1) We werent checking for failure on execlp() of shutdown 2) We assumed that /sbin was in the PATH, as otherwise one cannot execute shutdown. This is a flawed assumption, particularly in the case of running Opie as a nonroot user. In the case of OZ 3.1rc3.1, /etc/profile no longer puts the sbin dirs in the PATH (it never should have in the first place), and opie doesnt source $HOME/.profile in its startup script, which resulted in the shutdown app failing to reboot or shutdown. Fixed by using execle rather than execlp, and specifying /sbin and /usr/sbin as the executed path for shutdown.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/desktop.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp
index 03a23dc..4c239a6 100644
--- a/core/launcher/desktop.cpp
+++ b/core/launcher/desktop.cpp
@@ -1,84 +1,86 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
+#include <syslog.h>
+
#include "desktop.h"
#include "info.h"
#include "launcher.h"
#include "qcopbridge.h"
#include "shutdownimpl.h"
#include "startmenu.h"
#include "taskbar.h"
#include "transferserver.h"
#include "irserver.h"
#include "packageslave.h"
#include "screensaver.h"
#include <qpe/applnk.h>
#include <qpe/mimetype.h>
#include <qpe/password.h>
#include <qpe/config.h>
#include <qpe/power.h>
#include <qpe/timeconversion.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/network.h>
#include <qpe/global.h>
#if defined( QT_QWS_SHARP ) || defined( QT_QWS_IPAQ )
#include <qpe/custom.h>
#endif
#include <opie/odevice.h>
#include <qgfx_qws.h>
#include <qmainwindow.h>
#include <qmessagebox.h>
#include <qtimer.h>
#include <qwindowsystem_qws.h>
#include <qvaluelist.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
using namespace Opie;
class QCopKeyRegister
{
public:
QCopKeyRegister() : keyCode( 0 )
{ }
QCopKeyRegister( int k, const QCString &c, const QCString &m )
: keyCode( k ), channel( c ), message( m )
{ }
int getKeyCode() const
{
return keyCode;
}
QCString getChannel() const
{
return channel;
}
QCString getMessage() const
{
return message;
}
@@ -677,134 +679,142 @@ void Desktop::togglePower()
#endif
ODevice::inst ( )-> suspend ( );
DesktopApplication::switchLCD ( true ); // force LCD on without slow qcop call
QWSServer::screenSaverActivate ( false );
{
QCopEnvelope( "QPE/Card", "mtabChanged()" ); // might have changed while asleep
}
if ( wasloggedin )
login ( true );
execAutoStart();
//qcopBridge->closeOpenConnections();
excllock = false;
}
void Desktop::toggleLight()
{
QCopEnvelope e( "QPE/System", "setBacklight(int)" );
e << -2; // toggle
}
void Desktop::toggleSymbolInput()
{
tb->toggleSymbolInput();
}
void Desktop::toggleNumLockState()
{
tb->toggleNumLockState();
}
void Desktop::toggleCapsLockState()
{
tb->toggleCapsLockState();
}
void Desktop::styleChange( QStyle &s )
{
QWidget::styleChange( s );
int displayw = qApp->desktop() ->width();
int displayh = qApp->desktop() ->height();
QSize sz = tb->sizeHint();
tb->setGeometry( 0, displayh - sz.height(), displayw, sz.height() );
}
void DesktopApplication::shutdown()
{
if ( type() != GuiServer )
return ;
ShutdownImpl *sd = new ShutdownImpl( 0, 0, WDestructiveClose );
connect( sd, SIGNAL( shutdown( ShutdownImpl::Type ) ),
this, SLOT( shutdown( ShutdownImpl::Type ) ) );
sd->showMaximized();
}
void DesktopApplication::shutdown( ShutdownImpl::Type t )
{
+
+ char *opt = 0;
+
switch ( t ) {
case ShutdownImpl::ShutdownSystem:
- execlp( "shutdown", "shutdown", "-h", "now", ( void* ) 0 );
- break;
+ opt = "-h";
+ // fall through
case ShutdownImpl::RebootSystem:
- execlp( "shutdown", "shutdown", "-r", "now", ( void* ) 0 );
+ if ( opt == 0 )
+ opt = "-r";
+
+ if ( execle( "shutdown", "shutdown", opt, "now", ( void* ) 0, "/sbin", "/usr/sbin", ( void* ) 0 ) < 0 )
+ ::syslog ( LOG_ERR, "Erroring execing shutdown\n" );
+
break;
case ShutdownImpl::RestartDesktop:
restart();
break;
case ShutdownImpl::TerminateDesktop:
prepareForTermination( FALSE );
// This is a workaround for a Qt bug
// clipboard applet has to stop its poll timer, or Qt/E
// will hang on quit() right before it emits aboutToQuit()
emit aboutToQuit ( );
quit();
break;
}
}
void DesktopApplication::restart()
{
prepareForTermination( TRUE );
#ifdef Q_WS_QWS
for ( int fd = 3; fd < 100; fd++ )
close( fd );
#if defined(QT_DEMO_SINGLE_FLOPPY)
execl( "/sbin/init", "qpe", 0 );
#elif defined(QT_QWS_CASSIOPEIA)
execl( "/bin/sh", "sh", 0 );
#else
execl( ( qpeDir() + "/bin/qpe" ).latin1(), "qpe", 0 );
#endif
exit( 1 );
#endif
}
void Desktop::startTransferServer()
{
// start qcop bridge server
qcopBridge = new QCopBridge( 4243 );
if ( !qcopBridge->ok() ) {
delete qcopBridge;
qcopBridge = 0;
}
// start transfer server
transferServer = new TransferServer( 4242 );
if ( !transferServer->ok() ) {
delete transferServer;
transferServer = 0;
}
if ( !transferServer || !qcopBridge )
startTimer( 2000 );
}
void Desktop::timerEvent( QTimerEvent *e )
{
killTimer( e->timerId() );
startTransferServer();
}