Slave *Slave::createSlave(const QString &protocol, const KURL &url, int &error, QString &error_text) { // kdDebug(7002) << "createSlave '" << protocol << "' for " << url.prettyURL() << endl; // Firstly take into account all special slaves if(protocol == "data") return new DataProtocol(); DCOPClient *client = kapp->dcopClient(); if(!client->isAttached()) client->attach(); QString prefix = locateLocal("socket", KGlobal::instance()->instanceName()); KTempFile socketfile(prefix, QString::fromLatin1(".slave-socket")); if(socketfile.status() != 0) { error_text = i18n("Unable to create io-slave: %1").arg(strerror(errno)); error = KIO::ERR_CANNOT_LAUNCH_PROCESS; return 0; } #ifdef __CYGWIN__ socketfile.close(); #endif KServerSocket *kss = new KServerSocket(QFile::encodeName(socketfile.name())); Slave *slave = new Slave(kss, protocol, socketfile.name()); // WABA: if the dcopserver is running under another uid we don't ask // klauncher for a slave, because the slave might have that other uid // as well, which might either be a) undesired or b) make it impossible // for the slave to connect to the application. // In such case we start the slave via KProcess. // It's possible to force this by setting the env. variable // KDE_FORK_SLAVES, Clearcase seems to require this. static bool bForkSlaves = !QCString(getenv("KDE_FORK_SLAVES")).isEmpty(); if(bForkSlaves || !client->isAttached() || client->isAttachedToForeignServer()) { QString _name = KProtocolInfo::exec(protocol); if(_name.isEmpty()) { error_text = i18n("Unknown protocol '%1'.").arg(protocol); error = KIO::ERR_CANNOT_LAUNCH_PROCESS; delete slave; return 0; } QString lib_path = KLibLoader::findLibrary(_name.latin1()); if(lib_path.isEmpty()) { error_text = i18n("Can not find io-slave for protocol '%1'.").arg(protocol); error = KIO::ERR_CANNOT_LAUNCH_PROCESS; return 0; } KProcess proc; proc << locate("exe", "kioslave") << lib_path << protocol << "" << socketfile.name(); kdDebug(7002) << "kioslave" << ", " << lib_path << ", " << protocol << ", " << QString::null << ", " << socketfile.name() << endl; proc.start(KProcess::DontCare); slave->setPID(proc.pid()); QTimer::singleShot(1000 * SLAVE_CONNECTION_TIMEOUT_MIN, slave, SLOT(timeout())); return slave; } QByteArray params, reply; QCString replyType; QDataStream stream(params, IO_WriteOnly); stream << protocol << url.host() << socketfile.name(); QCString launcher = KApplication::launcher(); if(!client->call(launcher, launcher, "requestSlave(QString,QString,QString)", params, replyType, reply)) { error_text = i18n("Cannot talk to klauncher"); error = KIO::ERR_SLAVE_DEFINED; delete slave; return 0; } QDataStream stream2(reply, IO_ReadOnly); QString errorStr; pid_t pid; stream2 >> pid >> errorStr; if(!pid) { error_text = i18n("Unable to create io-slave:\nklauncher said: %1").arg(errorStr); error = KIO::ERR_CANNOT_LAUNCH_PROCESS; delete slave; return 0; } slave->setPID(pid); QTimer::singleShot(1000 * SLAVE_CONNECTION_TIMEOUT_MIN, slave, SLOT(timeout())); return slave; }