Compare commits

..

No commits in common. "7691b019e2a3c282a2d10163a488763c60f5a7aa" and "6be3b1d7f2038945049eb4e7bfdcb94b0c7f9f25" have entirely different histories.

38 changed files with 125 additions and 498 deletions

View File

@ -111,7 +111,6 @@ namespace Kernel
BAN::ErrorOr<size_t> sendto(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len); BAN::ErrorOr<size_t> sendto(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<size_t> recvfrom(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len); BAN::ErrorOr<size_t> recvfrom(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len);
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);
// General API // General API
BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer); BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
@ -154,7 +153,6 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, 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> 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); }
// 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

@ -25,7 +25,6 @@ namespace Kernel
BAN::Vector<BAN::RefPtr<NetworkInterface>>& interfaces() { return m_interfaces; } BAN::Vector<BAN::RefPtr<NetworkInterface>>& interfaces() { return m_interfaces; }
BAN::ErrorOr<BAN::RefPtr<Socket>> create_socket(Socket::Domain, Socket::Type, mode_t, uid_t, gid_t); BAN::ErrorOr<BAN::RefPtr<Socket>> create_socket(Socket::Domain, Socket::Type, mode_t, uid_t, gid_t);
BAN::ErrorOr<void> connect_sockets(Socket::Domain, BAN::RefPtr<Socket>, BAN::RefPtr<Socket>);
void on_receive(NetworkInterface&, BAN::ConstByteSpan); void on_receive(NetworkInterface&, BAN::ConstByteSpan);

View File

@ -42,7 +42,6 @@ namespace Kernel
virtual BAN::ErrorOr<long> ioctl_impl(int request, void* arg) override; virtual BAN::ErrorOr<long> ioctl_impl(int request, void* arg) override;
virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) override; virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override = 0;
protected: protected:
NetworkLayer& m_network_layer; NetworkLayer& m_network_layer;

View File

@ -61,7 +61,6 @@ namespace Kernel
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override; virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) override; virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override; virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override; virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;

View File

@ -36,7 +36,6 @@ namespace Kernel
virtual BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override; virtual BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len) override; virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len) override; virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
virtual bool can_read_impl() const override { return !m_packets.empty(); } virtual bool can_read_impl() const override { return !m_packets.empty(); }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }

View File

@ -17,7 +17,6 @@ namespace Kernel
public: public:
static BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> create(Socket::Type, const Socket::Info&); static BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> create(Socket::Type, const Socket::Info&);
BAN::ErrorOr<void> make_socket_pair(UnixDomainSocket&);
protected: protected:
virtual BAN::ErrorOr<long> accept_impl(sockaddr*, socklen_t*, int) override; virtual BAN::ErrorOr<long> accept_impl(sockaddr*, socklen_t*, int) override;
@ -26,7 +25,6 @@ namespace Kernel
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override; virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) override; virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override; virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, 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;

View File

@ -26,7 +26,6 @@ namespace Kernel
BAN::ErrorOr<int> open(BAN::StringView absolute_path, int flags); BAN::ErrorOr<int> open(BAN::StringView absolute_path, int flags);
BAN::ErrorOr<int> socket(int domain, int type, int protocol); BAN::ErrorOr<int> socket(int domain, int type, int protocol);
BAN::ErrorOr<void> socketpair(int domain, int type, int protocol, int socket_vector[2]);
BAN::ErrorOr<void> pipe(int fds[2]); BAN::ErrorOr<void> pipe(int fds[2]);

View File

