diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-02-14 15:55:19 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-02-14 15:55:19 +0100 |
commit | b20a7aca612b705e47fc15d1b1c9b864c6acda61 (patch) | |
tree | 81cc870f8ea5d9557ef0ea562272d8949d61f1cf /Kernel/LocalSocket.cpp | |
parent | b12ab1270a8605e7f095be18facbed3f40da7a9c (diff) | |
download | serenity-b20a7aca612b705e47fc15d1b1c9b864c6acda61.zip |
Kernel: More work on sockets. Fleshing out connect().
Diffstat (limited to 'Kernel/LocalSocket.cpp')
-rw-r--r-- | Kernel/LocalSocket.cpp | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/Kernel/LocalSocket.cpp b/Kernel/LocalSocket.cpp index abd3201cc8..2fb0f3de1c 100644 --- a/Kernel/LocalSocket.cpp +++ b/Kernel/LocalSocket.cpp @@ -31,11 +31,11 @@ bool LocalSocket::get_address(sockaddr* address, socklen_t* address_size) bool LocalSocket::bind(const sockaddr* address, socklen_t address_size, int& error) { + ASSERT(!m_connected); if (address_size != sizeof(sockaddr_un)) { error = -EINVAL; return false; } - if (address->sa_family != AF_LOCAL) { error = -EINVAL; return false; @@ -51,10 +51,46 @@ bool LocalSocket::bind(const sockaddr* address, socklen_t address_size, int& err if (!m_file) { if (error == -EEXIST) error = -EADDRINUSE; - return error; + return false; } + ASSERT(m_file->inode()); + m_file->inode()->bind_socket(*this); + m_address = local_address; m_bound = true; return true; } + +RetainPtr<Socket> LocalSocket::connect(const sockaddr* address, socklen_t address_size, int& error) +{ + ASSERT(!m_bound); + if (address_size != sizeof(sockaddr_un)) { + error = -EINVAL; + return nullptr; + } + if (address->sa_family != AF_LOCAL) { + error = -EINVAL; + return nullptr; + } + + const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address); + char safe_address[sizeof(local_address.sun_path) + 1]; + memcpy(safe_address, local_address.sun_path, sizeof(local_address.sun_path)); + + kprintf("%s(%u) LocalSocket{%p} connect(%s)\n", current->name().characters(), current->pid(), safe_address); + + m_file = VFS::the().open(safe_address, error, 0, 0, *current->cwd_inode()); + if (!m_file) { + error = -ECONNREFUSED; + return nullptr; + } + + ASSERT(m_file->inode()); + ASSERT(m_file->inode()->socket()); + + m_peer = m_file->inode()->socket(); + m_address = local_address; + m_connected = true; + return m_peer; +} |