File r1132903-kinit-xauth.diff of Package kdelibs4
--- trunk/KDE/kdelibs/kinit/kinit.cpp 2010/05/31 17:23:24 1132902
+++ trunk/KDE/kdelibs/kinit/kinit.cpp 2010/05/31 17:23:36 1132903
@@ -64,6 +64,7 @@
#include <klocale.h>
#include <kdebug.h>
#include <kde_file.h>
+#include <ksavefile.h>
#ifdef Q_OS_LINUX
#include <sys/prctl.h>
@@ -1574,6 +1575,42 @@
{
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