Welcome to mirror list, hosted at ThFree Co, Russian Federation.

UnixSocket.cpp - github.com/neutrinolabs/ulalaca-xrdp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 60d3643fefa8071f954a40382ff16cf7eda60cab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//
// Created by cheesekun on 2/28/22.
//

#include <filesystem>
#include <stdexcept>

#include <cassert>
#include <cstring>

#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>


#include "UnixSocket.hpp"

ssize_t UnixSocketBase::read(void *buffer, size_t size) {
    return ::read(descriptor(), buffer, size);
}

ssize_t UnixSocketBase::write(const void *buffer, size_t size) {
    return ::write(descriptor(), buffer, size);
}

void UnixSocketBase::close() {
    ::close(descriptor());
}

UnixSocketConnection::UnixSocketConnection(FD descriptor, sockaddr_un clientAddress) :
        _descriptor(descriptor),
        _clientAddress(clientAddress)
{
}

FD UnixSocketConnection::descriptor() {
    return _descriptor;
}


UnixSocket::UnixSocket(const std::string path):
        _path(path),
        _descriptor(createSocket())
{
}

void UnixSocket::bind() {
    if (std::filesystem::exists(_path)) {
        if (!std::filesystem::is_socket(_path)) {
            // TODO: file exists, but not socket
            throw std::runtime_error("");
        }

        std::filesystem::remove(_path);
    }

    sockaddr_un address = {};
    address.sun_family = AF_UNIX;
    std::strncpy(address.sun_path, _path.c_str(), _path.size());

    int retval = ::bind(_descriptor, (sockaddr *) &address, sizeof(address));
    if (retval == -1) {
        throw SystemCallException(errno, "bind");
    }
}

void UnixSocket::listen() {
    int retval = ::listen(_descriptor, 0);
    if (retval == -1) {
        throw SystemCallException(errno, "listen");
    }
}

UnixSocketConnection UnixSocket::accept() {
    socklen_t addressLength = 0;
    sockaddr_un clientAddress = {};
    FD client = ::accept(_descriptor, (sockaddr *) &clientAddress, &addressLength);

    if (client == -1) {
        throw SystemCallException(errno, "accept");
    }

    // assert(addressLength == sizeof(clientAddress));

    return UnixSocketConnection(client, clientAddress);
}

void UnixSocket::connect() {
    sockaddr_un address = {};
    address.sun_family = AF_UNIX;
    std::strncpy(address.sun_path, _path.c_str(), _path.size());
    address.sun_len = _path.size();

    int retval = ::connect(_descriptor, (sockaddr *) &address, sizeof(address));
    if (retval < 0) {
        throw SystemCallException(errno, "connect");
    }
}

FD UnixSocket::descriptor() {
    return _descriptor;
}

FD UnixSocket::createSocket() {
    FD descriptor = socket(AF_UNIX, SOCK_STREAM, 0);

    if (descriptor < 0) {
        throw SystemCallException(errno, "socket");
    }

    // size_t recvBufferSize = 256000;
    // setsockopt(descriptor, SOL_SOCKET, SO_RCVBUF, &recvBufferSize, sizeof(recvBufferSize));


    // size_t sendBufferSize = 256000;
    // setsockopt(descriptor, SOL_SOCKET, SO_SNDBUF, &sendBufferSize, sizeof(sendBufferSize));

    return descriptor;
}