From kde-commits Mon May 31 17:23:36 2010 From: =?utf-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Mon, 31 May 2010 17:23:36 +0000 To: kde-commits Subject: KDE/kdelibs/kinit Message-Id: <20100531172336.75562AC8C6 () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=127532635711915 SVN commit 1132903 by lunakl: A somewhat hackish way of making kdeinit work in su sessions, but I couldn't think of anything better. Kdeinit should still clean up properly in such sessions and exit after a timeout, like dcopserver did in KDE3. BUG: 75492 M +37 -0 kinit.cpp --- trunk/KDE/kdelibs/kinit/kinit.cpp #1132902:1132903 @@ -64,6 +64,7 @@ #include #include #include +#include #ifdef Q_OS_LINUX #include @@ -1574,7 +1575,43 @@ { XSetIOErrorHandler(kdeinit_xio_errhandler); XSetErrorHandler(kdeinit_x_errhandler); +/* + Handle the tricky case of running via kdesu/su/sudo/etc. There the usual case + is that kdesu (etc.) creates a file with xauth information, sets XAUTHORITY, + runs the command and removes the xauth file after the command finishes. However, + dbus and kdeinit daemon currently don't clean up properly and keeping running. + Which means that running a KDE app via kdesu the second time talks to kdeinit + with obsolete xauth information, which makes it unable to connect to X or launch + any X11 applications. + Even fixing the cleanup probably wouldn't be sufficient, since it'd be possible to + launch one kdesu session, another one, exit the first one and the app from the second + session would be using kdeinit from the first one. + So the trick here is to duplicate the xauth file to another file in KDE's tmp + location, make the file have a consistent name so that future sessions will use it + as well, point XAUTHORITY there and never remove the file (except for possible + tmp cleanup). +*/ + if( !qgetenv( "XAUTHORITY" ).isEmpty()) { + QByteArray display = qgetenv( DISPLAY ); + int i; + if((i = display.lastIndexOf('.')) > display.lastIndexOf(':') && i >= 0) + display.truncate(i); + display.replace(':','_'); +#ifdef __APPLE__ + display.replace('/','_'); +#endif + QString xauth = s_instance->dirs()->saveLocation( "tmp" ) + QLatin1String( "xauth-" ) + + QString::number( getuid()) + QLatin1String( "-" ) + QString::fromLocal8Bit( display ); + KSaveFile xauthfile( xauth ); + QFile xauthfrom( QFile::decodeName( qgetenv( "XAUTHORITY" ))); + if( !xauthfrom.open( QFile::ReadOnly ) || !xauthfile.open( QFile::WriteOnly ) + || xauthfile.write( xauthfrom.readAll()) != xauthfrom.size() || !xauthfile.finalize()) { + xauthfile.abort(); + } else { + setenv( "XAUTHORITY", QFile::encodeName( xauth ), true ); } + } +} // Borrowed from kdebase/kaudio/kaudioserver.cpp static int initXconnection()