[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kinit
From:       Luboš Luňák <l.lunak () kde ! org>
Date:       2010-05-31 17:23:36
Message-ID: 20100531172336.75562AC8C6 () svn ! kde ! org
[Download RAW message or body]

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 <klocale.h>
 #include <kdebug.h>
 #include <kde_file.h>
+#include <ksavefile.h>
 
 #ifdef Q_OS_LINUX
 #include <sys/prctl.h>
@@ -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()
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic