summaryrefslogtreecommitdiff
path: root/Kernel/Socket.cpp
blob: 129b44fdeb510c8df002dcc66f69a6479fe3de21 (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
#include <Kernel/Socket.h>
#include <Kernel/LocalSocket.h>
#include <Kernel/UnixTypes.h>
#include <Kernel/Process.h>
#include <LibC/errno_numbers.h>

RetainPtr<Socket> Socket::create(int domain, int type, int protocol, int& error)
{
    (void)protocol;
    switch (domain) {
    case AF_LOCAL:
        return LocalSocket::create(type & SOCK_TYPE_MASK);
    default:
        error = EAFNOSUPPORT;
        return nullptr;
    }
}

Socket::Socket(int domain, int type, int protocol)
    : m_domain(domain)
    , m_type(type)
    , m_protocol(protocol)
{
    m_origin_pid = current->pid();
}

Socket::~Socket()
{
}

bool Socket::listen(int backlog, int& error)
{
    LOCKER(m_lock);
    if (m_type != SOCK_STREAM) {
        error = -EOPNOTSUPP;
        return false;
    }
    m_backlog = backlog;
    m_listening = true;
    kprintf("Socket{%p} listening with backlog=%d\n", m_backlog);
    return true;
}

RetainPtr<Socket> Socket::accept()
{
    LOCKER(m_lock);
    if (m_pending.is_empty())
        return nullptr;
    auto client = m_pending.take_first();
    ASSERT(!client->is_connected());
    client->m_connected = true;
    m_clients.append(client.copy_ref());
    return client;
}

bool Socket::queue_connection_from(Socket& peer, int& error)
{
    LOCKER(m_lock);
    if (m_pending.size() >= m_backlog) {
        error = -ECONNREFUSED;
        return false;
    }
    m_pending.append(peer);
    return true;
}