@ -112,15 +112,12 @@ namespace Kernel
BAN::ErrorOr<long> sys_symlinkat(const char* path1, int fd, const char* path2); BAN::ErrorOr<long> sys_symlinkat(const char* path1, int fd, const char* path2);
BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset); BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset);
BAN::ErrorOr<long> sys_pwrite(int fd, const void* buffer, size_t count, off_t offset);
BAN::ErrorOr<long> sys_fchmodat(int fd, const char* path, mode_t mode, int flag); BAN::ErrorOr<long> sys_fchmodat(int fd, const char* path, mode_t mode, int flag);
BAN::ErrorOr<long> sys_fchownat(int fd, const char* path, uid_t uid, gid_t gid, int flag); BAN::ErrorOr<long> sys_fchownat(int fd, const char* path, uid_t uid, gid_t gid, int flag);
BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol); BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
BAN::ErrorOr<long> sys_socketpair(int domain, int type, int protocol, int socket_vector[2]);
BAN::ErrorOr<long> sys_getsockname(int socket, sockaddr* address, socklen_t* address_len); BAN::ErrorOr<long> sys_getsockname(int socket, sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<long> sys_getpeername(int socket, sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<long> sys_getsockopt(int socket, int level, int option_name, void* option_value, socklen_t* option_len); BAN::ErrorOr<long> sys_getsockopt(int socket, int level, int option_name, void* option_value, socklen_t* option_len);
BAN::ErrorOr<long> sys_setsockopt(int socket, int level, int option_name, const void* option_value, socklen_t option_len); BAN::ErrorOr<long> sys_setsockopt(int socket, int level, int option_name, const void* option_value, socklen_t option_len);

View File

@ -186,14 +186,6 @@ namespace Kernel
return getsockname_impl(address, address_len); return getsockname_impl(address, address_len);
} }
BAN::ErrorOr<void> Inode::getpeername(sockaddr* address, socklen_t* address_len)
{
LockGuard _(m_mutex);
if (!mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
return getpeername_impl(address, address_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

@ -237,28 +237,21 @@ namespace Kernel
BAN::ErrorOr<void> E1000::enable_interrupt() BAN::ErrorOr<void> E1000::enable_interrupt()
{ {
TRY(m_pci_device.reserve_interrupts(1));
write32(REG_ITR, 0x1000); write32(REG_ITR, 0x1000);
if (m_pci_device.interrupt_mechanism() == PCI::Device::InterruptMechanism::MSIX)
{
write32(REG_IVAR, 1 << 3); write32(REG_IVAR, 1 << 3);
write32(REG_EITR, 0x1000); write32(REG_EITR, 0x1000);
write32(REG_IMS, IMC_RxQ0); write32(REG_IMS, IMC_RxQ0);
} read32(REG_ICR);
else
{
write32(REG_IMS, IMC_RXT0);
}
write32(REG_ICR, 0xFFFFFFFF);
TRY(m_pci_device.reserve_interrupts(1));
m_pci_device.enable_interrupt(0, *this); m_pci_device.enable_interrupt(0, *this);
return {}; return {};
} }
BAN::ErrorOr<void> E1000::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan buffer) BAN::ErrorOr<void> E1000::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan buffer)
{ {
ASSERT(buffer.size() + sizeof(EthernetHeader) <= E1000_TX_BUFFER_SIZE); ASSERT(buffer.size() + sizeof(EthernetHeader) <= E1000_TX_BUFFER_SIZE);
@ -292,7 +285,7 @@ namespace Kernel
void E1000::handle_irq() void E1000::handle_irq()
{ {
if (!(read32(REG_ICR) & (ICR_RxQ0 | ICR_RXT0))) if (!(read32(REG_ICR) & ICR_RxQ0))
return; return;
SpinLockGuard _(m_lock); SpinLockGuard _(m_lock);

View File

@ -129,25 +129,6 @@ namespace Kernel
return socket; return socket;
} }
BAN::ErrorOr<void> NetworkManager::connect_sockets(Socket::Domain domain, BAN::RefPtr<Socket> socket1, BAN::RefPtr<Socket> socket2)
{
switch (domain)
{
case Socket::Domain::UNIX:
{
auto* usocket1 = static_cast<UnixDomainSocket*>(socket1.ptr());
auto* usocket2 = static_cast<UnixDomainSocket*>(socket2.ptr());
TRY(usocket1->make_socket_pair(*usocket2));
break;
}
default:
dwarnln("TODO: connect {} domain sockets", static_cast<int>(domain));
return BAN::Error::from_errno(ENOTSUP);
}
return {};
}
void NetworkManager::on_receive(NetworkInterface& interface, BAN::ConstByteSpan packet) void NetworkManager::on_receive(NetworkInterface& interface, BAN::ConstByteSpan packet)
{ {
if (packet.size() < sizeof(EthernetHeader)) if (packet.size() < sizeof(EthernetHeader))

View File

@ -256,17 +256,6 @@ namespace Kernel
return to_send; return to_send;
} }
BAN::ErrorOr<void> TCPSocket::getpeername_impl(sockaddr* address, socklen_t* address_len)
{
if (!m_has_connected && m_state != State::Established)
return BAN::Error::from_errno(ENOTCONN);
ASSERT(m_connection_info.has_value());
const size_t to_copy = BAN::Math::min(m_connection_info->address_len, *address_len);
memcpy(address, &m_connection_info->address, to_copy);
*address_len = to_copy;
return {};
}
bool TCPSocket::can_read_impl() const bool TCPSocket::can_read_impl() const
{ {
if (m_has_connected && !m_has_sent_zero && m_state != State::Established && m_state != State::Listen) if (m_has_connected && !m_has_sent_zero && m_state != State::Established && m_state != State::Listen)
@ -503,8 +492,6 @@ namespace Kernel
connection_info, connection_info,
header.seq_number + 1 header.seq_number + 1
)); ));
epoll_notify(EPOLLIN);
} }
} }
else else

View File

@ -69,20 +69,6 @@ namespace Kernel
} }
} }
BAN::ErrorOr<void> UnixDomainSocket::make_socket_pair(UnixDomainSocket& other)
{
if (!m_info.has<ConnectionInfo>() || !other.m_info.has<ConnectionInfo>())
return BAN::Error::from_errno(EINVAL);
TRY(this->get_weak_ptr());
TRY(other.get_weak_ptr());
this->m_info.get<ConnectionInfo>().connection = MUST(other.get_weak_ptr());
other.m_info.get<ConnectionInfo>().connection = MUST(this->get_weak_ptr());
return {};
}
BAN::ErrorOr<long> UnixDomainSocket::accept_impl(sockaddr* address, socklen_t* address_len, int flags) BAN::ErrorOr<long> UnixDomainSocket::accept_impl(sockaddr* address, socklen_t* address_len, int flags)
{ {
if (!m_info.has<ConnectionInfo>()) if (!m_info.has<ConnectionInfo>())
@ -426,33 +412,4 @@ namespace Kernel
return nread; return nread;
} }
BAN::ErrorOr<void> UnixDomainSocket::getpeername_impl(sockaddr* address, socklen_t* address_len)
{
if (!m_info.has<ConnectionInfo>())
return BAN::Error::from_errno(ENOTCONN);
auto connection = m_info.get<ConnectionInfo>().connection.lock();
if (!connection)
return BAN::Error::from_errno(ENOTCONN);
sockaddr_un sa_un;
sa_un.sun_family = AF_UNIX;
sa_un.sun_path[0] = 0;
{
SpinLockGuard _(s_bound_socket_lock);
for (auto& [path, socket] : s_bound_sockets)
{
if (socket.lock() != connection)
continue;
strcpy(sa_un.sun_path, path.data());
break;
}
}
const size_t to_copy = BAN::Math::min<socklen_t>(sizeof(sockaddr_un), *address_len);
memcpy(address, &sa_un, to_copy);
*address_len = to_copy;
return {};
}
} }

View File

@ -83,57 +83,50 @@ namespace Kernel
return open(TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)), flags); return open(TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)), flags);
} }
struct SocketInfo BAN::ErrorOr<int> OpenFileDescriptorSet::socket(int domain, int type, int protocol)
{ {
Socket::Domain domain;
Socket::Type type;
int status_flags;
int descriptor_flags;
};
static BAN::ErrorOr<SocketInfo> parse_socket_info(int domain, int type, int protocol)
{
SocketInfo info;
bool valid_protocol = true; bool valid_protocol = true;
Socket::Domain sock_domain;
switch (domain) switch (domain)
{ {
case AF_INET: case AF_INET:
info.domain = Socket::Domain::INET; sock_domain = Socket::Domain::INET;
break; break;
case AF_INET6: case AF_INET6:
info.domain = Socket::Domain::INET6; sock_domain = Socket::Domain::INET6;
break; break;
case AF_UNIX: case AF_UNIX:
info.domain = Socket::Domain::UNIX; sock_domain = Socket::Domain::UNIX;
valid_protocol = false; valid_protocol = false;
break; break;
default: default:
return BAN::Error::from_errno(EPROTOTYPE); return BAN::Error::from_errno(EPROTOTYPE);
} }
info.status_flags = 0; int status_flags = 0;
info.descriptor_flags = 0; int descriptor_flags = 0;
if (type & SOCK_NONBLOCK) if (type & SOCK_NONBLOCK)
info.status_flags |= O_NONBLOCK; status_flags |= O_NONBLOCK;
if (type & SOCK_CLOEXEC) if (type & SOCK_CLOEXEC)
info.descriptor_flags |= O_CLOEXEC; descriptor_flags |= O_CLOEXEC;
type &= ~(SOCK_NONBLOCK | SOCK_CLOEXEC); type &= ~(SOCK_NONBLOCK | SOCK_CLOEXEC);
Socket::Type sock_type;
switch (type) switch (type)
{ {
case SOCK_STREAM: case SOCK_STREAM:
info.type = Socket::Type::STREAM; sock_type = Socket::Type::STREAM;
if (protocol != IPPROTO_TCP) if (protocol != IPPROTO_TCP)
valid_protocol = false; valid_protocol = false;
break; break;
case SOCK_DGRAM: case SOCK_DGRAM:
info.type = Socket::Type::DGRAM; sock_type = Socket::Type::DGRAM;
if (protocol != IPPROTO_UDP) if (protocol != IPPROTO_UDP)
valid_protocol = false; valid_protocol = false;
break; break;
case SOCK_SEQPACKET: case SOCK_SEQPACKET:
info.type = Socket::Type::SEQPACKET; sock_type = Socket::Type::SEQPACKET;
valid_protocol = false; valid_protocol = false;
break; break;
default: default:
@ -143,39 +136,15 @@ namespace Kernel
if (protocol && !valid_protocol) if (protocol && !valid_protocol)
return BAN::Error::from_errno(EPROTONOSUPPORT); return BAN::Error::from_errno(EPROTONOSUPPORT);
return info; auto socket = TRY(NetworkManager::get().create_socket(sock_domain, sock_type, 0777, m_credentials.euid(), m_credentials.egid()));
}
BAN::ErrorOr<int> OpenFileDescriptorSet::socket(int domain, int type, int protocol)
{
auto sock_info = TRY(parse_socket_info(domain, type, protocol));
auto socket = TRY(NetworkManager::get().create_socket(sock_info.domain, sock_info.type, 0777, m_credentials.euid(), m_credentials.egid()));
LockGuard _(m_mutex); LockGuard _(m_mutex);
int fd = TRY(get_free_fd()); int fd = TRY(get_free_fd());
m_open_files[fd].description = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(socket, "<socket>"_sv), 0, O_RDWR | sock_info.status_flags)); m_open_files[fd].description = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(socket, "<socket>"_sv), 0, O_RDWR | status_flags));
m_open_files[fd].descriptor_flags = sock_info.descriptor_flags; m_open_files[fd].descriptor_flags = descriptor_flags;
return fd; return fd;
} }
BAN::ErrorOr<void> OpenFileDescriptorSet::socketpair(int domain, int type, int protocol, int socket_vector[2])
{
auto sock_info = TRY(parse_socket_info(domain, type, protocol));
auto socket1 = TRY(NetworkManager::get().create_socket(sock_info.domain, sock_info.type, 0600, m_credentials.euid(), m_credentials.egid()));
auto socket2 = TRY(NetworkManager::get().create_socket(sock_info.domain, sock_info.type, 0600, m_credentials.euid(), m_credentials.egid()));
TRY(NetworkManager::get().connect_sockets(sock_info.domain, socket1, socket2));
LockGuard _(m_mutex);
TRY(get_free_fd_pair(socket_vector));
m_open_files[socket_vector[0]].description = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(socket1, "<socketpair>"_sv), 0, O_RDWR | sock_info.status_flags));
m_open_files[socket_vector[0]].descriptor_flags = sock_info.descriptor_flags;
m_open_files[socket_vector[1]].description = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(socket2, "<socketpair>"_sv), 0, O_RDWR | sock_info.status_flags));
m_open_files[socket_vector[1]].descriptor_flags = sock_info.descriptor_flags;
return {};
}
BAN::ErrorOr<void> OpenFileDescriptorSet::pipe(int fds[2]) BAN::ErrorOr<void> OpenFileDescriptorSet::pipe(int fds[2])
{ {
LockGuard _(m_mutex); LockGuard _(m_mutex);

View File

@ -682,9 +682,9 @@ namespace Kernel::PCI
auto& prt_entry_fields = prt_entry.as.package->elements; auto& prt_entry_fields = prt_entry.as.package->elements;
if (TRY(ACPI::AML::convert_node(TRY(prt_entry_fields[0].value.node->copy()), ACPI::AML::ConvInteger, -1)).as.integer.value != acpi_device_id) if (TRY(ACPI::AML::convert_node(TRY(prt_entry_fields[0].value.node->copy()), ACPI::AML::ConvInteger, -1)).as.integer.value != acpi_device_id)
continue; return BAN::Error::from_errno(ENOENT);
if (TRY(ACPI::AML::convert_node(TRY(prt_entry_fields[1].value.node->copy()), ACPI::AML::ConvInteger, -1)).as.integer.value != acpi_pin) if (TRY(ACPI::AML::convert_node(TRY(prt_entry_fields[1].value.node->copy()), ACPI::AML::ConvInteger, -1)).as.integer.value != acpi_pin)
continue; return BAN::Error::from_errno(ENOENT);
auto ret = route_prt_entry(prt_entry); auto ret = route_prt_entry(prt_entry);
if (!ret.is_error()) if (!ret.is_error())
@ -714,14 +714,16 @@ namespace Kernel::PCI
return InterruptMechanism::NONE; return InterruptMechanism::NONE;
} }
if (m_offset_msi_x.has_value()) const bool is_xhci = false && m_class_code == 0x0C && m_subclass == 0x03 && m_prog_if == 0x30;
if (!is_xhci && m_offset_msi_x.has_value())
{ {
const uint16_t msg_ctrl = read_word(*m_offset_msi_x + 0x02); const uint16_t msg_ctrl = read_word(*m_offset_msi_x + 0x02);
if (count <= (msg_ctrl & 0x7FF) + 1) if (count <= (msg_ctrl & 0x7FF) + 1)
return InterruptMechanism::MSIX; return InterruptMechanism::MSIX;
} }
if (m_offset_msi.has_value()) if (!is_xhci && m_offset_msi.has_value())
{ {
if (count == 1) if (count == 1)
return InterruptMechanism::MSI; return InterruptMechanism::MSI;

View File

@ -301,14 +301,8 @@ namespace Kernel
); );
} }
for (size_t i = 0; i < m_threads.size(); i++) while (!m_threads.empty())
{ m_threads.front()->on_exit();
if (m_threads[i] == &Thread::current())
continue;
m_threads[i]->add_signal(SIGKILL);
}
Thread::current().on_exit();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
@ -1198,22 +1192,16 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_pread(int fd, void* buffer, size_t count, off_t offset) BAN::ErrorOr<long> Process::sys_pread(int fd, void* buffer, size_t count, off_t offset)
{ {
auto inode = TRY(m_open_file_descriptors.inode_of(fd)); LockGuard _(m_process_lock);
if (count == 0)
auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, true));
BAN::ScopeGuard _([buffer_region]{ if (buffer_region) buffer_region->unpin(); });
return TRY(inode->read(offset, { reinterpret_cast<uint8_t*>(buffer), count }));
}
BAN::ErrorOr<long> Process::sys_pwrite(int fd, const void* buffer, size_t count, off_t offset)
{ {
TRY(m_open_file_descriptors.inode_of(fd));
return 0;
}
TRY(validate_pointer_access(buffer, count, true));
auto inode = TRY(m_open_file_descriptors.inode_of(fd)); auto inode = TRY(m_open_file_descriptors.inode_of(fd));
return TRY(inode->read(offset, { (uint8_t*)buffer, count }));
auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, false)); }
BAN::ScopeGuard _([buffer_region]{ if (buffer_region) buffer_region->unpin(); });
return TRY(inode->write(offset, { reinterpret_cast<const uint8_t*>(buffer), count })); }
BAN::ErrorOr<long> Process::sys_fchmodat(int fd, const char* path, mode_t mode, int flag) BAN::ErrorOr<long> Process::sys_fchmodat(int fd, const char* path, mode_t mode, int flag)
{ {
@ -1270,14 +1258,6 @@ namespace Kernel
return TRY(m_open_file_descriptors.socket(domain, type, protocol)); return TRY(m_open_file_descriptors.socket(domain, type, protocol));
} }
BAN::ErrorOr<long> Process::sys_socketpair(int domain, int type, int protocol, int socket_vector[2])
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(socket_vector, sizeof(int) * 2, true));
TRY(m_open_file_descriptors.socketpair(domain, type, protocol, socket_vector));
return 0;
}
BAN::ErrorOr<long> Process::sys_getsockname(int socket, sockaddr* address, socklen_t* address_len) BAN::ErrorOr<long> Process::sys_getsockname(int socket, sockaddr* address, socklen_t* address_len)
{ {
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
@ -1292,20 +1272,6 @@ namespace Kernel
return 0; return 0;
} }
BAN::ErrorOr<long> Process::sys_getpeername(int socket, sockaddr* address, socklen_t* address_len)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(address_len, sizeof(address_len), true));
TRY(validate_pointer_access(address, *address_len, true));
auto inode = TRY(m_open_file_descriptors.inode_of(socket));
if (!inode->mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
TRY(inode->getpeername(address, address_len));
return 0;
}
BAN::ErrorOr<long> Process::sys_getsockopt(int socket, int level, int option_name, void* option_value, socklen_t* option_len) BAN::ErrorOr<long> Process::sys_getsockopt(int socket, int level, int option_name, void* option_value, socklen_t* option_len)
{ {
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
@ -2338,10 +2304,14 @@ namespace Kernel
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
TRY(m_exited_pthreads.emplace_back(Thread::current().tid(), value)); TRY(m_exited_pthreads.emplace_back(Thread::current().tid(), value));
for (auto* thread : m_threads)
{
if (thread != &Thread::current())
continue;
m_pthread_exit_blocker.unblock(); m_pthread_exit_blocker.unblock();
m_process_lock.unlock(); m_process_lock.unlock();
Thread::current().on_exit(); thread->on_exit();
}
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }

View File

@ -39,7 +39,6 @@ set(LIBC_SOURCES
sys/stat.cpp sys/stat.cpp
sys/statvfs.cpp sys/statvfs.cpp
sys/time.cpp sys/time.cpp
sys/uio.cpp
sys/utsname.cpp sys/utsname.cpp
sys/wait.cpp sys/wait.cpp
syslog.cpp syslog.cpp

View File

@ -2,7 +2,6 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <netinet/in.h>
#include <stdio.h> #include <stdio.h>
uint32_t htonl(uint32_t hostlong) uint32_t htonl(uint32_t hostlong)

View File

@ -19,7 +19,7 @@ static int malloc_environ()
ASSERT(!s_environ_malloced); ASSERT(!s_environ_malloced);
size_t environ_count = 0; size_t environ_count = 0;
while (environ && environ[environ_count]) while (environ[environ_count])
environ_count++; environ_count++;
const size_t bitmap_size = (environ_count + 7) / 8; const size_t bitmap_size = (environ_count + 7) / 8;
@ -111,37 +111,12 @@ static int putenv_impl(char* string, bool malloced)
return 0; return 0;
} }
int clearenv(void)
{
if (s_environ_malloced)
{
ASSERT(environ);
for (size_t i = 0; environ[i]; i++)
{
const size_t byte = i / 8;
const size_t mask = 1 << (i % 8);
if (s_environ_bitmap[byte] & mask)
free(environ[i]);
}
free(s_environ_bitmap);
free(environ);
}
environ = nullptr;
s_environ_count = 0;
s_environ_bitmap = nullptr;
s_environ_malloced = false;
return 0;
}
char* getenv(const char* name) char* getenv(const char* name)
{ {
if (environ == nullptr) if (environ == nullptr)
return nullptr; return nullptr;
const size_t namelen = strlen(name); const size_t namelen = strlen(name);
for (size_t i = 0; environ[i]; i++) for (int i = 0; environ[i]; i++)
if (strncmp(name, environ[i], namelen) == 0) if (strncmp(name, environ[i], namelen) == 0)
if (environ[i][namelen] == '=') if (environ[i][namelen] == '=')
return environ[i] + namelen + 1; return environ[i] + namelen + 1;
@ -179,9 +154,6 @@ int unsetenv(const char* name)
return -1; return -1;
} }
if (environ == nullptr)
return 0;
const size_t namelen = strlen(name); const size_t namelen = strlen(name);
size_t i = 0; size_t i = 0;

View File

@ -1,5 +1,5 @@
#ifndef _ARPA_INET_H #ifndef _INET_H
#define _ARPA_INET_H 1 #define _INET_H 1
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/arpa_inet.h.html // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/arpa_inet.h.html
@ -7,8 +7,13 @@
__BEGIN_DECLS __BEGIN_DECLS
#include <bits/inet_common.h> #include <netinet/in.h>
#include <bits/types/socklen_t.h> #include <inttypes.h>
uint32_t htonl(uint32_t);
uint16_t htons(uint16_t);
uint32_t ntohl(uint32_t);
uint16_t ntohs(uint16_t);
in_addr_t inet_addr(const char* cp); in_addr_t inet_addr(const char* cp);
char* inet_ntoa(struct in_addr in); char* inet_ntoa(struct in_addr in);

View File

@ -1,28 +0,0 @@
#ifndef _BITS_INET_COMMON_H
#define _BITS_INET_COMMON_H 1
#include <sys/cdefs.h>
__BEGIN_DECLS
#include <inttypes.h>
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
uint32_t htonl(uint32_t);
uint16_t htons(uint16_t);
uint32_t ntohl(uint32_t);
uint16_t ntohs(uint16_t);
__END_DECLS
#endif

View File

@ -1,12 +0,0 @@
#ifndef _BITS_TYPES_SOCKLEN_T_H
#define _BITS_TYPES_SOCKLEN_T_H 1
#include <sys/cdefs.h>
__BEGIN_DECLS
typedef long socklen_t;
__END_DECLS
#endif

View File

@ -7,7 +7,7 @@
__BEGIN_DECLS __BEGIN_DECLS
#include <bits/inet_common.h> #include <inttypes.h>
#include <sys/socket.h> #include <sys/socket.h>
#define IPPROTO_IP 1 #define IPPROTO_IP 1
@ -30,6 +30,9 @@ __BEGIN_DECLS
#define INADDR_BROADCAST 0xFFFFFFFF #define INADDR_BROADCAST 0xFFFFFFFF
#define INADDR_LOOPBACK 0x7F000001 #define INADDR_LOOPBACK 0x7F000001
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
@ -48,6 +51,14 @@ __BEGIN_DECLS
#define IN6_IS_ADDR_MC_GLOBAL(addr) #define IN6_IS_ADDR_MC_GLOBAL(addr)
#endif #endif
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
struct sockaddr_in struct sockaddr_in
{ {
sa_family_t sin_family; /* AF_INET. */ sa_family_t sin_family; /* AF_INET. */

View File

@ -57,8 +57,8 @@ struct uthread
#define PTHREAD_SPIN_INITIALIZER (pthread_spinlock_t)0 #define PTHREAD_SPIN_INITIALIZER (pthread_spinlock_t)0
#define PTHREAD_COND_INITIALIZER (pthread_cond_t){ { CLOCK_REALTIME, 0 }, PTHREAD_SPIN_INITIALIZER, NULL } #define PTHREAD_COND_INITIALIZER (pthread_cond_t){ { CLOCK_REALTIME, 0 }, PTHREAD_SPIN_INITIALIZER, NULL }
#define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t){ { PTHREAD_MUTEX_DEFAULT, 0 }, 0, 0 } #define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t){ { PTHREAD_MUTEX_DEFAULT, false }, 0, 0 }
#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t){ { 0 }, 0, 0 } #define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t){ { false }, 0, 0 }
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void(*child)(void)); int pthread_atfork(void (*prepare)(void), void (*parent)(void), void(*child)(void));
int pthread_attr_destroy(pthread_attr_t* attr); int pthread_attr_destroy(pthread_attr_t* attr);

View File

@ -51,7 +51,6 @@ long atol(const char* str);
long long atoll(const char* str); long long atoll(const char* str);
void* bsearch(const void* key, const void* base, size_t nel, size_t width, int (*compar)(const void*, const void*)); void* bsearch(const void* key, const void* base, size_t nel, size_t width, int (*compar)(const void*, const void*));
void* calloc(size_t nelem, size_t elsize); void* calloc(size_t nelem, size_t elsize);
int clearenv(void);
div_t div(int numer, int denom); div_t div(int numer, int denom);
double drand48(void); double drand48(void);
double erand48(unsigned short xsubi[3]); double erand48(unsigned short xsubi[3]);

View File

@ -14,7 +14,7 @@ __BEGIN_DECLS
#include <sys/uio.h> #include <sys/uio.h>
#include <bits/types/sa_family_t.h> #include <bits/types/sa_family_t.h>
#include <bits/types/socklen_t.h> typedef long socklen_t;
#if !defined(FILENAME_MAX) #if !defined(FILENAME_MAX)
#define FILENAME_MAX 256 #define FILENAME_MAX 256

View File

@ -60,11 +60,9 @@ __BEGIN_DECLS
O(SYS_READLINKAT, readlinkat) \ O(SYS_READLINKAT, readlinkat) \
O(SYS_MSYNC, msync) \ O(SYS_MSYNC, msync) \
O(SYS_PREAD, pread) \ O(SYS_PREAD, pread) \
O(SYS_PWRITE, pwrite) \
O(SYS_FCHOWNAT, fchownat) \ O(SYS_FCHOWNAT, fchownat) \
O(SYS_LOAD_KEYMAP, load_keymap) \ O(SYS_LOAD_KEYMAP, load_keymap) \
O(SYS_SOCKET, socket) \ O(SYS_SOCKET, socket) \
O(SYS_SOCKETPAIR, socketpair) \
O(SYS_BIND, bind) \ O(SYS_BIND, bind) \
O(SYS_SENDTO, sendto) \ O(SYS_SENDTO, sendto) \
O(SYS_RECVFROM, recvfrom) \ O(SYS_RECVFROM, recvfrom) \
@ -79,7 +77,6 @@ __BEGIN_DECLS
O(SYS_SMO_MAP, smo_map) \ O(SYS_SMO_MAP, smo_map) \
O(SYS_ISATTY, isatty) \ O(SYS_ISATTY, isatty) \
O(SYS_GETSOCKNAME, getsockname) \ O(SYS_GETSOCKNAME, getsockname) \
O(SYS_GETPEERNAME, getpeername) \
O(SYS_GETSOCKOPT, getsockopt) \ O(SYS_GETSOCKOPT, getsockopt) \
O(SYS_SETSOCKOPT, setsockopt) \ O(SYS_SETSOCKOPT, setsockopt) \
O(SYS_REALPATH, realpath) \ O(SYS_REALPATH, realpath) \

View File

@ -33,36 +33,6 @@ int gettimeofday(struct timeval* __restrict tp, void* __restrict tzp);
int setitimer(int which, const struct itimerval* __restrict value, struct itimerval* __restrict ovalue); int setitimer(int which, const struct itimerval* __restrict value, struct itimerval* __restrict ovalue);
int utimes(const char* path, const struct timeval times[2]); int utimes(const char* path, const struct timeval times[2]);
#define timeradd(a, b, res) \
do { \
(res)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(res)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
(res)->tv_sec += (res)->tv_usec / 1000000; \
(res)->tv_usec %= 1000000; \
} while (0)
#define timersub(a, b, res) \
do { \
(res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
(res)->tv_sec += (res)->tv_usec / 1000000; \
(res)->tv_usec %= 1000000; \
} while (0)
#define timerclear(tvp) \
do { \
(tvp)->tv_sec = 0; \
(tvp)->tv_usec = 0; \
} while (0)
#define timerisset(tvp) \
((tvp)->tv_sec || (tvp)->tv_usec)
#define timercmp(a, b, CMP) \
(((a)->tv_sec == (b)->tv_sec) \
? ((a)->tv_usec CMP (b)->tv_usec) \
: ((a)->tv_sec CMP (b)->tv_sec))
__END_DECLS __END_DECLS
#endif #endif

View File

@ -185,8 +185,6 @@ __BEGIN_DECLS
typedef int bits32_t; typedef int bits32_t;
typedef unsigned int u_bits32_t; typedef unsigned int u_bits32_t;
typedef char* bits64_t; typedef char* bits64_t;
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int; typedef unsigned int u_int;
typedef unsigned long u_long; typedef unsigned long u_long;
#endif #endif

View File

@ -70,7 +70,7 @@ int getaddrinfo(const char* __restrict nodename, const char* __restrict servname
return EAI_SOCKTYPE; return EAI_SOCKTYPE;
} }
if (!nodename && !servname) if (!nodename)
return EAI_NONAME; return EAI_NONAME;
int port = 0; int port = 0;
@ -147,34 +147,9 @@ error_close_socket:
return EAI_FAIL; return EAI_FAIL;
} }
#include <BAN/Debug.h> int getnameinfo(const struct sockaddr* __restrict, socklen_t, char* __restrict, socklen_t, char* __restrict, socklen_t, int)
int getnameinfo(const struct sockaddr* __restrict sa, socklen_t salen, char* __restrict node, socklen_t nodelen, char* __restrict service, socklen_t servicelen, int flags)
{ {
printf("getnameinfo(%p, %p, %p, 0x%X)\n", sa, node, service, flags); ASSERT_NOT_REACHED();
switch (sa->sa_family)
{
case AF_INET:
if (salen < static_cast<socklen_t>(sizeof(sockaddr_in)))
return EAI_FAMILY;
if (service && snprintf(service, servicelen, "%d", reinterpret_cast<sockaddr_in*>(service)->sin_port) < 0)
return EAI_SYSTEM;
break;
case AF_INET6:
if (salen < static_cast<socklen_t>(sizeof(sockaddr_in6)))
return EAI_FAMILY;
if (service && snprintf(service, servicelen, "%d", reinterpret_cast<sockaddr_in6*>(service)->sin6_port) < 0)
return EAI_SYSTEM;
break;
default:
return EAI_FAIL;
}
if (node && inet_ntop(sa->sa_family, sa, node, nodelen) == nullptr)
return EAI_SYSTEM;
return 0;
} }
struct hostent* gethostbyname(const char* name) struct hostent* gethostbyname(const char* name)

View File

@ -552,7 +552,6 @@ extern "C" int printf_impl(const char* format, va_list arguments, int (*putc_fun
conversion[0] = va_arg(arguments, int); conversion[0] = va_arg(arguments, int);
conversion[1] = '\0'; conversion[1] = '\0';
string = conversion; string = conversion;
length = 1;
format++; format++;
break; break;
} }
@ -634,7 +633,7 @@ extern "C" int printf_impl(const char* format, va_list arguments, int (*putc_fun
for (int i = length; i < options.width; i++) for (int i = length; i < options.width; i++)
BAN_PRINTF_PUTC(' '); BAN_PRINTF_PUTC(' ');
for (int i = 0; i < length; i++) for (int i = 0; i < length && string[i]; i++)
BAN_PRINTF_PUTC(string[i]); BAN_PRINTF_PUTC(string[i]);
if (options.left_justified) if (options.left_justified)

View File

@ -82,9 +82,12 @@ static void init_closed_file(FILE* file)
static int drop_read_buffer(FILE* file) static int drop_read_buffer(FILE* file)
{ {
const off_t bytes_remaining = file->buffer_rd_size - file->buffer_idx; if (file->buffer_rd_size == 0)
if (bytes_remaining > 0) return 0;
if (syscall(SYS_SEEK, file->fd, -bytes_remaining, SEEK_CUR) == -1) ASSERT(file->buffer_idx != 0);
if (file->buffer_idx == 1)
return 0;
if (syscall(SYS_SEEK, file->fd, file->buffer_idx - 1, SEEK_CUR) == -1)
return EOF; return EOF;
file->buffer_rd_size = 0; file->buffer_rd_size = 0;
file->buffer_idx = 0; file->buffer_idx = 0;
@ -449,7 +452,8 @@ int fseeko(FILE* file, off_t offset, int whence)
ScopeLock _(file); ScopeLock _(file);
if (fflush(file) == EOF) if (fflush(file) == EOF)
return -1; return -1;
if (syscall(SYS_SEEK, file->fd, offset, whence) == -1) long ret = syscall(SYS_SEEK, file->fd, offset, whence);
if (ret < 0)
return -1; return -1;
file->eof = false; file->eof = false;
return 0; return 0;
@ -468,12 +472,12 @@ long ftell(FILE* file)
off_t ftello(FILE* file) off_t ftello(FILE* file)
{ {
ScopeLock _(file); ScopeLock _(file);
auto offset = syscall(SYS_TELL, file->fd); if (fflush(file) == EOF)
if (offset == -1)
return -1; return -1;
if (file->buffer_rd_size) long ret = syscall(SYS_TELL, file->fd);
offset -= file->buffer_rd_size - file->buffer_idx; if (ret < 0)
return offset - file->unget_buf_idx; return -1;
return ret;
} }
int ftrylockfile(FILE* fp) int ftrylockfile(FILE* fp)
@ -537,7 +541,10 @@ int getc_unlocked(FILE* file)
if (file->unget_buf_idx) if (file->unget_buf_idx)
{ {
file->unget_buf_idx--; file->unget_buf_idx--;
return file->unget_buffer[file->unget_buf_idx]; unsigned char ch = file->unget_buffer[file->unget_buf_idx];
if (fseeko(file, 1, SEEK_CUR) == -1)
return EOF;
return ch;
} }
// read from unbuffered file // read from unbuffered file
@ -575,6 +582,8 @@ int getc_unlocked(FILE* file)
((nread == 0) ? file->eof : file->error) = true; ((nread == 0) ? file->eof : file->error) = true;
return EOF; return EOF;
} }
if (fseeko(file, 1 - nread, SEEK_CUR) == -1)
return EOF;
file->buffer_rd_size = nread; file->buffer_rd_size = nread;
file->buffer_idx = 1; file->buffer_idx = 1;
return file->buffer[0]; return file->buffer[0];
@ -956,29 +965,7 @@ char* tempnam(const char*, const char*);
FILE* tmpfile(void) FILE* tmpfile(void)
{ {
for (;;) ASSERT_NOT_REACHED();
{
char path[PATH_MAX];
if (tmpnam(path) == nullptr)
return nullptr;
int fd = open(path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1)
{
if (errno == EEXIST)
continue;
return nullptr;
}
(void)unlink(path);
FILE* fp = fdopen(fd, "wb+");
if (fp != nullptr)
return fp;
close(fd);
return nullptr;
}
} }
char* tmpnam(char* storage) char* tmpnam(char* storage)
@ -1011,6 +998,9 @@ int ungetc_unlocked(int c, FILE* stream)
return EOF; return EOF;
} }
if (fseeko(stream, -1, SEEK_CUR) == -1)
return EOF;
stream->unget_buffer[stream->unget_buf_idx] = c; stream->unget_buffer[stream->unget_buf_idx] = c;
stream->unget_buf_idx++; stream->unget_buf_idx++;
stream->eof = false; stream->eof = false;

View File

@ -69,8 +69,10 @@ static constexpr int get_base_digit(char c, int base)
} }
template<BAN::integral T> template<BAN::integral T>
static constexpr bool will_digit_append_overflow(T current, int digit, int base) static constexpr bool will_digit_append_overflow(bool negative, T current, int digit, int base)
{ {
if (BAN::is_unsigned_v<T> && negative && digit)
return true;
if (BAN::Math::will_multiplication_overflow<T>(current, base)) if (BAN::Math::will_multiplication_overflow<T>(current, base))
return true; return true;
if (BAN::Math::will_addition_overflow<T>(current * base, current < 0 ? -digit : digit)) if (BAN::Math::will_addition_overflow<T>(current * base, current < 0 ? -digit : digit))
@ -84,8 +86,6 @@ static T strtoT(const char* str, char** endp, int base, int& error)
// validate base // validate base
if (base != 0 && (base < 2 || base > 36)) if (base != 0 && (base < 2 || base > 36))
{ {
if (endp)
*endp = const_cast<char*>(str);
error = EINVAL; error = EINVAL;
return 0; return 0;
} }
@ -134,17 +134,10 @@ static T strtoT(const char* str, char** endp, int base, int& error)
break; break;
str++; str++;
overflow = will_digit_append_overflow(result, digit, base); overflow = will_digit_append_overflow(negative, result, digit, base);
if (!overflow) if (!overflow)
{ result = result * base + (negative ? -digit : digit);
if (negative && !BAN::is_unsigned_v<T>)
digit = -digit;
result = result * base + digit;
} }
}
if (negative && BAN::is_unsigned_v<T>)
result = -result;
// save endp if asked // save endp if asked
if (endp) if (endp)
@ -547,26 +540,6 @@ char* ptsname(int fildes)
return buffer; return buffer;
} }
int mblen(const char* s, size_t n)
{
if (s == nullptr)
return 0;
if (n == 0)
return -1;
switch (__getlocale(LC_CTYPE))
{
case LOCALE_INVALID:
ASSERT_NOT_REACHED();
case LOCALE_POSIX:
return 1;
case LOCALE_UTF8:
if (const auto bytes = BAN::UTF8::byte_length(*s); n >= bytes)
return bytes;
return -1;
}
ASSERT_NOT_REACHED();
}
size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n) size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n)
{ {
auto* us = reinterpret_cast<const unsigned char*>(s); auto* us = reinterpret_cast<const unsigned char*>(s);

View File

@ -147,12 +147,11 @@ char* strcat(char* __restrict__ dest, const char* __restrict__ src)
char* strncat(char* __restrict__ dest, const char* __restrict__ src, size_t n) char* strncat(char* __restrict__ dest, const char* __restrict__ src, size_t n)
{ {
char* ret = dest;
dest += strlen(dest); dest += strlen(dest);
while (*src && n--) while (*src && n--)
*dest++ = *src++; *dest++ = *src++;
*dest = '\0'; *dest = '\0';
return ret; return dest;
} }
int strcoll(const char* s1, const char* s2) int strcoll(const char* s1, const char* s2)

View File

@ -68,21 +68,11 @@ int socket(int domain, int type, int protocol)
return syscall(SYS_SOCKET, domain, type, protocol); return syscall(SYS_SOCKET, domain, type, protocol);
} }
int socketpair(int domain, int type, int protocol, int socket_vector[2])
{
return syscall(SYS_SOCKETPAIR, domain, type, protocol, socket_vector);
}
int getsockname(int socket, struct sockaddr* __restrict address, socklen_t* __restrict address_len) int getsockname(int socket, struct sockaddr* __restrict address, socklen_t* __restrict address_len)
{ {
return syscall(SYS_GETSOCKNAME, socket, address, address_len); return syscall(SYS_GETSOCKNAME, socket, address, address_len);
} }
int getpeername(int socket, struct sockaddr* __restrict address, socklen_t* __restrict address_len)
{
return syscall(SYS_GETPEERNAME, socket, address, address_len);
}
int getsockopt(int socket, int level, int option_name, void* __restrict option_value, socklen_t* __restrict option_len) int getsockopt(int socket, int level, int option_name, void* __restrict option_value, socklen_t* __restrict option_len)
{ {
return syscall(SYS_GETSOCKOPT, socket, level, option_name, option_value, option_len); return syscall(SYS_GETSOCKOPT, socket, level, option_name, option_value, option_len);
@ -97,6 +87,11 @@ int setsockopt(int socket, int level, int option_name, const void* option_value,
#include <BAN/Assert.h> #include <BAN/Assert.h>
int getpeername(int, struct sockaddr* __restrict, socklen_t* __restrict)
{
ASSERT_NOT_REACHED();
}
int shutdown(int, int) int shutdown(int, int)
{ {
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();

View File

@ -1,46 +0,0 @@
#include <sys/uio.h>
#include <unistd.h>
ssize_t readv(int fildes, const struct iovec* iov, int iovcnt)
{
size_t result = 0;
for (int i = 0; i < iovcnt; i++)
{
uint8_t* base = static_cast<uint8_t*>(iov->iov_base);
size_t nread = 0;
while (nread < iov[i].iov_len)
{
const ssize_t ret = read(fildes, base + nread, iov[i].iov_len - nread);
if (ret == -1 && result == 0)
return -1;
if (ret <= 0)
return result;
nread += ret;
}
result += nread;
}
return result;
}
ssize_t writev(int fildes, const struct iovec* iov, int iovcnt)
{
size_t result = 0;
for (int i = 0; i < iovcnt; i++)
{
const uint8_t* base = static_cast<const uint8_t*>(iov->iov_base);
size_t nwrite = 0;
while (nwrite < iov[i].iov_len)
{
const ssize_t ret = write(fildes, base + nwrite, iov[i].iov_len - nwrite);
if (ret == -1 && result == 0)
return -1;
if (ret <= 0)
return result;
nwrite += ret;
}
result += nwrite;
}
return result;
}

View File

@ -9,10 +9,6 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
int daylight;
long timezone;
char* tzname[2];
int clock_gettime(clockid_t clock_id, struct timespec* tp) int clock_gettime(clockid_t clock_id, struct timespec* tp)
{ {
return syscall(SYS_CLOCK_GETTIME, clock_id, tp); return syscall(SYS_CLOCK_GETTIME, clock_id, tp);
@ -131,8 +127,8 @@ time_t mktime(struct tm* tm)
tm->tm_mon %= 12; tm->tm_mon %= 12;
tm->tm_yday = tm->tm_mday - 1; tm->tm_yday = tm->tm_mday - 1;
for (int i = 0; i < tm->tm_mon; i++) if (tm->tm_mon > 0)
tm->tm_yday += month_days[i]; tm->tm_yday += month_days[tm->tm_mon - 1];
const time_t num_febs = (tm->tm_mon > 1) ? tm->tm_year + 1 : tm->tm_year; const time_t num_febs = (tm->tm_mon > 1) ? tm->tm_year + 1 : tm->tm_year;
const time_t leap_years = (num_febs - 69) / 4 - (num_febs - 1) / 100 + (num_febs + 299) / 400; const time_t leap_years = (num_febs - 69) / 4 - (num_febs - 1) / 100 + (num_febs + 299) / 400;
@ -200,14 +196,6 @@ struct tm* localtime(const time_t* timer)
return localtime_r(timer, &tm); return localtime_r(timer, &tm);
} }
void tzset()
{
daylight = 0;
timezone = 0;
tzname[0] = const_cast<char*>("UTC");
tzname[1] = const_cast<char*>("UTC");
}
size_t strftime(char* __restrict s, size_t maxsize, const char* __restrict format, const struct tm* __restrict timeptr) size_t strftime(char* __restrict s, size_t maxsize, const char* __restrict format, const struct tm* __restrict timeptr)
{ {
size_t len = 0; size_t len = 0;
@ -556,3 +544,13 @@ size_t strftime(char* __restrict s, size_t maxsize, const char* __restrict forma
s[len++] = '\0'; s[len++] = '\0';
return len; return len;
} }
#include <BAN/Assert.h>
long timezone;
void tzset()
{
ASSERT_NOT_REACHED();
}

View File

@ -127,11 +127,6 @@ ssize_t pread(int fildes, void* buf, size_t nbyte, off_t offset)
return syscall(SYS_PREAD, fildes, buf, nbyte, offset); return syscall(SYS_PREAD, fildes, buf, nbyte, offset);
} }
ssize_t pwrite(int fildes, const void* buf, size_t nbyte, off_t offset)
{
return syscall(SYS_PWRITE, fildes, buf, nbyte, offset);
}
off_t lseek(int fildes, off_t offset, int whence) off_t lseek(int fildes, off_t offset, int whence)
{ {
return syscall(SYS_SEEK, fildes, offset, whence); return syscall(SYS_SEEK, fildes, offset, whence);