File indexing completed on 2024-05-05 16:13:48

0001 /*
0002     SPDX-FileCopyrightText: 2017 Chinmoy Ranjan Pradhan <chinmoyrp65@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "fdreceiver.h"
0008 
0009 #include <QSocketNotifier>
0010 #include <cerrno>
0011 
0012 #include "sharefd_p.h"
0013 
0014 FdReceiver::FdReceiver(const std::string &path, QObject *parent)
0015     : QObject(parent)
0016     , m_readNotifier(nullptr)
0017     , m_path(path)
0018     , m_socketDes(-1)
0019     , m_fileDes(-1)
0020 {
0021     const SocketAddress addr(m_path);
0022     if (!addr.address()) {
0023         std::cerr << "Invalid socket address:" << m_path << std::endl;
0024         return;
0025     }
0026 
0027     m_socketDes = ::socket(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0);
0028     if (m_socketDes == -1) {
0029         std::cerr << "socket error:" << strerror(errno) << std::endl;
0030         return;
0031     }
0032 
0033     ::unlink(m_path.c_str());
0034     if (bind(m_socketDes, addr.address(), addr.length()) != 0 || listen(m_socketDes, 5) != 0) {
0035         std::cerr << "bind/listen error:" << strerror(errno) << std::endl;
0036         ::close(m_socketDes);
0037         m_socketDes = -1;
0038         return;
0039     }
0040 
0041     m_readNotifier = new QSocketNotifier(m_socketDes, QSocketNotifier::Read, this);
0042     connect(m_readNotifier, &QSocketNotifier::activated, this, &FdReceiver::receiveFileDescriptor);
0043 }
0044 
0045 FdReceiver::~FdReceiver()
0046 {
0047     if (m_socketDes >= 0) {
0048         ::close(m_socketDes);
0049     }
0050     ::unlink(m_path.c_str());
0051 }
0052 
0053 bool FdReceiver::isListening() const
0054 {
0055     return m_socketDes >= 0 && m_readNotifier;
0056 }
0057 
0058 void FdReceiver::receiveFileDescriptor()
0059 {
0060     int client = ::accept(m_socketDes, nullptr, nullptr);
0061     if (client > 0) {
0062         FDMessageHeader msg;
0063         if (::recvmsg(client, msg.message(), 0) == 2) {
0064             ::memcpy(&m_fileDes, CMSG_DATA(msg.cmsgHeader()), sizeof m_fileDes);
0065         }
0066         ::close(client);
0067     }
0068 }
0069 
0070 int FdReceiver::fileDescriptor() const
0071 {
0072     return m_fileDes;
0073 }
0074 
0075 #include "moc_fdreceiver.cpp"