3 * - By John Hodge (thePowersGang)
5 * CIPCChannel_AcessIPCPipe.cpp
6 * - IPC Channel :: Acess' IPC Pipe /Devices/ipcpipe/<name>
9 #include <CIPCChannel_AcessIPCPipe.hpp>
11 #include <system_error>
12 #include <acess/sys.h>
17 CIPCChannel_AcessIPCPipe::CIPCChannel_AcessIPCPipe(const ::std::string& suffix)
19 ::std::string path = "/Devices/ipcpipe/" + suffix;
20 m_fd = _SysOpen(path.c_str(), OPENFLAG_CREATE);
22 _SysDebug("Failed to open %s: %s", path.c_str(), strerror(errno));
23 throw ::std::system_error(errno, ::std::system_category());
26 CIPCChannel_AcessIPCPipe::~CIPCChannel_AcessIPCPipe()
31 int CIPCChannel_AcessIPCPipe::FillSelect(fd_set& rfds)
33 _SysDebug("CIPCChannel_AcessIPCPipe::FillSelect");
37 for( auto& clientref : m_clients )
39 _SysDebug("CIPCChannel_AcessIPCPipe::FillSelect - FD%i", clientref.m_fd);
40 maxfd = ::std::max(maxfd, clientref.m_fd);
41 FD_SET(clientref.m_fd, &rfds);
47 void CIPCChannel_AcessIPCPipe::HandleSelect(const fd_set& rfds)
49 _SysDebug("CIPCChannel_AcessIPCPipe::HandleSelect");
50 if( FD_ISSET(m_fd, &rfds) )
52 _SysDebug("CIPCChannel_AcessIPCPipe::HandleSelect - New client on FD %i", m_fd);
53 int newfd = _SysOpenChild(m_fd, "newclient", OPENFLAG_READ|OPENFLAG_WRITE);
54 _SysDebug("newfd = %i", newfd);
56 // emplace creates a new object within the list
57 m_clients.emplace( m_clients.end(), *this, newfd );
58 IPC::RegisterClient( m_clients.back() );
61 for( auto it = m_clients.begin(); it != m_clients.end(); )
63 CClient_AcessIPCPipe& clientref = *it;
64 _SysDebug("CIPCChannel_AcessIPCPipe::HandleSelect - Trying FD%i", clientref.m_fd);
67 if( FD_ISSET(clientref.m_fd, &rfds) )
70 clientref.HandleReceive();
72 catch( const ::std::exception& e ) {
73 _SysDebug("ERROR - Exception processing IPCPipe FD%i: %s",
74 clientref.m_fd, e.what()
76 it = m_clients.erase(--it);
80 _SysDebug("CIPCChannel_AcessIPCPipe::HandleSelect - END");
84 CClient_AcessIPCPipe::CClient_AcessIPCPipe(::AxWin::IIPCChannel& channel, int fd):
91 CClient_AcessIPCPipe::~CClient_AcessIPCPipe()
94 _SysDebug("Closed client FD%i", m_fd);
97 void CClient_AcessIPCPipe::SendMessage(CSerialiser& message)
99 const ::std::vector<uint8_t>& data = message.Compact();
101 _SysDebug("CClient_AcessIPCPipe::SendMessage - %i bytes to %i", data.size(), m_fd);
102 _SysWrite(m_fd, data.data(), data.size());
105 void CClient_AcessIPCPipe::HandleReceive()
107 size_t len = _SysRead(m_fd, &m_rxbuf[0], m_rxbuf.capacity());
108 if( len == (size_t)-1 )
109 throw ::std::system_error(errno, ::std::system_category());
111 CDeserialiser message(len, &m_rxbuf[0]);
112 CClient::HandleMessage(message);