New Ticket     Wiki     Browse Source     Timeline     Roadmap     Ticket Reports     Search

Ticket #21973: workaround-kdeinit4-crash.patch

File workaround-kdeinit4-crash.patch, 5.2 KB (added by sharky@…, 3 years ago)

A better patch which also handles library calls (e.g KIO slaves)

  • kinit/kinit.cpp

    old new  
    489489      init_startup_info( startup_id, name, envc, envs ); 
    490490#endif 
    491491 
     492  // Don't run this inside the child process, it crashes on OS/X 10.6 
     493  const QByteArray docPath = QFile::encodeName(KGlobalSettings::documentPath()); 
     494  QString helperpath = s_instance->dirs()->findExe(QString::fromLatin1("kdeinit4_helper")); 
     495#ifdef Q_WS_MAC 
     496  QString bundlepath = s_instance->dirs()->findExe(QFile::decodeName(execpath)); 
     497  QString argvexe = s_instance->dirs()->findExe(QString::fromLatin1(_name)); 
     498#endif 
     499 
    492500  d.errorMsg = 0; 
    493501  d.fork = fork(); 
    494502  switch(d.fork) { 
     
    513521     if (cwd && *cwd) { 
    514522         (void)chdir(cwd); 
    515523     } else { 
    516          const QByteArray docPath = QFile::encodeName(KGlobalSettings::documentPath()); 
    517524         (void)chdir(docPath.constData()); 
    518525     } 
    519526 
     
    549556     { 
    550557       int r; 
    551558       QByteArray procTitle; 
    552        d.argv = (char **) malloc(sizeof(char *) * (argc+1)); 
     559       d.argv = (char **) malloc(sizeof(char *) * (argc+2)); 
    553560       d.argv[0] = (char *) _name; 
    554561#ifdef Q_WS_MAC 
    555        QString argvexe = s_instance->dirs()->findExe(QString::fromLatin1(d.argv[0])); 
    556562       if (!argvexe.isEmpty()) { 
    557563          QByteArray cstr = argvexe.toLocal8Bit(); 
    558564          kDebug(7016) << "kdeinit4: launch() setting argv: " << cstr.data(); 
     
    628634 
    629635        QByteArray executable = execpath; 
    630636#ifdef Q_WS_MAC 
    631         QString bundlepath = s_instance->dirs()->findExe(QFile::decodeName(executable)); 
    632637        if (!bundlepath.isEmpty()) 
    633638           executable = QFile::encodeName(bundlepath); 
    634639#endif 
     
    642647        exit(255); 
    643648     } 
    644649 
    645      void * sym = l.resolve( "kdeinitmain"); 
    646      if (!sym ) 
    647         { 
    648         sym = l.resolve( "kdemain" ); 
    649         if ( !sym ) 
    650            { 
    651             QString ltdlError = l.errorString(); 
    652             fprintf(stderr, "Could not find kdemain: %s\n", qPrintable(ltdlError) ); 
    653               QString errorMsg = i18n("Could not find 'kdemain' in '%1'.\n%2", 
    654                                       libpath, ltdlError); 
    655               exitWithErrorMsg(errorMsg); 
    656            } 
    657         } 
    658  
    659      d.result = 0; // Success 
     650     d.result = 2; // Try execing 
    660651     write(d.fd[1], &d.result, 1); 
    661      close(d.fd[1]); 
    662652 
    663      d.func = (int (*)(int, char *[])) sym; 
     653     // We set the close on exec flag. 
     654     // Closing of d.fd[1] indicates that the execvp succeeded! 
     655     fcntl(d.fd[1], F_SETFD, FD_CLOEXEC); 
     656 
    664657     if (d.debug_wait) 
    665658     { 
    666659        fprintf(stderr, "kdeinit4: Suspending process\n" 
     
    674667        setup_tty( tty ); 
    675668     } 
    676669 
    677      exit( d.func(argc, d.argv)); /* Launch! */ 
     670     QByteArray helperexe = QFile::encodeName(helperpath); 
     671     QByteArray libpathbytes = QFile::encodeName(libpath); 
     672     d.argv[argc] = libpathbytes.data(); 
     673     d.argv[argc+1] = 0; 
     674 
     675     if (!helperexe.isEmpty()) 
     676        execvp(helperexe, d.argv); 
    678677 
     678     d.result = 1; // Error 
     679     write(d.fd[1], &d.result, 1); 
     680     close(d.fd[1]); 
     681     exit(255); 
    679682     break; 
    680683  } 
    681684  default: 
  • kinit/CMakeLists.txt

    old new  
    5353 
    5454install(TARGETS kdeinit4 ${INSTALL_TARGETS_DEFAULT_ARGS} ) 
    5555 
     56########### kdeinit4_helper ############### 
     57 
     58set(kdeinit4_helper_SRCS helper.cpp) 
     59 
     60kde4_add_executable(kdeinit4_helper NOGUI ${kdeinit4_helper_SRCS}) 
     61 
     62target_link_libraries(kdeinit4_helper ${QT_QTCORE_LIBRARY}) 
     63 
     64install(TARGETS kdeinit4_helper DESTINATION ${LIBEXEC_INSTALL_DIR} ) 
     65 
    5666########### kwrapper4 ############### 
    5767if (WIN32) 
    5868  set(kwrapper_SRCS kwrapper_win.cpp  ) 
  • (a) /dev/null vs. (b) kdelibs-4.3.2/kinit/helper.cpp

    a b  
     1#include <stdio.h> 
     2#include <stdlib.h> 
     3 
     4#include <QFile> 
     5#include <QLibrary> 
     6 
     7typedef int (*handler) (int, char *[]); 
     8 
     9int main(int argc, char *argv[]) 
     10{ 
     11    if (argc < 2) 
     12    { 
     13        fprintf(stderr, "Too few arguments\n"); 
     14        exit(1); 
     15    } 
     16 
     17    QString libpath = QFile::decodeName(argv[argc-1]); 
     18    QLibrary l(libpath); 
     19 
     20    if (!libpath.isEmpty() && (!l.load() || !l.isLoaded())) 
     21    { 
     22        QString ltdlError = l.errorString(); 
     23        fprintf(stderr, "Could not open library %s: %s\n", qPrintable(libpath), qPrintable(ltdlError) ); 
     24        exit(1); 
     25    } 
     26 
     27    void * sym = l.resolve( "kdeinitmain"); 
     28    if (!sym) 
     29    { 
     30        sym = l.resolve( "kdemain" ); 
     31        if ( !sym ) 
     32        { 
     33            QString ltdlError = l.errorString(); 
     34            fprintf(stderr, "Could not find kdemain: %s\n", qPrintable(ltdlError) ); 
     35            exit(1); 
     36        } 
     37    } 
     38 
     39    handler func = (int (*)(int, char *[])) sym; 
     40    exit( func(argc - 1, argv)); /* Launch! */ 
     41} 
     42