Compare commits

..

No commits in common. "f022a1b08ffd73982eb24042c318f98b3cb982fb" and "c304133224af3f9866d00c8cb8a92d6a3aba1899" have entirely different histories.

18 changed files with 108 additions and 281 deletions

View File

@ -126,16 +126,14 @@ namespace BAN
Variant(Variant&& other) Variant(Variant&& other)
: m_index(other.m_index) : m_index(other.m_index)
{ {
if (other.has_value()) detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
other.clear(); other.clear();
} }
Variant(const Variant& other) Variant(const Variant& other)
: m_index(other.m_index) : m_index(other.m_index)
{ {
if (other.has_value()) detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
} }
template<typename T> template<typename T>
@ -159,13 +157,12 @@ namespace BAN
Variant& operator=(Variant&& other) Variant& operator=(Variant&& other)
{ {
if (m_index == other.m_index && m_index != invalid_index()) if (m_index == other.m_index)
detail::move_assign<Ts...>(m_index, other.m_storage, m_storage); detail::move_assign<Ts...>(m_index, other.m_storage, m_storage);
else else
{ {
clear(); clear();
if (other.has_value()) detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
m_index = other.m_index; m_index = other.m_index;
} }
other.clear(); other.clear();
@ -174,13 +171,12 @@ namespace BAN
Variant& operator=(const Variant& other) Variant& operator=(const Variant& other)
{ {
if (m_index == other.m_index && m_index != invalid_index()) if (m_index == other.m_index)
detail::copy_assign<Ts...>(m_index, other.m_storage, m_storage); detail::copy_assign<Ts...>(m_index, other.m_storage, m_storage);
else else
{ {
clear(); clear();
if (other.has_value()) detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
m_index = other.m_index; m_index = other.m_index;
} }
return *this; return *this;

View File

@ -113,8 +113,6 @@ namespace Kernel
BAN::ErrorOr<size_t> recvmsg(msghdr& message, int flags); BAN::ErrorOr<size_t> recvmsg(msghdr& message, int flags);
BAN::ErrorOr<void> getsockname(sockaddr* address, socklen_t* address_len); BAN::ErrorOr<void> getsockname(sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<void> getpeername(sockaddr* address, socklen_t* address_len); BAN::ErrorOr<void> getpeername(sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<void> getsockopt(int level, int option, void* value, socklen_t* value_len);
BAN::ErrorOr<void> setsockopt(int level, int option, const void* value, socklen_t value_len);
// General API // General API
BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer); BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
@ -163,8 +161,6 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> setsockopt_impl(int, int, const void*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
// General API // General API
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); }

View File

@ -63,7 +63,6 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override; virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override; virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override; virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override; virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;

View File

@ -38,7 +38,6 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override; virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override; virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); } virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override; virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;

View File

@ -6,6 +6,7 @@
#include <kernel/FS/Socket.h> #include <kernel/FS/Socket.h>
#include <kernel/FS/TmpFS/Inode.h> #include <kernel/FS/TmpFS/Inode.h>
#include <kernel/FS/VirtualFileSystem.h> #include <kernel/FS/VirtualFileSystem.h>
#include <kernel/Lock/SpinLock.h>
#include <kernel/OpenFileDescriptorSet.h> #include <kernel/OpenFileDescriptorSet.h>
namespace Kernel namespace Kernel
@ -31,8 +32,6 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override; virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override; virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override; virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
virtual BAN::ErrorOr<void> setsockopt_impl(int, int, const void*, socklen_t) override;
virtual bool can_read_impl() const override; virtual bool can_read_impl() const override;
virtual bool can_write_impl() const override; virtual bool can_write_impl() const override;
@ -70,10 +69,9 @@ namespace Kernel
size_t size; size_t size;
BAN::Vector<FDWrapper> fds; BAN::Vector<FDWrapper> fds;
BAN::Optional<struct ucred> ucred; BAN::Optional<struct ucred> ucred;
BAN::WeakPtr<UnixDomainSocket> sender;
}; };
BAN::ErrorOr<size_t> add_packet(const msghdr&, PacketInfo&&, bool dont_block); BAN::ErrorOr<void> add_packet(const msghdr&, PacketInfo&&);
private: private:
const Socket::Type m_socket_type; const Socket::Type m_socket_type;
@ -83,14 +81,10 @@ namespace Kernel
BAN::CircularQueue<PacketInfo, 512> m_packet_infos; BAN::CircularQueue<PacketInfo, 512> m_packet_infos;
size_t m_packet_size_total { 0 }; size_t m_packet_size_total { 0 };
size_t m_packet_buffer_tail { 0 };
BAN::UniqPtr<VirtualRange> m_packet_buffer; BAN::UniqPtr<VirtualRange> m_packet_buffer;
mutable Mutex m_packet_lock; Mutex m_packet_lock;
ThreadBlocker m_packet_thread_blocker; ThreadBlocker m_packet_thread_blocker;
BAN::Atomic<size_t> m_sndbuf { 0 };
BAN::Atomic<size_t> m_bytes_sent { 0 };
friend class BAN::RefPtr<UnixDomainSocket>; friend class BAN::RefPtr<UnixDomainSocket>;
}; };

View File

@ -222,22 +222,6 @@ namespace Kernel
return getpeername_impl(address, address_len); return getpeername_impl(address, address_len);
} }
BAN::ErrorOr<void> Inode::getsockopt(int level, int option, void* value, socklen_t* value_len)
{
LockGuard _(m_mutex);
if (!mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
return getsockopt_impl(level, option, value, value_len);
}
BAN::ErrorOr<void> Inode::setsockopt(int level, int option, const void* value, socklen_t value_len)
{
LockGuard _(m_mutex);
if (!mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
return setsockopt_impl(level, option, value, value_len);
}
BAN::ErrorOr<size_t> Inode::read(off_t offset, BAN::ByteSpan buffer) BAN::ErrorOr<size_t> Inode::read(off_t offset, BAN::ByteSpan buffer)
{ {
LockGuard _(m_mutex); LockGuard _(m_mutex);

View File

@ -170,8 +170,8 @@ namespace Kernel
SpinLockGuard _(m_bound_socket_lock); SpinLockGuard _(m_bound_socket_lock);
if (bind_address.sin_port == 0) if (bind_address.sin_port == 0)
bind_address.sin_port = BAN::host_to_network_endian(TRY(find_free_port())); bind_address.sin_port = TRY(find_free_port());
const uint16_t port = BAN::network_endian_to_host(bind_address.sin_port); const uint16_t port = BAN::host_to_network_endian(bind_address.sin_port);
if (m_bound_sockets.contains(port)) if (m_bound_sockets.contains(port))
return BAN::Error::from_errno(EADDRINUSE); return BAN::Error::from_errno(EADDRINUSE);

View File

@ -245,7 +245,10 @@ namespace Kernel
BAN::ErrorOr<size_t> TCPSocket::sendmsg_impl(const msghdr& message, int flags) BAN::ErrorOr<size_t> TCPSocket::sendmsg_impl(const msghdr& message, int flags)
{ {
if (flags & ~(MSG_NOSIGNAL | MSG_DONTWAIT)) if (flags & MSG_NOSIGNAL)
dwarnln("sendmsg ignoring MSG_NOSIGNAL");
flags &= (MSG_EOR | MSG_OOB /* | MSG_NOSIGNAL */);
if (flags != 0)
{ {
dwarnln("TODO: sendmsg with flags 0x{H}", flags); dwarnln("TODO: sendmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP); return BAN::Error::from_errno(ENOTSUP);
@ -261,8 +264,6 @@ namespace Kernel
{ {
if (m_state != State::Established) if (m_state != State::Established)
return return_with_maybe_zero(); return return_with_maybe_zero();
if (flags & MSG_DONTWAIT)
return BAN::Error::from_errno(EAGAIN);
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex)); TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
} }
@ -296,34 +297,6 @@ namespace Kernel
return {}; return {};
} }
BAN::ErrorOr<void> TCPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
{
if (level != SOL_SOCKET)
return BAN::Error::from_errno(EINVAL);
int result;
switch (option)
{
case SO_ERROR:
result = 0;
break;
case SO_SNDBUF:
result = m_send_window.scaled_size();
break;
case SO_RCVBUF:
result = m_recv_window.buffer->size();
break;
default:
return BAN::Error::from_errno(ENOTSUP);
}
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
memcpy(value, &result, len);
*value_len = sizeof(int);
return {};
}
BAN::ErrorOr<long> TCPSocket::ioctl_impl(int request, void* argument) BAN::ErrorOr<long> TCPSocket::ioctl_impl(int request, void* argument)
{ {
switch (request) switch (request)
@ -463,7 +436,7 @@ namespace Kernel
}; };
auto interface = MUST(this->interface(reinterpret_cast<const sockaddr*>(&target), sizeof(target))); auto interface = MUST(this->interface(reinterpret_cast<const sockaddr*>(&target), sizeof(target)));
add_tcp_header_option<0, TCPOption::MaximumSeqmentSize>(header, interface->payload_mtu() - m_network_layer.header_size() - protocol_header_size()); add_tcp_header_option<0, TCPOption::MaximumSeqmentSize>(header, interface->payload_mtu() - m_network_layer.header_size());
if (m_connection_info->has_window_scale) if (m_connection_info->has_window_scale)
add_tcp_header_option<4, TCPOption::WindowScale>(header, m_recv_window.scale_shift); add_tcp_header_option<4, TCPOption::WindowScale>(header, m_recv_window.scale_shift);

View File

@ -162,7 +162,10 @@ namespace Kernel
BAN::ErrorOr<size_t> UDPSocket::sendmsg_impl(const msghdr& message, int flags) BAN::ErrorOr<size_t> UDPSocket::sendmsg_impl(const msghdr& message, int flags)
{ {
if (flags & ~(MSG_NOSIGNAL | MSG_DONTWAIT)) if (flags & MSG_NOSIGNAL)
dwarnln("sendmsg ignoring MSG_NOSIGNAL");
flags &= (MSG_EOR | MSG_OOB /* | MSG_NOSIGNAL */);
if (flags != 0)
{ {
dwarnln("TODO: sendmsg with flags 0x{H}", flags); dwarnln("TODO: sendmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP); return BAN::Error::from_errno(ENOTSUP);
@ -210,34 +213,6 @@ namespace Kernel
return TRY(m_network_layer.sendto(*this, buffer.span(), address, address_len)); return TRY(m_network_layer.sendto(*this, buffer.span(), address, address_len));
} }
BAN::ErrorOr<void> UDPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
{
if (level != SOL_SOCKET)
return BAN::Error::from_errno(EINVAL);
int result;
switch (option)
{
case SO_ERROR:
result = 0;
break;
case SO_SNDBUF:
result = m_packet_buffer->size();
break;
case SO_RCVBUF:
result = m_packet_buffer->size();
break;
default:
return BAN::Error::from_errno(ENOTSUP);
}
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
memcpy(value, &result, len);
*value_len = sizeof(int);
return {};
}
BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument) BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument)
{ {
switch (request) switch (request)

View File

@ -25,7 +25,7 @@ namespace Kernel
static BAN::HashMap<BAN::RefPtr<Inode>, BAN::WeakPtr<UnixDomainSocket>, UnixSocketHash> s_bound_sockets; static BAN::HashMap<BAN::RefPtr<Inode>, BAN::WeakPtr<UnixDomainSocket>, UnixSocketHash> s_bound_sockets;
static Mutex s_bound_socket_lock; static Mutex s_bound_socket_lock;
static constexpr size_t s_packet_buffer_size = 0x10000; static constexpr size_t s_packet_buffer_size = 10 * PAGE_SIZE;
static BAN::ErrorOr<BAN::StringView> validate_sockaddr_un(const sockaddr* address, socklen_t address_len) static BAN::ErrorOr<BAN::StringView> validate_sockaddr_un(const sockaddr* address, socklen_t address_len)
{ {
@ -45,6 +45,8 @@ namespace Kernel
return BAN::StringView { sockaddr_un.sun_path, length }; return BAN::StringView { sockaddr_un.sun_path, length };
} }
// FIXME: why is this using spinlocks instead of mutexes??
BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> UnixDomainSocket::create(Socket::Type socket_type, const Socket::Info& info) BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> UnixDomainSocket::create(Socket::Type socket_type, const Socket::Info& info)
{ {
auto socket = TRY(BAN::RefPtr<UnixDomainSocket>::create(socket_type, info)); auto socket = TRY(BAN::RefPtr<UnixDomainSocket>::create(socket_type, info));
@ -62,7 +64,6 @@ namespace Kernel
UnixDomainSocket::UnixDomainSocket(Socket::Type socket_type, const Socket::Info& info) UnixDomainSocket::UnixDomainSocket(Socket::Type socket_type, const Socket::Info& info)
: Socket(info) : Socket(info)
, m_socket_type(socket_type) , m_socket_type(socket_type)
, m_sndbuf(s_packet_buffer_size)
{ {
switch (socket_type) switch (socket_type)
{ {
@ -288,56 +289,28 @@ namespace Kernel
case Socket::Type::SEQPACKET: case Socket::Type::SEQPACKET:
case Socket::Type::DGRAM: case Socket::Type::DGRAM:
return false; return false;
default:
ASSERT_NOT_REACHED();
} }
ASSERT_NOT_REACHED();
} }
BAN::ErrorOr<size_t> UnixDomainSocket::add_packet(const msghdr& packet, PacketInfo&& packet_info, bool dont_block) BAN::ErrorOr<void> UnixDomainSocket::add_packet(const msghdr& packet, PacketInfo&& packet_info)
{ {
LockGuard _(m_packet_lock); LockGuard _(m_packet_lock);
const auto has_space = while (m_packet_infos.full() || m_packet_size_total + packet_info.size > s_packet_buffer_size)
[&]() -> bool
{
if (m_packet_infos.full())
return false;
if (is_streaming())
return m_packet_size_total < m_packet_buffer->size();
return m_packet_size_total + packet_info.size <= m_packet_buffer->size();
};
while (!has_space())
{
if (dont_block)
return BAN::Error::from_errno(EAGAIN);
TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &m_packet_lock)); TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &m_packet_lock));
}
if (auto available = m_packet_buffer->size() - m_packet_size_total; available < packet_info.size) uint8_t* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr() + m_packet_size_total);
size_t offset = 0;
for (int i = 0; i < packet.msg_iovlen; i++)
{ {
ASSERT(is_streaming()); memcpy(packet_buffer + offset, packet.msg_iov[i].iov_base, packet.msg_iov[i].iov_len);
packet_info.size = available; offset += packet.msg_iov[i].iov_len;
} }
uint8_t* packet_buffer_base_u8 = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr()); ASSERT(offset == packet_info.size);
size_t bytes_copied = 0;
for (int i = 0; i < packet.msg_iovlen && bytes_copied < packet_info.size; i++)
{
const uint8_t* iov_base_u8 = static_cast<const uint8_t*>(packet.msg_iov[i].iov_base);
const size_t to_copy = BAN::Math::min(packet.msg_iov[i].iov_len, packet_info.size - bytes_copied);
const size_t copy_offset = (m_packet_buffer_tail + m_packet_size_total + bytes_copied) % m_packet_buffer->size();
const size_t before_wrap = BAN::Math::min(to_copy, m_packet_buffer->size() - copy_offset);
memcpy(packet_buffer_base_u8 + copy_offset, iov_base_u8, before_wrap);
if (const size_t after_wrap = to_copy - before_wrap)
memcpy(packet_buffer_base_u8, iov_base_u8 + before_wrap, after_wrap);
bytes_copied += to_copy;
}
ASSERT(bytes_copied == packet_info.size);
m_packet_size_total += packet_info.size; m_packet_size_total += packet_info.size;
m_packet_infos.emplace(BAN::move(packet_info)); m_packet_infos.emplace(BAN::move(packet_info));
@ -345,7 +318,7 @@ namespace Kernel
epoll_notify(EPOLLIN); epoll_notify(EPOLLIN);
return bytes_copied; return {};
} }
bool UnixDomainSocket::can_read_impl() const bool UnixDomainSocket::can_read_impl() const
@ -361,13 +334,24 @@ namespace Kernel
return false; return false;
} }
LockGuard _(m_packet_lock);
return m_packet_size_total > 0; return m_packet_size_total > 0;
} }
bool UnixDomainSocket::can_write_impl() const bool UnixDomainSocket::can_write_impl() const
{ {
return m_bytes_sent < m_sndbuf; if (m_info.has<ConnectionInfo>())
{
auto& connection_info = m_info.get<ConnectionInfo>();
auto connection = connection_info.connection.lock();
if (!connection)
return false;
if (connection->m_packet_infos.full())
return false;
if (connection->m_packet_size_total >= s_packet_buffer_size)
return false;
}
return true;
} }
bool UnixDomainSocket::has_hungup_impl() const bool UnixDomainSocket::has_hungup_impl() const
@ -391,7 +375,6 @@ namespace Kernel
} }
LockGuard _(m_packet_lock); LockGuard _(m_packet_lock);
while (m_packet_size_total == 0) while (m_packet_size_total == 0)
{ {
if (m_info.has<ConnectionInfo>()) if (m_info.has<ConnectionInfo>())
@ -412,7 +395,7 @@ namespace Kernel
cheader->cmsg_len = message.msg_controllen; cheader->cmsg_len = message.msg_controllen;
size_t cheader_len = 0; size_t cheader_len = 0;
uint8_t* packet_buffer_base_u8 = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr()); uint8_t* packet_buffer = reinterpret_cast<uint8_t*>(m_packet_buffer->vaddr());
message.msg_flags = 0; message.msg_flags = 0;
@ -486,12 +469,7 @@ namespace Kernel
uint8_t* iov_base = static_cast<uint8_t*>(iov.iov_base); uint8_t* iov_base = static_cast<uint8_t*>(iov.iov_base);
const size_t nrecv = BAN::Math::min<size_t>(iov.iov_len - iov_offset, packet_info.size - packet_received); const size_t nrecv = BAN::Math::min<size_t>(iov.iov_len - iov_offset, packet_info.size - packet_received);
memcpy(iov_base + iov_offset, packet_buffer + packet_received, nrecv);
const size_t copy_offset = (m_packet_buffer_tail + packet_received) % m_packet_buffer->size();
const size_t before_wrap = BAN::Math::min<size_t>(nrecv, m_packet_buffer->size() - copy_offset);
memcpy(iov_base + iov_offset, packet_buffer_base_u8 + copy_offset, before_wrap);
if (const size_t after_wrap = nrecv - before_wrap)
memcpy(iov_base + iov_offset + before_wrap, packet_buffer_base_u8, after_wrap);
packet_received += nrecv; packet_received += nrecv;
@ -512,17 +490,12 @@ namespace Kernel
if (packet_info.size == 0) if (packet_info.size == 0)
m_packet_infos.pop(); m_packet_infos.pop();
m_packet_buffer_tail = (m_packet_buffer_tail + to_discard) % m_packet_buffer->size(); // FIXME: get rid of this memmove :)
memmove(packet_buffer, packet_buffer + to_discard, m_packet_size_total - to_discard);
m_packet_size_total -= to_discard; m_packet_size_total -= to_discard;
total_recv += packet_received; total_recv += packet_received;
if (auto sender = packet_info.sender.lock())
{
sender->m_bytes_sent -= to_discard;
sender->epoll_notify(EPOLLOUT);
}
// on linux ancillary data is a barrier on stream sockets, lets do the same // on linux ancillary data is a barrier on stream sockets, lets do the same
if (!is_streaming() || had_ancillary_data) if (!is_streaming() || had_ancillary_data)
break; break;
@ -532,12 +505,17 @@ namespace Kernel
m_packet_thread_blocker.unblock(); m_packet_thread_blocker.unblock();
epoll_notify(EPOLLOUT);
return total_recv; return total_recv;
} }
BAN::ErrorOr<size_t> UnixDomainSocket::sendmsg_impl(const msghdr& message, int flags) BAN::ErrorOr<size_t> UnixDomainSocket::sendmsg_impl(const msghdr& message, int flags)
{ {
if (flags & ~(MSG_NOSIGNAL | MSG_DONTWAIT)) if (flags & MSG_NOSIGNAL)
dwarnln("sendmsg ignoring MSG_NOSIGNAL");
flags &= (MSG_EOR | MSG_OOB /* | MSG_NOSIGNAL */);
if (flags != 0)
{ {
dwarnln("TODO: sendmsg with flags 0x{H}", flags); dwarnln("TODO: sendmsg with flags 0x{H}", flags);
return BAN::Error::from_errno(ENOTSUP); return BAN::Error::from_errno(ENOTSUP);
@ -551,14 +529,13 @@ namespace Kernel
return result; return result;
}(); }();
if (!is_streaming() && total_message_size > m_packet_buffer->size()) if (total_message_size > s_packet_buffer_size)
return BAN::Error::from_errno(EMSGSIZE); return BAN::Error::from_errno(ENOBUFS);
PacketInfo packet_info { PacketInfo packet_info {
.size = total_message_size, .size = total_message_size,
.fds = {}, .fds = {},
.ucred = {}, .ucred = {},
.sender = TRY(get_weak_ptr()),
}; };
for (const auto* header = CMSG_FIRSTHDR(&message); header; header = CMSG_NXTHDR(&message, header)) for (const auto* header = CMSG_FIRSTHDR(&message); header; header = CMSG_NXTHDR(&message, header))
@ -631,9 +608,8 @@ namespace Kernel
auto target = connection_info.connection.lock(); auto target = connection_info.connection.lock();
if (!target) if (!target)
return BAN::Error::from_errno(ENOTCONN); return BAN::Error::from_errno(ENOTCONN);
const size_t bytes_sent = TRY(target->add_packet(message, BAN::move(packet_info), flags & MSG_DONTWAIT)); TRY(target->add_packet(message, BAN::move(packet_info)));
m_bytes_sent += bytes_sent; return total_message_size;
return bytes_sent;
} }
else else
{ {
@ -650,7 +626,7 @@ namespace Kernel
Process::current().root_file().inode, Process::current().root_file().inode,
Process::current().credentials(), Process::current().credentials(),
absolute_path, absolute_path,
O_WRONLY O_RDWR
)).inode; )).inode;
} }
else else
@ -676,11 +652,9 @@ namespace Kernel
if (!target) if (!target)
return BAN::Error::from_errno(EDESTADDRREQ); return BAN::Error::from_errno(EDESTADDRREQ);
if (target->m_socket_type != m_socket_type) TRY(target->add_packet(message, BAN::move(packet_info)));
return BAN::Error::from_errno(EPROTOTYPE);
const auto bytes_sent = TRY(target->add_packet(message, BAN::move(packet_info), flags & MSG_DONTWAIT)); return total_message_size;
m_bytes_sent += bytes_sent;
return bytes_sent;
} }
} }
@ -704,58 +678,4 @@ namespace Kernel
return {}; return {};
} }
BAN::ErrorOr<void> UnixDomainSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
{
if (level != SOL_SOCKET)
return BAN::Error::from_errno(EINVAL);
int result;
switch (option)
{
case SO_ERROR:
result = 0;
break;
case SO_SNDBUF:
result = m_sndbuf;
break;
case SO_RCVBUF:
result = m_packet_buffer->size();
break;
default:
dwarnln("getsockopt(SOL_SOCKET, {})", option);
return BAN::Error::from_errno(ENOTSUP);
}
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
memcpy(value, &result, len);
*value_len = sizeof(int);
return {};
}
BAN::ErrorOr<void> UnixDomainSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len)
{
if (level != SOL_SOCKET)
return BAN::Error::from_errno(EINVAL);
switch (option)
{
case SO_SNDBUF:
{
if (value_len != sizeof(int))
return BAN::Error::from_errno(EINVAL);
const int new_sndbuf = *static_cast<const int*>(value);
if (new_sndbuf < 0)
return BAN::Error::from_errno(EINVAL);
m_sndbuf = new_sndbuf;
break;
}
default:
dwarnln("setsockopt(SOL_SOCKET, {})", option);
return BAN::Error::from_errno(ENOTSUP);
}
return {};
}
} }

