summaryrefslogtreecommitdiff
path: root/Kernel/LocalSocket.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-02-14 15:55:19 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-02-14 15:55:19 +0100
commitb20a7aca612b705e47fc15d1b1c9b864c6acda61 (patch)
tree81cc870f8ea5d9557ef0ea562272d8949d61f1cf /Kernel/LocalSocket.cpp
parentb12ab1270a8605e7f095be18facbed3f40da7a9c (diff)
downloadserenity-b20a7aca612b705e47fc15d1b1c9b864c6acda61.zip
Kernel: More work on sockets. Fleshing out connect().
Diffstat (limited to 'Kernel/LocalSocket.cpp')
-rw-r--r--Kernel/LocalSocket.cpp40
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;
+}