Ticket #21973: workaround-kdeinit4-crash.patch

File workaround-kdeinit4-crash.patch, 5.2 KB (added by sharky@…, 15 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  )
  • new file kdelibs-4.3.2/kinit/helper.cpp

    - +  
     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