File indexing completed on 2024-04-28 15:27:02
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 1999-2000 Waldo Bastian <bastian@kde.org> 0004 SPDX-FileCopyrightText: 1999 Mario Weilguni <mweilguni@sime.com> 0005 SPDX-FileCopyrightText: 2001 Lubos Lunak <l.lunak@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only 0008 */ 0009 0010 #include <cerrno> 0011 #include <locale.h> 0012 #include <signal.h> 0013 #include <stdio.h> 0014 #include <stdlib.h> 0015 0016 #include <QFile> 0017 #include <QLibrary> 0018 #include <QPluginLoader> 0019 #include <QString> 0020 0021 #ifdef Q_OS_WIN 0022 #include <QProcess> 0023 #include <QStandardPaths> 0024 #include <QStringList> 0025 0026 #include <process.h> 0027 #include <qt_windows.h> 0028 #endif 0029 0030 #ifndef Q_OS_WIN 0031 #include <unistd.h> 0032 0033 /* These are to link libkio even if 'smart' linker is used */ 0034 #include <kio/authinfo.h> 0035 extern "C" KIO::AuthInfo *_kioslave_init_kio() 0036 { 0037 return new KIO::AuthInfo(); 0038 } 0039 #endif 0040 0041 int main(int argc, char **argv) 0042 { 0043 if (argc < 5) { 0044 fprintf(stderr, "Usage: kioslave5 <slave-lib> <protocol> <klauncher-socket> <app-socket>\n\nThis program is part of KDE.\n"); 0045 return 1; 0046 } 0047 #ifndef _WIN32_WCE 0048 setlocale(LC_ALL, ""); 0049 #endif 0050 QString libname = QFile::decodeName(argv[1]); 0051 0052 if (libname.isEmpty()) { 0053 fprintf(stderr, "library path is empty.\n"); 0054 return 1; 0055 } 0056 0057 // Use QPluginLoader to locate the library when using a relative path 0058 // But we need to use QLibrary to actually load it, because of resolve()! 0059 QString libpath = QPluginLoader(libname).fileName(); 0060 if (libpath.isEmpty()) { 0061 fprintf(stderr, "could not locate %s, check QT_PLUGIN_PATH\n", qPrintable(libname)); 0062 return 1; 0063 } 0064 0065 QLibrary lib(libpath); 0066 if (!lib.load()) { 0067 fprintf(stderr, "could not open %s: %s\n", qPrintable(libname), qPrintable(lib.errorString())); 0068 return 1; 0069 } 0070 0071 QFunctionPointer sym = lib.resolve("kdemain"); 0072 if (!sym) { 0073 fprintf(stderr, "Could not find kdemain: %s\n", qPrintable(lib.errorString())); 0074 return 1; 0075 } 0076 0077 const QByteArray slaveDebugWait = qgetenv("KDE_SLAVE_DEBUG_WAIT"); 0078 0079 #ifdef Q_OS_WIN 0080 // enter debugger in case debugging is activated 0081 if (slaveDebugWait == "all" || slaveDebugWait == argv[2]) { 0082 #ifdef Q_CC_MSVC 0083 // msvc debugger or windbg supports jit debugging, the latter requires setting up windbg jit with windbg -i 0084 DebugBreak(); 0085 #else 0086 // gdb does not support win32 jit debug support, so implement it by ourself 0087 WCHAR buf[1024]; 0088 GetModuleFileName(NULL, buf, 1024); 0089 QStringList params; 0090 params << QString::fromUtf16((const unsigned short *)buf); 0091 params << QString::number(GetCurrentProcessId()); 0092 const QString gdbExec = QStandardPaths::findExecutable(QStringLiteral("gdb")); 0093 if (gdbExec.isEmpty()) { 0094 fprintf(stderr, "Could not find 'gdb' executable in PATH\n"); 0095 return 1; 0096 } 0097 QProcess::startDetached(gdbExec, params); 0098 Sleep(1000); 0099 #endif 0100 } 0101 #if defined(Q_CC_MSVC) && !defined(_WIN32_WCE) 0102 else { 0103 QString slaveDebugPopup(QString::fromLocal8Bit(qgetenv("KDE_SLAVE_DEBUG_POPUP"))); 0104 if (slaveDebugPopup == QLatin1String("all") || slaveDebugPopup == QString::fromLocal8Bit(argv[2])) { 0105 // A workaround for OSes where DebugBreak() does not work in administrative mode (actually Vista with msvc 2k5) 0106 // - display a native message box so developer can attach the debugger to the KIO slave process and click OK. 0107 MessageBoxA( 0108 NULL, 0109 QStringLiteral("Please attach the debugger to process #%1 (%2)").arg(getpid()).arg(QString::fromLocal8Bit(argv[0])).toLatin1().constData(), 0110 QStringLiteral("\"%1\" KIO Slave Debugging").arg(QString::fromLocal8Bit(argv[2])).toLatin1().constData(), 0111 MB_OK | MB_ICONINFORMATION | MB_TASKMODAL); 0112 } 0113 } 0114 #endif 0115 #endif // Q_OS_WIN 0116 0117 #if defined(Q_OS_UNIX) 0118 // Enter debugger in case debugging is activated 0119 if (slaveDebugWait == "all" || slaveDebugWait == argv[2]) { 0120 const pid_t pid = getpid(); 0121 fprintf(stderr, 0122 "kioslave5: Suspending process to debug io slave(s): %s\n" 0123 "kioslave5: 'gdb kioslave5 %d' to debug\n" 0124 "kioslave5: 'kill -SIGCONT %d' to continue\n", 0125 slaveDebugWait.constData(), 0126 pid, 0127 pid); 0128 0129 kill(pid, SIGSTOP); 0130 } 0131 #endif 0132 0133 int (*func)(int, char *[]) = (int (*)(int, char *[]))sym; 0134 0135 // We need argv[0] to remain /path/to/kioslave5 0136 // so that applicationDirPath() is correct on non-Linux (no /proc) 0137 // and we want to skip argv[1] so the kioslave5 exe is transparent to kdemain. 0138 const int newArgc = argc - 1; 0139 QVarLengthArray<char *, 5> newArgv(newArgc); 0140 newArgv[0] = argv[0]; 0141 for (int i = 1; i < newArgc; ++i) { 0142 newArgv[i] = argv[i + 1]; 0143 } 0144 0145 return func(newArgc, newArgv.data()); /* Launch! */ 0146 }