Kernel/LibC: Implement SOCK_CLOEXEC and SOCK_NONBLOCK
This removes the need for fcntl after creating a socket :)
This commit is contained in:
@@ -110,12 +110,12 @@ namespace Kernel
|
||||
return link_target_impl();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Inode::accept(sockaddr* address, socklen_t* address_len)
|
||||
BAN::ErrorOr<long> Inode::accept(sockaddr* address, socklen_t* address_len, int flags)
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
if (!mode().ifsock())
|
||||
return BAN::Error::from_errno(ENOTSOCK);
|
||||
return accept_impl(address, address_len);
|
||||
return accept_impl(address, address_len, flags);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Inode::bind(const sockaddr* address, socklen_t address_len)
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Kernel
|
||||
dprintln_if(DEBUG_TCP, "Socket destroyed");
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> TCPSocket::accept_impl(sockaddr* address, socklen_t* address_len)
|
||||
BAN::ErrorOr<long> TCPSocket::accept_impl(sockaddr* address, socklen_t* address_len, int flags)
|
||||
{
|
||||
if (m_state != State::Listen)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
@@ -123,7 +123,7 @@ namespace Kernel
|
||||
memcpy(address, &connection.target.address, *address_len);
|
||||
}
|
||||
|
||||
return TRY(Process::current().open_inode(return_inode, O_RDWR));
|
||||
return TRY(Process::current().open_inode(return_inode, O_RDWR | flags));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> TCPSocket::connect_impl(const sockaddr* address, socklen_t address_len)
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Kernel
|
||||
}
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> UnixDomainSocket::accept_impl(sockaddr* address, socklen_t* address_len)
|
||||
BAN::ErrorOr<long> UnixDomainSocket::accept_impl(sockaddr* address, socklen_t* address_len, int flags)
|
||||
{
|
||||
if (!m_info.has<ConnectionInfo>())
|
||||
return BAN::Error::from_errno(EOPNOTSUPP);
|
||||
@@ -104,7 +104,7 @@ namespace Kernel
|
||||
strncpy(sockaddr_un.sun_path, pending->m_bound_path.data(), copy_len);
|
||||
}
|
||||
|
||||
return TRY(Process::current().open_inode(return_inode, O_RDWR));
|
||||
return TRY(Process::current().open_inode(return_inode, O_RDWR | flags));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> UnixDomainSocket::connect_impl(const sockaddr* address, socklen_t address_len)
|
||||
|
||||
@@ -106,6 +106,13 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(EPROTOTYPE);
|
||||
}
|
||||
|
||||
int extra_flags = 0;
|
||||
if (type & SOCK_NONBLOCK)
|
||||
extra_flags |= O_NONBLOCK;
|
||||
if (type & SOCK_CLOEXEC)
|
||||
extra_flags |= O_CLOEXEC;
|
||||
type &= ~(SOCK_NONBLOCK | SOCK_CLOEXEC);
|
||||
|
||||
Socket::Type sock_type;
|
||||
switch (type)
|
||||
{
|
||||
@@ -133,7 +140,7 @@ namespace Kernel
|
||||
auto socket = TRY(NetworkManager::get().create_socket(sock_domain, sock_type, 0777, m_credentials.euid(), m_credentials.egid()));
|
||||
|
||||
int fd = TRY(get_free_fd());
|
||||
m_open_files[fd] = TRY(BAN::RefPtr<OpenFileDescription>::create(socket, "no-path"_sv, 0, O_RDWR));
|
||||
m_open_files[fd] = TRY(BAN::RefPtr<OpenFileDescription>::create(socket, "<socket>"_sv, 0, O_RDWR | extra_flags));
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
@@ -1192,12 +1192,14 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len)
|
||||
BAN::ErrorOr<long> Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len, int flags)
|
||||
{
|
||||
if (address && !address_len)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (!address && address_len)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC))
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
if (address)
|
||||
@@ -1210,7 +1212,13 @@ namespace Kernel
|
||||
if (!inode->mode().ifsock())
|
||||
return BAN::Error::from_errno(ENOTSOCK);
|
||||
|
||||
return TRY(inode->accept(address, address_len));
|
||||
int open_flags = 0;
|
||||
if (flags & SOCK_NONBLOCK)
|
||||
open_flags |= O_NONBLOCK;
|
||||
if (flags & SOCK_CLOEXEC)
|
||||
open_flags |= O_CLOEXEC;
|
||||
|
||||
return TRY(inode->accept(address, address_len, open_flags));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_bind(int socket, const sockaddr* address, socklen_t address_len)
|
||||
|
||||
Reference in New Issue
Block a user