View File

@ -795,7 +795,7 @@ namespace Kernel
LockGuard _(inode->m_mutex); LockGuard _(inode->m_mutex);
if (is_nonblock && !inode->can_read()) if (is_nonblock && !inode->can_read())
return BAN::Error::from_errno(EAGAIN); return BAN::Error::from_errno(EWOULDBLOCK);
return inode->recvmsg(message, flags); return inode->recvmsg(message, flags);
} }
@ -817,13 +817,12 @@ namespace Kernel
LockGuard _(inode->m_mutex); LockGuard _(inode->m_mutex);
if (inode->has_hungup()) if (inode->has_hungup())
{ {
if (!(flags & MSG_NOSIGNAL)) Thread::current().add_signal(SIGPIPE, {});
Thread::current().add_signal(SIGPIPE, {});
return BAN::Error::from_errno(EPIPE); return BAN::Error::from_errno(EPIPE);
} }
if (is_nonblock && !inode->can_write()) if (is_nonblock && !inode->can_write())
return BAN::Error::from_errno(EAGAIN); return BAN::Error::from_errno(EWOULDBLOCK);
return inode->sendmsg(message, flags | (is_nonblock ? MSG_DONTWAIT : 0)); return inode->sendmsg(message, flags);
} }
BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const

View File

@ -1674,13 +1674,20 @@ namespace Kernel
if (!inode->mode().ifsock()) if (!inode->mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK); return BAN::Error::from_errno(ENOTSOCK);
auto* buffer = TRY(validate_and_pin_pointer_access(user_option_value, option_len, true)); switch (option_name)
BAN::ScopeGuard _([buffer] { buffer->unpin(); }); {
case SO_ERROR:
{
option_len = BAN::Math::min<socklen_t>(option_len, sizeof(int));
const int zero { 0 };
TRY(write_to_user(user_option_value, &zero, option_len));
TRY(write_to_user(user_option_len, &option_len, sizeof(socklen_t)));
return 0;
}
}
TRY(inode->getsockopt(level, option_name, user_option_value, &option_len)); dwarnln("getsockopt(SOL_SOCKET, {})", option_name);
TRY(write_to_user(user_option_len, &option_len, sizeof(socklen_t))); return BAN::Error::from_errno(ENOTSUP);
return 0;
} }
BAN::ErrorOr<long> Process::sys_setsockopt(int socket, int level, int option_name, const void* user_option_value, socklen_t option_len) BAN::ErrorOr<long> Process::sys_setsockopt(int socket, int level, int option_name, const void* user_option_value, socklen_t option_len)
@ -1698,12 +1705,10 @@ namespace Kernel
if (!inode->mode().ifsock()) if (!inode->mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK); return BAN::Error::from_errno(ENOTSOCK);
auto* buffer = TRY(validate_and_pin_pointer_access(user_option_value, option_len, false)); (void)user_option_value;
BAN::ScopeGuard _([buffer] { buffer->unpin(); });
TRY(inode->setsockopt(level, option_name, user_option_value, option_len)); dwarnln("setsockopt(SOL_SOCKET, {})", option_name);
return BAN::Error::from_errno(ENOTSUP);
return 0;
} }
BAN::ErrorOr<long> Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len, int flags) BAN::ErrorOr<long> Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len, int flags)

View File

@ -18,7 +18,7 @@ typedef struct
{ {
short flags; short flags;
pid_t pgroup; pid_t pgroup;
struct sched_param schedparam; sched_param schedparam;
int schedpolicy; int schedpolicy;
sigset_t sigdefault; sigset_t sigdefault;
sigset_t sigmask; sigset_t sigmask;

View File

@ -123,15 +123,14 @@ struct linger
#define SOMAXCONN 4096 #define SOMAXCONN 4096
#define MSG_CTRUNC 0x001 #define MSG_CTRUNC 0x01
#define MSG_DONTROUTE 0x002 #define MSG_DONTROUTE 0x02
#define MSG_EOR 0x004 #define MSG_EOR 0x04
#define MSG_OOB 0x008 #define MSG_OOB 0x08
#define MSG_NOSIGNAL 0x010 #define MSG_NOSIGNAL 0x10
#define MSG_PEEK 0x020 #define MSG_PEEK 0x20
#define MSG_TRUNC 0x040 #define MSG_TRUNC 0x40
#define MSG_WAITALL 0x080 #define MSG_WAITALL 0x80
#define MSG_DONTWAIT 0x100
#define AF_UNSPEC 0 #define AF_UNSPEC 0
#define AF_INET 1 #define AF_INET 1

View File

@ -20,10 +20,9 @@ ssize_t readv(int fildes, const struct iovec* iov, int iovcnt)
if (ret <= 0) if (ret <= 0)
return result; return result;
nread += ret; nread += ret;
result += ret;
} }
result += nread;
} }
return result; return result;
} }
@ -45,9 +44,8 @@ ssize_t writev(int fildes, const struct iovec* iov, int iovcnt)
if (ret <= 0) if (ret <= 0)
return result; return result;
nwrite += ret; nwrite += ret;
result += ret;
} }
result += nwrite;
} }
return result; return result;
} }

View File

@ -45,9 +45,6 @@ namespace LibGUI
void fill_rect(int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t color); void fill_rect(int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t color);
void fill(uint32_t color) { return fill_rect(0, 0, width(), height(), color); } void fill(uint32_t color) { return fill_rect(0, 0, width(), height(), color); }
void clear_rect(int32_t x, int32_t y, uint32_t width, uint32_t height) { fill_rect(x, y, width, height, m_bg_color); }
void clear() { return clear_rect(0, 0, width(), height()); }
void copy_texture(const Texture& texture, int32_t x, int32_t y, uint32_t sub_x = 0, uint32_t sub_y = 0, uint32_t width = -1, uint32_t height = -1); void copy_texture(const Texture& texture, int32_t x, int32_t y, uint32_t sub_x = 0, uint32_t sub_y = 0, uint32_t width = -1, uint32_t height = -1);
void draw_character(uint32_t codepoint, const LibFont::Font& font, int32_t x, int32_t y, uint32_t color); void draw_character(uint32_t codepoint, const LibFont::Font& font, int32_t x, int32_t y, uint32_t color);

View File

@ -373,6 +373,8 @@ static void handle_copy_relocation(const LoadedElf& elf, const RelocT& reloc)
reinterpret_cast<void*>(src_elf->base + src_sym->st_value), reinterpret_cast<void*>(src_elf->base + src_sym->st_value),
symbol.st_size symbol.st_size
); );
src_sym->st_value = (elf.base + reloc.r_offset) - src_elf->base;
} }
template<typename RelocT> requires BAN::is_same_v<RelocT, ElfNativeRelocation> || BAN::is_same_v<RelocT, ElfNativeRelocationA> template<typename RelocT> requires BAN::is_same_v<RelocT, ElfNativeRelocation> || BAN::is_same_v<RelocT, ElfNativeRelocationA>
@ -925,8 +927,6 @@ static bool can_load_elf(int fd, const ElfNativeFileHeader& file_header, uintptr
return true; return true;
} }
// FIXME: Don't map read-only sections as writable with DT_TEXTREL.
// Instead mprotect the areas writable during relocation.
static void load_program_header(const ElfNativeProgramHeader& program_header, int fd, bool needs_writable) static void load_program_header(const ElfNativeProgramHeader& program_header, int fd, bool needs_writable)
{ {
if (program_header.p_type != PT_LOAD) if (program_header.p_type != PT_LOAD)
@ -966,7 +966,7 @@ static void load_program_header(const ElfNativeProgramHeader& program_header, in
mmap_args.flags = MAP_PRIVATE | MAP_FIXED; mmap_args.flags = MAP_PRIVATE | MAP_FIXED;
mmap_args.len = file_backed_size; mmap_args.len = file_backed_size;
mmap_args.off = program_header.p_offset; mmap_args.off = program_header.p_offset;
mmap_args.prot = prot | (needs_writable ? PROT_WRITE : 0); mmap_args.prot = prot | PROT_WRITE;
if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(program_header.p_vaddr)) if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(program_header.p_vaddr))
print_error_and_exit("could not load program header", ret); print_error_and_exit("could not load program header", ret);
@ -1002,13 +1002,12 @@ static void load_program_header(const ElfNativeProgramHeader& program_header, in
0x00, 0x00,
program_header.p_memsz - program_header.p_filesz program_header.p_memsz - program_header.p_filesz
); );
}
if (!(prot & PROT_WRITE) && !needs_writable) if (!(prot & PROT_WRITE) && !needs_writable)
{ {
if (auto ret = syscall(SYS_MPROTECT, program_header.p_vaddr + file_backed_size, program_header.p_memsz - file_backed_size, prot)) // FIXME: Implement mprotect so PROT_WRITE can be removed
print_error_and_exit("failed to remove PROT_WRITE from mapped", ret); //syscall(SYS_MPROTECT, start_vaddr, length, prot);
print(STDDBG_FILENO, "dropped PROT_WRITE :nekocatwoah:");
}
} }
} }

View File

@ -274,12 +274,6 @@ BAN::ErrorOr<void> Execute::execute_command(const PipedCommand& piped_command)
} }
); );
if (piped_command.commands[i].arguments.empty())
{
child_codes[i] = 0;
continue;
}
const int fd_in = last_pipe_rd; const int fd_in = last_pipe_rd;
const int fd_out = new_pipe[1]; const int fd_out = new_pipe[1];