⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 launcher.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
字号:
/*  This file is part of the KDE project    Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.    As a special exception this program may be linked with Qt non-commercial     edition, the resulting executable be distributed, without including the     source code for the Qt non-commercial edition in the source distribution.*/#include "launcher.h"#include <sys/types.h>#include <sys/socket.h>#include <sys/uio.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <kdebug.h>#include <kio/slave.h>#include <kio/slavebase.h>#include <kio/connection.h>#include <dcopdispatcher.h>extern void setupSignalHandler();using namespace KIO;Launcher *Launcher::s_self = 0;Launcher *Launcher::self(){    if ( !s_self )        startLauncherProcess();    return s_self;}KIO::Slave *Launcher::createSlave( const QString &prot ){    int app2slave[ 2 ]; // app -> slave    int slave2app[ 2 ]; // slave -> app    int dcopApp2Slave[ 2 ]; // dcop: app -> slave    int dcopSlave2App[ 2 ]; // dcop: slave -> app    if ( pipe( app2slave ) == -1 )    {        perror( "FATAL: can't create pipe for app->slave communication" );        ::exit( 0 );    }    if ( pipe( slave2app ) == -1 )    {        perror( "FATAL: can't create pipe for slave->app communcation" );        ::exit( 0 );    }    if ( pipe( dcopApp2Slave ) == -1 )    {        perror( "FATAL: can't create pipe for dcop app->slave communcation" );        ::exit( 0 );    }    if ( pipe( dcopSlave2App ) == -1 )    {        perror( "FATAL: can't create pipe for dcop slave->app communication" );        ::exit( 0 );    }    pid_t slavePid = sendCreateSlaveCommand( prot.latin1(),                                             app2slave[ 0 ], slave2app[ 1 ],                                             dcopApp2Slave[ 0 ], dcopSlave2App[ 1 ] );    // we can close these, now that they have been transferred to the slave    ::close( app2slave[ 0 ] );    ::close( slave2app[ 1 ] );    ::close( dcopApp2Slave[ 0 ] );    ::close( dcopSlave2App[ 1 ] );    if ( slavePid == 0 )    {        ::close( app2slave[ 1 ] );        ::close( slave2app[ 0 ] );        ::close( dcopApp2Slave[ 1 ] );        ::close( dcopSlave2App[ 0 ] );        return 0;    }    Connection *connection = new Connection;    connection->init( slave2app[ 0 ], app2slave[ 1 ] );    Slave *slave = new Slave( connection, slavePid );    connection = new Connection;    connection->init( dcopSlave2App[ 0 ], dcopApp2Slave[ 1 ] );    DCOPDispatcher::self()->addClient( connection, slave );    return slave;}Launcher::Launcher( int socket )    : m_socket( socket ), m_launcherPid( 0 ){}Launcher::Launcher( int socket, pid_t launcherPid )    : m_socket( socket ), m_launcherPid( launcherPid ){}Launcher::~Launcher(){    if ( m_launcherPid != 0 )        ::kill( m_launcherPid, SIGTERM );}void Launcher::startLauncherProcess(){    int launcherFds[ 2 ];    if ( socketpair( AF_UNIX, SOCK_STREAM, 0, launcherFds ) != 0 )    {        perror( "FATAL: can't create socket for launcher" );        ::exit( 1 );    }    pid_t pid = fork();    if ( pid == 0 )    {        ::close( launcherFds[ 0 ] );        Launcher l( launcherFds[ 1 ] );        l.dispatchLoop();        ::exit( 0 );    }    ::close( launcherFds[ 1 ] );    s_self = new Launcher( launcherFds[ 0 ], pid );}void Launcher::stopLauncherProcess(){    delete this;    s_self = 0;}pid_t Launcher::sendCreateSlaveCommand( const char *protocol,                                        int slaveReadFd, int slaveWriteFd,                                        int dcopReadFd, int dcopWriteFd ){    LauncherMsg launcherMsg;    iovec iov;    // size of hdr plus size of four fds    // (kio: app->slave and slave->app)    // (dcop: app->slave and slave->app)    size_t hdrlen = CMSG_LEN( sizeof( int ) * slaveFdCount );    cmsghdr *hdr = (cmsghdr *)malloc( hdrlen );    msghdr msg;    iov.iov_base = (char *)&launcherMsg;    iov.iov_len = sizeof( LauncherMsg );    msg.msg_name = 0;    msg.msg_namelen = 0;    msg.msg_iov = &iov;    msg.msg_iovlen = 1;    msg.msg_control = (char *)hdr;    msg.msg_controllen = hdrlen;    msg.msg_flags = 0;    hdr->cmsg_len = hdrlen;    hdr->cmsg_level = SOL_SOCKET;    hdr->cmsg_type = SCM_RIGHTS;    int *fdPtr = reinterpret_cast<int *>( CMSG_DATA( hdr ) );    *fdPtr++ = slaveReadFd;    *fdPtr++ = slaveWriteFd;    *fdPtr++ = dcopReadFd;    *fdPtr = dcopWriteFd;    memset( &launcherMsg, 0, sizeof( launcherMsg ) );    launcherMsg.command = launcherCreateSlaveCmd;    strncpy( launcherMsg.data.protocol, protocol, sizeof( launcherMsg.data.protocol ) );    launcherMsg.data.protocol[ sizeof( launcherMsg.data.protocol ) - 1 ] = 0;    if ( sendmsg( m_socket, &msg, 0 ) == -1 )    {        perror( "error sending launcherCreateSlaveCmd" );        free( hdr );        return 0;    }    msg.msg_name = 0;    msg.msg_namelen = 0;    int n = recvmsg( m_socket, &msg, MSG_WAITALL );    free( hdr );    if ( n == -1 )        return 0;    if ( launcherMsg.command != launcherSlavePidCmd )    {        kdDebug() << "received unexpected command " << launcherMsg.command << " from launcher!" << endl;        return 0;    }    return launcherMsg.data.slavePid;}void Launcher::dispatchLoop(){    qDebug( "Launcher::dispatchLoop()..." );    setupSignalHandler();    while ( 42 )    {        LauncherMsg launcherMsg;        iovec iov;        // size of hdr plus size of four fds        // (kio: app->slave and slave->app)        // (dcop: app->slave and slave->app)        size_t hdrlen = CMSG_LEN( sizeof( int ) * slaveFdCount );        cmsghdr *hdr = (cmsghdr *)malloc( hdrlen );        msghdr msg;        iov.iov_base = (char *)&launcherMsg;        iov.iov_len = sizeof( launcherMsg );        msg.msg_name = 0;        msg.msg_namelen = 0;        msg.msg_iov = &iov;        msg.msg_iovlen = 1;        msg.msg_control = (char *)hdr;        msg.msg_controllen = hdrlen;        msg.msg_flags = 0;        if ( recvmsg( m_socket, &msg, MSG_WAITALL ) == -1 )        {            perror( "launcher: recvmsg() failed" );            free( hdr );            return;        }        bool r = dispatch( launcherMsg, hdr );        free( hdr );        // something went wrong :-(        if ( !r )            break;    }}bool Launcher::dispatch( LauncherMsg &msg, cmsghdr *controlmsg ){    if ( msg.command == launcherCreateSlaveCmd )        return createSlaveInternal( msg.data.protocol, controlmsg );    else {        kdDebug() << "launcher: received unknown command " << msg.command << endl;        return false;    }}bool Launcher::createSlaveInternal( const char *protocol, cmsghdr *controlmsg ){    qDebug( "launcher: creating slave for protocol %s", protocol );    int *fdPtr = reinterpret_cast<int *>( CMSG_DATA( controlmsg ) );    int slaveReadFd = *fdPtr++;    int slaveWriteFd = *fdPtr++;    int dcopReadFd = *fdPtr++;    int dcopWriteFd = *fdPtr;    pid_t pid = fork();    if ( pid == 0 )    {        // here we are, in the slave, finally :-)        Connection *connection = new Connection;        connection->init( slaveReadFd, slaveWriteFd );        SlaveBase *slave = SlaveBase::createSlave( QString::fromLatin1( protocol ) );        assert( slave );        slave->setConnection( connection );        connection = new Connection;        connection->init( dcopReadFd, dcopWriteFd );        DCOPClient::setGlobalConnection( connection );        slave->dispatchLoop();        ::exit( 0 );    }    assert( pid != -1 );    ::close( slaveReadFd );    ::close( slaveWriteFd );    ::close( dcopReadFd );    ::close( dcopWriteFd );    // send back pid to main    LauncherMsg launcherMsg;    iovec iov;    msghdr msg;    iov.iov_base = (char *)&launcherMsg;    iov.iov_len = sizeof( launcherMsg );    msg.msg_name = 0;    msg.msg_namelen = 0;    msg.msg_iov = &iov;    msg.msg_iovlen = 1;    msg.msg_control = 0;    msg.msg_controllen = 0;    msg.msg_flags = 0;    memset( &launcherMsg, 0, sizeof( launcherMsg ) );    launcherMsg.command = launcherSlavePidCmd;    launcherMsg.data.slavePid = pid;    if ( sendmsg( m_socket, &msg, 0 ) == -1 ) {        perror( "launcher: error sending launcherSlavePidCmd" );        return false;    }    return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -