Compare commits
No commits in common. "f022a1b08ffd73982eb24042c318f98b3cb982fb" and "c304133224af3f9866d00c8cb8a92d6a3aba1899" have entirely different histories.
f022a1b08f
...
c304133224
|
|
@ -126,7 +126,6 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +133,6 @@ namespace BAN
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,12 +157,11 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
@ -174,12 +171,11 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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); }
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 {};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1674,14 +1674,21 @@ 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:
|
||||||
TRY(inode->getsockopt(level, option_name, user_option_value, &option_len));
|
{
|
||||||
|
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)));
|
TRY(write_to_user(user_option_len, &option_len, sizeof(socklen_t)));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dwarnln("getsockopt(SOL_SOCKET, {})", option_name);
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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:");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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];
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue