Compare commits

..

No commits in common. "0ff365c7f043f4972a8952cf77172ab97d089ad9" and "70bbdbd8f5683708bde8563e6b6381093c68dc30" have entirely different histories.

58 changed files with 314 additions and 1467 deletions

View File

@ -34,6 +34,4 @@ signal_trampoline:
addl $8, %esp
popf
movl (%esp), %esp
ret

View File

@ -59,7 +59,5 @@ signal_trampoline:
addq $16, %rsp
popfq
movq (%rsp), %rsp
// return over red-zone
ret $128

View File

@ -1,179 +0,0 @@
#pragma once
#include <BAN/ByteSpan.h>
#include <BAN/Debug.h>
#include <BAN/Optional.h>
namespace Kernel::ACPI
{
struct ResourceData
{
enum class Type
{
IRQ,
DMA,
IOPort,
FixedIOPort,
FixedDMA,
// TODO: large stuff the stuff :)
};
union {
struct {
uint16_t irq_mask;
union {
struct {
uint8_t edge_triggered : 1;
uint8_t : 2;
uint8_t active_low : 1;
uint8_t shared : 1;
uint8_t wake_capable : 1;
uint8_t : 2;
};
uint8_t raw;
};
} irq;
struct {
uint8_t channel_mask;
union {
struct {
uint8_t type : 2; // 0: 8 bit, 1: 8 and 16 bit, 2: 16 bit only
uint8_t bus_master : 1;
uint8_t : 2;
uint8_t channel_speed : 2; // 0: compatibility, 1: type A, 2: type B, 3: type F
uint8_t : 1;
};
uint8_t raw;
};
} dma;
struct {
uint16_t range_min_base;
uint16_t range_max_base;
uint8_t base_alignment;
uint8_t range_length;
} io_port;
struct {
uint16_t range_base;
uint8_t range_length;
} fixed_io_port;
struct {
uint16_t request_line;
uint16_t channel;
uint8_t transfer_width; // 0: 8 bit, 1: 16 bit, 2: 32 bit, 3: 64 bit, 4: 128 bit
} fixed_dma;
} as;
Type type;
};
class ResourceParser
{
public:
ResourceParser(BAN::ConstByteSpan buffer)
: m_buffer(buffer)
{}
BAN::Optional<ResourceData> get_next()
{
for (;;)
{
if (m_buffer.empty())
return {};
if (m_buffer[0] & 0x80)
{
dprintln("Skipping large resource 0x{2H}", m_buffer[0] & 0x7F);
const uint16_t length = (m_buffer[2] << 8) | m_buffer[1];
if (m_buffer.size() < static_cast<size_t>(3 + length))
return {};
m_buffer = m_buffer.slice(3 + length);
continue;
}
const uint8_t length = m_buffer[0] & 0x07;
if (m_buffer.size() < static_cast<size_t>(1 + length))
return {};
BAN::Optional<ResourceData> result;
switch ((m_buffer[0] >> 3) & 0x0F)
{
case 0x04:
if (length < 2)
break;
result = ResourceData {
.as = { .irq = {
.irq_mask = static_cast<uint16_t>((m_buffer[2] << 8) | m_buffer[1]),
.raw = (length >= 3) ? m_buffer[3] : static_cast<uint8_t>(1),
}},
.type = ResourceData::Type::IRQ,
};
break;
case 0x05:
if (length < 2)
break;
result = ResourceData {
.as = { .dma = {
.channel_mask = m_buffer[1],
.raw = m_buffer[2],
}},
.type = ResourceData::Type::DMA,
};
break;
case 0x08:
if (length < 7)
break;
result = ResourceData {
.as = { .io_port = {
.range_min_base = static_cast<uint16_t>(((m_buffer[3] << 8) | m_buffer[2]) & ((m_buffer[1] & 1) ? 0xFFFF : 0x03FF)),
.range_max_base = static_cast<uint16_t>(((m_buffer[5] << 8) | m_buffer[4]) & ((m_buffer[1] & 1) ? 0xFFFF : 0x03FF)),
.base_alignment = m_buffer[6],
.range_length = m_buffer[7],
}},
.type = ResourceData::Type::IOPort,
};
break;
case 0x09:
if (length < 3)
break;
result = ResourceData {
.as = { .fixed_io_port = {
.range_base = static_cast<uint16_t>(((m_buffer[2] << 8) | m_buffer[1]) & 0x03FF),
.range_length = m_buffer[3],
}},
.type = ResourceData::Type::FixedIOPort,
};
break;
case 0x0A:
if (length < 5)
break;
result = ResourceData {
.as = { .fixed_dma = {
.request_line = static_cast<uint16_t>((m_buffer[2] << 8) | m_buffer[1]),
.channel = static_cast<uint16_t>((m_buffer[4] << 8) | m_buffer[3]),
.transfer_width = m_buffer[5],
}},
.type = ResourceData::Type::FixedDMA,
};
break;
case 0x0F:
// End tag
return {};
case 0x06:
case 0x07:
case 0x0E:
dprintln("Skipping short resource 0x{2H}", (m_buffer[0] >> 3) & 0x0F);
break;
}
m_buffer = m_buffer.slice(1 + length);
if (result.has_value())
return result.release_value();
}
}
private:
BAN::ConstByteSpan m_buffer;
};
}

View File

@ -193,9 +193,6 @@ namespace Kernel
BAN::ErrorOr<long> sys_sigaction(int signal, const struct sigaction* act, struct sigaction* oact);
BAN::ErrorOr<long> sys_sigpending(sigset_t* set);
BAN::ErrorOr<long> sys_sigprocmask(int how, const sigset_t* set, sigset_t* oset);
BAN::ErrorOr<long> sys_sigsuspend(const sigset_t* set);
BAN::ErrorOr<long> sys_sigwait(const sigset_t* set, int* sig);
BAN::ErrorOr<long> sys_sigaltstack(const stack_t* ss, stack_t* oss);
BAN::ErrorOr<long> sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime);
BAN::ErrorOr<long> sys_yield();
@ -350,6 +347,14 @@ namespace Kernel
BAN::UniqPtr<PageTable> m_page_table;
BAN::RefPtr<TTY> m_controlling_terminal;
struct futex_t
{
ThreadBlocker blocker;
uint32_t waiters { 0 };
uint32_t to_wakeup { 0 };
};
BAN::HashMap<paddr_t, BAN::UniqPtr<futex_t>> m_futexes;
friend class Thread;
};

View File

@ -1,7 +1,6 @@
#pragma once
#include <BAN/NoCopyMove.h>
#include <BAN/Optional.h>
#include <BAN/RefPtr.h>
#include <BAN/UniqPtr.h>
#include <kernel/InterruptStack.h>
@ -60,10 +59,7 @@ namespace Kernel
bool will_execute_signal() const;
// Returns true if handled signal had SA_RESTART
bool handle_signal(int signal = 0);
void add_signal(int signal);
void set_suspend_signal_mask(uint64_t sigmask);
BAN::ErrorOr<void> sigaltstack(const stack_t* ss, stack_t* oss);
bool add_signal(int signal);
// blocks current thread and returns either on unblock, eintr, spuriously or after timeout
// if mutex is not nullptr, it will be atomically freed before blocking and automatically locked on wake
@ -142,8 +138,6 @@ namespace Kernel
static void on_exit_trampoline(Thread*);
void on_exit();
bool currently_on_alternate_stack() const;
private:
// NOTE: this is the first member to force it being last destructed
// {kernel,userspace}_stack has to be destroyed before page table
@ -166,9 +160,7 @@ namespace Kernel
uint64_t m_signal_pending_mask { 0 };
uint64_t m_signal_block_mask { 0 };
BAN::Optional<uint64_t> m_signal_suspend_mask;
SpinLock m_signal_lock;
stack_t m_signal_alt_stack { nullptr, 0, SS_DISABLE };
static_assert(_SIGMAX < 64);
mutable SpinLock m_cpu_time_lock;

View File

@ -438,7 +438,7 @@ namespace Kernel::ACPI::AML
{
dprintln_if(AML_DUMP_FUNCTION_CALLS, "find_named_object('{}', '{}')", scope, name_string);
if (force_absolute || name_string.base != 0 || name_string.parts.size() > 1)
if (force_absolute || name_string.base != 0)
{
// Absolute path
@ -460,15 +460,23 @@ namespace Kernel::ACPI::AML
// Relative path
Scope path_guess;
TRY(path_guess.parts.reserve(scope.parts.size() + 1));
const uint32_t name_seg = name_string.parts.front();
TRY(path_guess.parts.reserve(scope.parts.size() + name_string.parts.size()));
for (const auto& part : scope.parts)
TRY(path_guess.parts.push_back(part));
TRY(path_guess.parts.push_back(name_seg));
for (const auto& part : name_string.parts)
TRY(path_guess.parts.push_back(part));
for (;;)
auto it = m_named_objects.find(path_guess);
if (it != m_named_objects.end()) {
return FindResult {
.path = BAN::move(path_guess),
.node = it->value,
};
}
for (size_t i = 0; i < scope.parts.size(); i++)
{
path_guess.parts.remove(scope.parts.size() - i - 1);
auto it = m_named_objects.find(path_guess);
if (it != m_named_objects.end()) {
return FindResult {
@ -476,17 +484,12 @@ namespace Kernel::ACPI::AML
.node = it->value,
};
}
if (path_guess.parts.size() == 1) {
return FindResult {
.path = {},
.node = nullptr,
};
}
path_guess.parts.pop_back();
path_guess.parts.back() = name_seg;
}
return FindResult {
.path = {},
.node = nullptr,
};
}
BAN::ErrorOr<Scope> Namespace::find_reference_scope(const Reference* reference)

View File

@ -30,19 +30,19 @@ namespace Kernel
timespec FATInode::atime() const
{
const time_t epoch = fat_date_to_epoch(m_entry.last_access_date, {});
uint64_t epoch = fat_date_to_epoch(m_entry.last_access_date, {});
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
}
timespec FATInode::mtime() const
{
const time_t epoch = fat_date_to_epoch(m_entry.write_date, m_entry.write_time);
uint64_t epoch = fat_date_to_epoch(m_entry.write_date, m_entry.write_time);
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
}
timespec FATInode::ctime() const
{
const time_t epoch = fat_date_to_epoch(m_entry.creation_date, m_entry.creation_time);
uint64_t epoch = fat_date_to_epoch(m_entry.creation_date, m_entry.creation_time);
return timespec { .tv_sec = epoch, .tv_nsec = 0 };
}

View File

@ -256,84 +256,84 @@ namespace Kernel::Input
void PS2Keymap::initialize_scancode_set3()
{
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 0);
m_scancode_to_keycode_normal[0x16] = keycode_normal(0, 1);
m_scancode_to_keycode_normal[0x1E] = keycode_normal(0, 2);
m_scancode_to_keycode_normal[0x26] = keycode_normal(0, 3);
m_scancode_to_keycode_normal[0x25] = keycode_normal(0, 4);
m_scancode_to_keycode_normal[0x2E] = keycode_normal(0, 5);
m_scancode_to_keycode_normal[0x36] = keycode_normal(0, 6);
m_scancode_to_keycode_normal[0x3D] = keycode_normal(0, 7);
m_scancode_to_keycode_normal[0x3E] = keycode_normal(0, 8);
m_scancode_to_keycode_normal[0x46] = keycode_normal(0, 9);
m_scancode_to_keycode_normal[0x45] = keycode_normal(0, 10);
m_scancode_to_keycode_normal[0x4E] = keycode_normal(0, 11);
m_scancode_to_keycode_normal[0x55] = keycode_normal(0, 12);
m_scancode_to_keycode_normal[0x66] = keycode_normal(0, 13);
m_scancode_to_keycode_normal[0x0D] = keycode_normal(1, 0);
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 1);
m_scancode_to_keycode_normal[0x1D] = keycode_normal(1, 2);
m_scancode_to_keycode_normal[0x24] = keycode_normal(1, 3);
m_scancode_to_keycode_normal[0x2D] = keycode_normal(1, 4);
m_scancode_to_keycode_normal[0x2C] = keycode_normal(1, 5);
m_scancode_to_keycode_normal[0x35] = keycode_normal(1, 6);
m_scancode_to_keycode_normal[0x3C] = keycode_normal(1, 7);
m_scancode_to_keycode_normal[0x43] = keycode_normal(1, 8);
m_scancode_to_keycode_normal[0x44] = keycode_normal(1, 9);
m_scancode_to_keycode_normal[0x4D] = keycode_normal(1, 10);
m_scancode_to_keycode_normal[0x54] = keycode_normal(1, 11);
m_scancode_to_keycode_normal[0x5B] = keycode_normal(1, 12);
m_scancode_to_keycode_normal[0x14] = keycode_normal(2, 0);
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 1);
m_scancode_to_keycode_normal[0x1B] = keycode_normal(2, 2);
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 3);
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 4);
m_scancode_to_keycode_normal[0x34] = keycode_normal(2, 5);
m_scancode_to_keycode_normal[0x33] = keycode_normal(2, 6);
m_scancode_to_keycode_normal[0x3B] = keycode_normal(2, 7);
m_scancode_to_keycode_normal[0x42] = keycode_normal(2, 8);
m_scancode_to_keycode_normal[0x4B] = keycode_normal(2, 9);
m_scancode_to_keycode_normal[0x4C] = keycode_normal(2, 10);
m_scancode_to_keycode_normal[0x52] = keycode_normal(2, 11);
m_scancode_to_keycode_normal[0x5C] = keycode_normal(2, 12);
m_scancode_to_keycode_normal[0x5A] = keycode_normal(2, 13);
m_scancode_to_keycode_normal[0x12] = keycode_normal(3, 0);
m_scancode_to_keycode_normal[0x13] = keycode_normal(3, 1);
m_scancode_to_keycode_normal[0x1A] = keycode_normal(3, 2);
m_scancode_to_keycode_normal[0x22] = keycode_normal(3, 3);
m_scancode_to_keycode_normal[0x21] = keycode_normal(3, 4);
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 5);
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 6);
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
m_scancode_to_keycode_normal[0x3A] = keycode_normal(3, 8);
m_scancode_to_keycode_normal[0x41] = keycode_normal(3, 9);
m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10);
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11);
m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12);
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 0);
m_scancode_to_keycode_normal[0x8B] = keycode_normal(4, 1);
m_scancode_to_keycode_normal[0x19] = keycode_normal(4, 2);
m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 3);
m_scancode_to_keycode_normal[0x39] = keycode_normal(4, 4);
m_scancode_to_keycode_normal[0x58] = keycode_normal(4, 5);
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 0);
m_scancode_to_keycode_normal[0x16] = keycode_normal(0, 1);
m_scancode_to_keycode_normal[0x1E] = keycode_normal(0, 2);
m_scancode_to_keycode_normal[0x26] = keycode_normal(0, 3);
m_scancode_to_keycode_normal[0x25] = keycode_normal(0, 4);
m_scancode_to_keycode_normal[0x2E] = keycode_normal(0, 5);
m_scancode_to_keycode_normal[0x36] = keycode_normal(0, 6);
m_scancode_to_keycode_normal[0x3D] = keycode_normal(0, 7);
m_scancode_to_keycode_normal[0x3E] = keycode_normal(0, 8);
m_scancode_to_keycode_normal[0x46] = keycode_normal(0, 9);
m_scancode_to_keycode_normal[0x45] = keycode_normal(0, 10);
m_scancode_to_keycode_normal[0x4E] = keycode_normal(0, 11);
m_scancode_to_keycode_normal[0x55] = keycode_normal(0, 12);
m_scancode_to_keycode_normal[0x66] = keycode_normal(0, 13);
m_scancode_to_keycode_normal[0x0D] = keycode_normal(1, 0);
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 1);
m_scancode_to_keycode_normal[0x1D] = keycode_normal(1, 2);
m_scancode_to_keycode_normal[0x24] = keycode_normal(1, 3);
m_scancode_to_keycode_normal[0x2D] = keycode_normal(1, 4);
m_scancode_to_keycode_normal[0x2C] = keycode_normal(1, 5);
m_scancode_to_keycode_normal[0x35] = keycode_normal(1, 6);
m_scancode_to_keycode_normal[0x3C] = keycode_normal(1, 7);
m_scancode_to_keycode_normal[0x43] = keycode_normal(1, 8);
m_scancode_to_keycode_normal[0x44] = keycode_normal(1, 9);
m_scancode_to_keycode_normal[0x4D] = keycode_normal(1, 10);
m_scancode_to_keycode_normal[0x54] = keycode_normal(1, 11);
m_scancode_to_keycode_normal[0x5B] = keycode_normal(1, 12);
m_scancode_to_keycode_normal[0x14] = keycode_normal(2, 0);
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 1);
m_scancode_to_keycode_normal[0x1B] = keycode_normal(2, 2);
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 3);
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 4);
m_scancode_to_keycode_normal[0x34] = keycode_normal(2, 5);
m_scancode_to_keycode_normal[0x33] = keycode_normal(2, 6);
m_scancode_to_keycode_normal[0x3B] = keycode_normal(2, 7);
m_scancode_to_keycode_normal[0x42] = keycode_normal(2, 8);
m_scancode_to_keycode_normal[0x4B] = keycode_normal(2, 9);
m_scancode_to_keycode_normal[0x4C] = keycode_normal(2, 10);
m_scancode_to_keycode_normal[0x52] = keycode_normal(2, 11);
m_scancode_to_keycode_normal[0x5C] = keycode_normal(2, 12);
m_scancode_to_keycode_normal[0x5A] = keycode_normal(2, 13);
m_scancode_to_keycode_normal[0x12] = keycode_normal(3, 0);
m_scancode_to_keycode_normal[0x13] = keycode_normal(3, 1);
m_scancode_to_keycode_normal[0x1A] = keycode_normal(3, 2);
m_scancode_to_keycode_normal[0x22] = keycode_normal(3, 3);
m_scancode_to_keycode_normal[0x21] = keycode_normal(3, 4);
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 5);
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 6);
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
m_scancode_to_keycode_normal[0x3A] = keycode_normal(3, 8);
m_scancode_to_keycode_normal[0x41] = keycode_normal(3, 9);
m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10);
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11);
m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12);
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 0);
m_scancode_to_keycode_normal[0x8B] = keycode_normal(4, 1);
m_scancode_to_keycode_normal[0x19] = keycode_normal(4, 2);
m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 3);
m_scancode_to_keycode_normal[0x39] = keycode_normal(4, 4);
m_scancode_to_keycode_normal[0x58] = keycode_normal(4, 5);
m_scancode_to_keycode_normal[0x76] = keycode_numpad(0, 0);
m_scancode_to_keycode_normal[0x4A] = keycode_numpad(0, 1);
//m_scancode_to_keycode_normal[0x] = keycode_numpad(0, 1);
m_scancode_to_keycode_normal[0x7E] = keycode_numpad(0, 2);
m_scancode_to_keycode_normal[0x4E] = keycode_numpad(0, 3);
m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 0);
m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 1);
m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 2);
m_scancode_to_keycode_normal[0x7C] = keycode_numpad(1, 3);
m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 0);
m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 1);
m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 2);
m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 0);
m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 1);
m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 2);
m_scancode_to_keycode_normal[0x79] = keycode_numpad(3, 3);
m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 0);
m_scancode_to_keycode_normal[0x71] = keycode_numpad(4, 1);
//m_scancode_to_keycode_normal[0x] = keycode_numpad(0, 3);
m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 1);
m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 2);
m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 3);
m_scancode_to_keycode_normal[0x7C] = keycode_numpad(1, 4);
m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 1);
m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 2);
m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 3);
m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 1);
m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 2);
m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 3);
m_scancode_to_keycode_normal[0x79] = keycode_numpad(3, 4);
m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 1);
m_scancode_to_keycode_normal[0x71] = keycode_numpad(4, 2);
m_scancode_to_keycode_normal[0x08] = keycode_function(0);
m_scancode_to_keycode_normal[0x07] = keycode_function(1);

View File

@ -289,10 +289,10 @@ namespace Kernel
BAN::ErrorOr<void> UnixDomainSocket::add_packet(BAN::ConstByteSpan packet)
{
SpinLockGuard guard(m_packet_lock);
auto state = m_packet_lock.lock();
while (m_packet_sizes.full() || m_packet_size_total + packet.size() > s_packet_buffer_size)
{
SpinLockGuardAsMutex smutex(guard);
SpinLockAsMutex smutex(m_packet_lock, state);
TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &smutex));
}
@ -304,6 +304,7 @@ namespace Kernel
m_packet_sizes.push(packet.size());
m_packet_thread_blocker.unblock();
m_packet_lock.unlock(state);
epoll_notify(EPOLLIN);
@ -413,7 +414,7 @@ namespace Kernel
BAN::ErrorOr<size_t> UnixDomainSocket::recvfrom_impl(BAN::ByteSpan buffer, sockaddr*, socklen_t*)
{
SpinLockGuard guard(m_packet_lock);
auto state = m_packet_lock.lock();
while (m_packet_size_total == 0)
{
if (m_info.has<ConnectionInfo>())
@ -421,12 +422,18 @@ namespace Kernel
auto& connection_info = m_info.get<ConnectionInfo>();
bool expected = true;
if (connection_info.target_closed.compare_exchange(expected, false))
{
m_packet_lock.unlock(state);
return 0;
}
if (!connection_info.connection)
{
m_packet_lock.unlock(state);
return BAN::Error::from_errno(ENOTCONN);
}
}
SpinLockGuardAsMutex smutex(guard);
SpinLockAsMutex smutex(m_packet_lock, state);
TRY(Thread::current().block_or_eintr_indefinite(m_packet_thread_blocker, &smutex));
}
@ -446,6 +453,7 @@ namespace Kernel
m_packet_size_total -= nread;
m_packet_thread_blocker.unblock();
m_packet_lock.unlock(state);
epoll_notify(EPOLLOUT);

View File

@ -37,15 +37,6 @@ namespace Kernel
static BAN::Vector<Process*> s_processes;
static RecursiveSpinLock s_process_lock;
struct futex_t
{
ThreadBlocker blocker;
uint32_t waiters { 0 };
uint32_t to_wakeup { 0 };
};
static BAN::HashMap<paddr_t, BAN::UniqPtr<futex_t>> s_futexes;
static Mutex s_futex_lock;
static void for_each_process(const BAN::Function<BAN::Iteration(Process&)>& callback)
{
SpinLockGuard _(s_process_lock);
@ -318,7 +309,7 @@ namespace Kernel
LockGuard _(m_process_lock);
for (auto* thread : m_threads)
if (thread != &Thread::current())
thread->add_signal(SIGKILL);
ASSERT(thread->add_signal(SIGKILL));
}
while (m_threads.size() > 1)
@ -1167,10 +1158,8 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_hardlinkat(int fd1, const char* path1, int fd2, const char* path2, int flag)
{
LockGuard _(m_process_lock);
if (path1 != nullptr)
TRY(validate_string_access(path1));
if (path2 != nullptr)
TRY(validate_string_access(path2));
TRY(validate_string_access(path1));
TRY(validate_string_access(path2));
auto inode = TRY(find_file(fd1, path1, flag)).inode;
if (inode->mode().ifdir())
@ -1191,8 +1180,7 @@ namespace Kernel
return BAN::Error::from_errno(EINVAL);
LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_string_access(path));
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_WRONLY));
@ -1207,8 +1195,7 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize)
{
LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_string_access(path));
TRY(validate_pointer_access(buffer, bufsize, true));
auto inode = TRY(find_file(fd, path, O_NOFOLLOW | O_RDONLY)).inode;
@ -1275,8 +1262,7 @@ namespace Kernel
flag = O_NOFOLLOW;
LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_string_access(path));
auto inode = TRY(find_file(fd, path, flag)).inode;
@ -1299,8 +1285,7 @@ namespace Kernel
flag = O_NOFOLLOW;
LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_string_access(path));
auto inode = TRY(find_file(fd, path, flag)).inode;
@ -1986,8 +1971,6 @@ namespace Kernel
flag = O_NOFOLLOW;
LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_pointer_access(buf, sizeof(struct stat), true));
auto inode = TRY(find_file(fd, path, flag)).inode;
@ -2011,8 +1994,6 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_fstatvfsat(int fd, const char* path, struct statvfs* buf)
{
LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_pointer_access(buf, sizeof(struct statvfs), true));
auto inode = TRY(find_file(fd, path, 0)).inode;
@ -2177,17 +2158,6 @@ namespace Kernel
vaddr_t base_addr = reinterpret_cast<vaddr_t>(args.addr);
address_range.start = BAN::Math::div_round_up<vaddr_t>(base_addr, PAGE_SIZE) * PAGE_SIZE;
address_range.end = BAN::Math::div_round_up<vaddr_t>(base_addr + args.len, PAGE_SIZE) * PAGE_SIZE;
for (size_t i = 0; i < m_mapped_regions.size(); i++)
{
if (!m_mapped_regions[i]->overlaps(base_addr, args.len))
continue;
if (!m_mapped_regions[i]->contains_fully(base_addr, args.len))
derrorln("VERY BROKEN MAP_FIXED UNMAP");
m_mapped_regions[i]->wait_not_pinned();
m_mapped_regions.remove(i--);
}
}
if (args.flags & MAP_ANONYMOUS)
@ -2671,81 +2641,23 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_sigsuspend(const sigset_t* set)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(set, sizeof(sigset_t), false));
auto& thread = Thread::current();
thread.set_suspend_signal_mask(*set & ~(SIGKILL | SIGSTOP));
while (!thread.is_interrupted_by_signal())
Processor::scheduler().block_current_thread(nullptr, -1, &m_process_lock);
return BAN::Error::from_errno(EINTR);
}
BAN::ErrorOr<long> Process::sys_sigwait(const sigset_t* set, int* sig)
{
LockGuard _(m_process_lock);
auto& thread = Thread::current();
for (;;)
{
TRY(validate_pointer_access(set, sizeof(sigset_t), false));
TRY(validate_pointer_access(sig, sizeof(int), true));
{
SpinLockGuard _1(thread.m_signal_lock);
SpinLockGuard _2(m_signal_lock);
const uint64_t pending = thread.m_signal_pending_mask | this->m_signal_pending_mask;
if (const auto wait_mask = pending & *set)
{
for (size_t i = _SIGMIN; i <= _SIGMAX; i++)
{
const auto mask = 1ull << i;
if (!(wait_mask & mask))
continue;
thread.m_signal_pending_mask &= ~mask;
this->m_signal_pending_mask &= ~mask;
*sig = i;
return 0;
}
ASSERT_NOT_REACHED();
}
}
Processor::scheduler().block_current_thread(nullptr, -1, &m_process_lock);
}
}
BAN::ErrorOr<long> Process::sys_sigaltstack(const stack_t* ss, stack_t* oss)
{
LockGuard _(m_process_lock);
if (ss != nullptr)
TRY(validate_pointer_access(ss, sizeof(stack_t), false));
if (oss != nullptr)
TRY(validate_pointer_access(oss, sizeof(stack_t), true));
TRY(Thread::current().sigaltstack(ss, oss));
return 0;
}
BAN::ErrorOr<long> Process::sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime)
{
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
if (vaddr % 4)
return BAN::Error::from_errno(EINVAL);
const bool is_private = (op & FUTEX_PRIVATE);
const bool is_realtime = (op & FUTEX_REALTIME);
op &= ~(FUTEX_PRIVATE | FUTEX_REALTIME);
// TODO: possibly optimize private futexes?
if (!is_private)
{
dwarnln("TODO: shared futex");
return BAN::Error::from_errno(ENOTSUP);
}
LockGuard _(s_futex_lock);
LockGuard _(m_process_lock);
auto* buffer_region = TRY(validate_and_pin_pointer_access(addr, sizeof(uint32_t), false));
BAN::ScopeGuard pin_guard([&] { if (buffer_region) buffer_region->unpin(); });
@ -2776,20 +2688,20 @@ namespace Kernel
return SystemTimer::get().ns_since_boot() + (abs_ns - real_ns);
}());
auto it = s_futexes.find(paddr);
if (it == s_futexes.end())
it = TRY(s_futexes.emplace(paddr, TRY(BAN::UniqPtr<futex_t>::create())));
auto it = m_futexes.find(paddr);
if (it == m_futexes.end())
it = TRY(m_futexes.emplace(paddr, TRY(BAN::UniqPtr<futex_t>::create())));
futex_t* const futex = it->value.ptr();
futex->waiters++;
BAN::ScopeGuard _([futex, paddr] {
BAN::ScopeGuard _([futex, paddr, this] {
if (--futex->waiters == 0)
s_futexes.remove(paddr);
m_futexes.remove(paddr);
});
for (;;)
{
TRY(Thread::current().block_or_eintr_or_waketime_ns(futex->blocker, wake_time_ns, true, &s_futex_lock));
TRY(Thread::current().block_or_eintr_or_waketime_ns(futex->blocker, wake_time_ns, true, &m_process_lock));
if (BAN::atomic_load(*addr) == val || futex->to_wakeup == 0)
continue;
futex->to_wakeup--;
@ -2798,8 +2710,8 @@ namespace Kernel
}
case FUTEX_WAKE:
{
auto it = s_futexes.find(paddr);
if (it == s_futexes.end())
auto it = m_futexes.find(paddr);
if (it == m_futexes.end())
return 0;
futex_t* const futex = it->value.ptr();
@ -3299,10 +3211,8 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_getgroups(gid_t groups[], size_t count)
{
LockGuard _(m_process_lock);
const auto current = m_credentials.groups();
if (count == 0)
return current.size();
TRY(validate_pointer_access(groups, count * sizeof(gid_t), true));
auto current = m_credentials.groups();
if (current.size() > count)
return BAN::Error::from_errno(EINVAL);
for (size_t i = 0; i < current.size(); i++)
@ -3385,9 +3295,6 @@ unauthorized_access:
{
// TODO: This seems very slow as we loop over the range twice
if (size == 0)
return {};
TRY(validate_pointer_access_check(ptr, size, needs_write));
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(ptr);

View File

@ -92,14 +92,14 @@ namespace Kernel
if (ret.is_error() && ret.error().is_kernel_error())
Kernel::panic("Kernel error while returning to userspace {}", ret.error());
Processor::set_interrupt_state(InterruptState::Disabled);
auto& current_thread = Thread::current();
if (current_thread.can_add_signal_to_execute())
if (current_thread.handle_signal())
if (ret.is_error() && ret.error().get_error_code() == EINTR && is_restartable_syscall(syscall))
ret = BAN::Error::from_errno(ERESTART);
Processor::set_interrupt_state(InterruptState::Disabled);
ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing);
if (ret.is_error())

View File

@ -165,7 +165,7 @@ namespace Kernel
PseudoTerminalSlave::PseudoTerminalSlave(BAN::String&& name, uint32_t number, mode_t mode, uid_t uid, gid_t gid)
: TTY({
.c_iflag = ICRNL,
.c_iflag = 0,
.c_oflag = 0,
.c_cflag = CS8,
.c_lflag = ECHO | ECHOE | ECHOK | ICANON | ISIG,

View File

@ -243,14 +243,19 @@ namespace Kernel
LockGuard _(m_mutex);
if ((m_termios.c_iflag & ISTRIP))
ch &= 0x7F;
if ((m_termios.c_iflag & IGNCR) && ch == CR)
return;
if ((m_termios.c_iflag & ICRNL) && ch == CR)
ch = NL;
else if ((m_termios.c_iflag & INLCR) && ch == NL)
ch = CR;
if (m_termios.c_lflag & ICANON)
{
if ((m_termios.c_iflag & ISTRIP))
ch &= 0x7F;
if ((m_termios.c_iflag & IGNCR) && ch == CR)
return;
uint8_t conv = ch;
if ((m_termios.c_iflag & ICRNL) && ch == CR)
conv = NL;
if ((m_termios.c_iflag & INLCR) && ch == NL)
conv = CR;
ch = conv;
}
if (m_termios.c_lflag & ISIG)
{
@ -293,10 +298,11 @@ namespace Kernel
should_flush = true;
}
if (ch == NL || ch == CR || ch == m_termios.c_cc[VEOL])
if (ch == NL || ch == m_termios.c_cc[VEOL])
{
should_flush = true;
force_echo = !!(m_termios.c_lflag & ECHONL);
ch = NL;
}
}

View File

@ -37,7 +37,7 @@ namespace Kernel
VirtualTTY::VirtualTTY(BAN::RefPtr<TerminalDriver> driver)
: TTY({
.c_iflag = ICRNL,
.c_iflag = 0,
.c_oflag = 0,
.c_cflag = CS8,
.c_lflag = ECHO | ECHOE | ECHOK | ICANON | ISIG,

View File

@ -69,20 +69,6 @@ namespace Kernel
s_default_sse_storage_initialized = true;
}
static bool is_default_ignored_signal(int signal)
{
switch (signal)
{
case SIGCHLD:
case SIGURG:
case SIGWINCH:
case SIGCANCEL:
return true;
default:
return false;
}
}
BAN::ErrorOr<Thread*> Thread::create_kernel(entry_t entry, void* data)
{
// Create the thread object
@ -481,7 +467,7 @@ namespace Kernel
}
if (signal_handler == (vaddr_t)SIG_IGN)
continue;
if (signal_handler == (vaddr_t)SIG_DFL && is_default_ignored_signal(i))
if (signal_handler == (vaddr_t)SIG_DFL && (i == SIGCHLD || i == SIGURG))
continue;
return true;
}
@ -507,7 +493,6 @@ namespace Kernel
ASSERT(is_userspace());
auto state = m_signal_lock.lock();
ASSERT(state == InterruptState::Disabled);
auto& interrupt_stack = *reinterpret_cast<InterruptStack*>(kernel_stack_top() - sizeof(InterruptStack));
ASSERT(GDT::is_user_segment(interrupt_stack.cs));
@ -531,7 +516,6 @@ namespace Kernel
vaddr_t signal_handler;
bool has_sa_restart;
vaddr_t signal_stack_top = 0;
{
SpinLockGuard _(m_process->m_signal_lock);
@ -544,23 +528,11 @@ namespace Kernel
handler.sa_handler = SIG_DFL;
has_sa_restart = !!(handler.sa_flags & SA_RESTART);
const auto& alt_stack = m_signal_alt_stack;
if (alt_stack.ss_flags != SS_DISABLE && (handler.sa_flags & SA_ONSTACK) && !currently_on_alternate_stack())
signal_stack_top = reinterpret_cast<vaddr_t>(alt_stack.ss_sp) + alt_stack.ss_size;
}
m_signal_pending_mask &= ~(1ull << signal);
process().remove_pending_signal(signal);
if (m_signal_suspend_mask.has_value())
{
m_signal_block_mask = m_signal_suspend_mask.value();
m_signal_suspend_mask.clear();
}
m_signal_lock.unlock(state);
if (signal_handler == (vaddr_t)SIG_IGN)
;
else if (signal_handler != (vaddr_t)SIG_DFL)
@ -569,32 +541,7 @@ namespace Kernel
#if ARCH(x86_64)
interrupt_stack.sp -= 128; // skip possible red-zone
#endif
{
// Make sure stack is allocated
const vaddr_t pages[3] {
(interrupt_stack.sp - sizeof(uintptr_t)) & PAGE_ADDR_MASK,
(signal_stack_top - 4 * sizeof(uintptr_t)) & PAGE_ADDR_MASK,
(signal_stack_top - 1 * sizeof(uintptr_t)) & PAGE_ADDR_MASK,
};
for (size_t i = 0; i < 3; i++)
{
if (m_process->page_table().get_page_flags(pages[i]) & PageTable::Flags::Present)
continue;
Processor::set_interrupt_state(InterruptState::Enabled);
if (auto ret = m_process->allocate_page_for_demand_paging(pages[i], true, false); ret.is_error() || !ret.value())
m_process->exit(128 + SIGSEGV, SIGSEGV);
Processor::set_interrupt_state(InterruptState::Disabled);
}
}
write_to_stack(interrupt_stack.sp, interrupt_stack.ip);
const vaddr_t old_stack = interrupt_stack.sp;
if (signal_stack_top)
interrupt_stack.sp = signal_stack_top;
write_to_stack(interrupt_stack.sp, old_stack);
write_to_stack(interrupt_stack.sp, interrupt_stack.flags);
write_to_stack(interrupt_stack.sp, signal);
write_to_stack(interrupt_stack.sp, signal_handler);
@ -615,6 +562,7 @@ namespace Kernel
case SIGTRAP:
case SIGXCPU:
case SIGXFSZ:
m_signal_lock.unlock(state);
process().exit(128 + signal, signal | 0x80);
ASSERT_NOT_REACHED();
@ -630,11 +578,18 @@ namespace Kernel
case SIGPOLL:
case SIGPROF:
case SIGVTALRM:
m_signal_lock.unlock(state);
process().exit(128 + signal, signal);
ASSERT_NOT_REACHED();
// Ignore the signal
case SIGCHLD:
case SIGURG:
case SIGWINCH:
case SIGCANCEL:
break;
// Stop the process:
case SIGSTOP:
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
@ -643,18 +598,15 @@ namespace Kernel
// Continue the process, if it is stopped; otherwise, ignore the signal.
case SIGCONT:
ASSERT_NOT_REACHED();
default:
if (is_default_ignored_signal(signal))
break;
panic("Executing unhandled signal {}", signal);
}
}
m_signal_lock.unlock(state);
return has_sa_restart;
}
void Thread::add_signal(int signal)
bool Thread::add_signal(int signal)
{
SpinLockGuard _(m_signal_lock);
if (m_process)
@ -666,64 +618,19 @@ namespace Kernel
signal_handler = (vaddr_t)m_process->m_signal_handlers[signal].sa_handler;
}
if (signal_handler == (vaddr_t)SIG_IGN)
return;
if (signal_handler == (vaddr_t)SIG_DFL && is_default_ignored_signal(signal))
return;
return false;
if (signal_handler == (vaddr_t)SIG_DFL && (signal == SIGCHLD || signal == SIGURG))
return false;
}
const uint64_t mask = 1ull << signal;
m_signal_pending_mask |= mask;
if (this != &Thread::current())
Processor::scheduler().unblock_thread(this);
}
void Thread::set_suspend_signal_mask(uint64_t sigmask)
{
SpinLockGuard _(m_signal_lock);
ASSERT(!m_signal_suspend_mask.has_value());
m_signal_suspend_mask = m_signal_block_mask;
m_signal_block_mask = sigmask;
}
bool Thread::currently_on_alternate_stack() const
{
ASSERT(m_signal_lock.current_processor_has_lock());
if (m_signal_alt_stack.ss_flags == SS_ONSTACK)
return false;
const vaddr_t stack_bottom = reinterpret_cast<vaddr_t>(m_signal_alt_stack.ss_sp);
const vaddr_t stack_top = stack_bottom + m_signal_alt_stack.ss_size;
const vaddr_t sp = m_interrupt_stack.sp;
return stack_bottom <= sp && sp <= stack_top;
}
BAN::ErrorOr<void> Thread::sigaltstack(const stack_t* ss, stack_t* oss)
{
SpinLockGuard _(m_signal_lock);
const bool on_alt_stack = currently_on_alternate_stack();
if (oss)
uint64_t mask = 1ull << signal;
if (!(m_signal_block_mask & mask))
{
*oss = m_signal_alt_stack;
if (on_alt_stack)
oss->ss_flags = SS_ONSTACK;
m_signal_pending_mask |= mask;
if (this != &Thread::current())
Processor::scheduler().unblock_thread(this);
return true;
}
if (ss)
{
if (on_alt_stack)
return BAN::Error::from_errno(EPERM);
if (ss->ss_flags && ss->ss_flags != SS_DISABLE)
return BAN::Error::from_errno(EINVAL);
if (ss->ss_size < MINSIGSTKSZ)
return BAN::Error::from_errno(ENOMEM);
m_signal_alt_stack = *ss;
}
return {};
return false;
}
BAN::ErrorOr<void> Thread::sleep_or_eintr_ns(uint64_t ns)

View File

@ -299,7 +299,7 @@ namespace Kernel
long ns_this_second = ticks_this_second * regs.counter_clk_period / FS_PER_NS;
return timespec {
.tv_sec = static_cast<time_t>(seconds),
.tv_sec = seconds,
.tv_nsec = ns_this_second
};
}

View File

@ -487,8 +487,8 @@ diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_message_box.h SDL2-2.32.8-
+/* vi: set ts=4 sw=4 expandtab: */
diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp
--- SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp 1970-01-01 02:00:00.000000000 +0200
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp 2025-08-21 02:32:59.649175565 +0300
@@ -0,0 +1,724 @@
+++ SDL2-2.32.8-banan_os/src/video/banan_os/SDL_banan_os_video.cpp 2025-08-06 02:01:21.086666679 +0300
@@ -0,0 +1,718 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
@ -894,12 +894,6 @@ diff -ruN SDL2-2.32.8/src/video/banan_os/SDL_banan_os_video.cpp SDL2-2.32.8-bana
+ }
+ );
+
+ ban_window->window->set_window_focus_event_callback(
+ [window](LibGUI::EventPacket::WindowFocusEvent::event_t event) {
+ SDL_SetKeyboardFocus(event.focused ? window : nullptr);
+ }
+ );
+
+ ban_window->window->set_close_window_event_callback(
+ [window]() {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0);

View File

@ -3,16 +3,15 @@
NAME='SDL2_mixer'
VERSION='2.8.1'
DOWNLOAD_URL="https://github.com/libsdl-org/SDL_mixer/releases/download/release-$VERSION/SDL2_mixer-$VERSION.tar.gz#cb760211b056bfe44f4a1e180cc7cb201137e4d1572f2002cc1be728efd22660"
DEPENDENCIES=('SDL2' 'timidity')
DEPENDENCIES=('SDL2')
configure() {
$BANAN_CMAKE --fresh -S . -B build -G Ninja \
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
-DCMAKE_INSTALL_PREFIX='/usr' \
-DCMAKE_BUILD_TYPE=Release \
-DSDL2MIXER_DEPS_SHARED=OFF \
-DSDL2MIXER_MIDI_FLUIDSYNTH=OFF \
-DSDL2MIXER_WAVPACK=OFF \
-DSDL2MIXER_MIDI=OFF \
-DSDL2MIXER_OPUS=OFF \
-DSDL2MIXER_MOD=OFF \
|| exit 1

View File

@ -1,26 +0,0 @@
#!/bin/bash ../install.sh
NAME='glib'
VERSION='2.85.2'
DOWNLOAD_URL="https://download.gnome.org/sources/glib/${VERSION%.*}/glib-$VERSION.tar.xz#833b97c0f0a1bfdba1d0fbfc36cd368b855c5afd9f02b8ffb24129114ad051b2"
DEPENDENCIES=('pcre2' 'libffi' 'zlib' 'libiconv')
CONFIGURE_OPTIONS=(
'-Dprefix=/usr'
'-Dxattr=false'
)
configure() {
meson setup \
--reconfigure \
--cross-file "$MESON_CROSS_FILE" \
"${CONFIGURE_OPTIONS[@]}" \
build || exit 1
}
build() {
meson compile -C build || exit 1
}
install() {
meson install --destdir="$BANAN_SYSROOT" -C build || exit 1
}

View File

@ -1,106 +0,0 @@
diff -ruN glib-2.85.2/gio/gnetworking.h.in glib-2.85.2-banan_os/gio/gnetworking.h.in
--- glib-2.85.2/gio/gnetworking.h.in 2025-07-21 20:47:53.000000000 +0300
+++ glib-2.85.2-banan_os/gio/gnetworking.h.in 2025-08-19 18:21:06.038296386 +0300
@@ -40,13 +40,17 @@
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#ifndef __banan_os__
#include <resolv.h>
+#endif
#include <sys/socket.h>
#include <sys/un.h>
#include <net/if.h>
#include <arpa/inet.h>
+#ifndef __banan_os__
#include <arpa/nameser.h>
+#endif
@NAMESER_COMPAT_INCLUDE@
#ifndef __GI_SCANNER__
diff -ruN glib-2.85.2/gio/gthreadedresolver.c glib-2.85.2-banan_os/gio/gthreadedresolver.c
--- glib-2.85.2/gio/gthreadedresolver.c 2025-07-21 20:47:53.000000000 +0300
+++ glib-2.85.2-banan_os/gio/gthreadedresolver.c 2025-08-19 18:21:06.052332130 +0300
@@ -41,6 +41,10 @@
#include "gsocketaddress.h"
#include "gsrvtarget.h"
+#if defined __banan_os__
+#include <endian.h>
+#endif
+
#if HAVE_GETIFADDRS
#include <ifaddrs.h>
#endif
@@ -692,7 +696,7 @@
#if defined(G_OS_UNIX)
-#if defined __BIONIC__ && !defined BIND_4_COMPAT
+#if (defined __BIONIC__ && !defined BIND_4_COMPAT) || defined __banan_os__
/* Copy from bionic/libc/private/arpa_nameser_compat.h
* and bionic/libc/private/arpa_nameser.h */
typedef struct {
@@ -763,6 +767,14 @@
#define dn_skipname __dn_skipname
int dn_skipname(const u_char *, const u_char *);
+#if defined __banan_os__
+#warning "TODO: dn_expand"
+int dn_expand(const u_char *, const u_char *, const u_char *, char *, int)
+{
+ return -1;
+}
+#endif
+
/* From bionic/libc/private/arpa_nameser_compat.h */
#define T_MX ns_t_mx
#define T_TXT ns_t_txt
@@ -1369,7 +1381,7 @@
}
#if defined(G_OS_UNIX)
-#ifdef __BIONIC__
+#if defined __BIONIC__
#ifndef C_IN
#define C_IN 1
#endif
@@ -1420,6 +1432,9 @@
g_byte_array_set_size (answer, len * 2);
#if defined(HAVE_RES_NQUERY)
len = res_nquery (&res, rrname, C_IN, rrtype, answer->data, answer->len);
+#elif defined __banan_os__
+#warning "TODO: res_query"
+ len = -1;
#else
len = res_query (rrname, C_IN, rrtype, answer->data, answer->len);
#endif
diff -ruN glib-2.85.2/gio/meson.build glib-2.85.2-banan_os/gio/meson.build
--- glib-2.85.2/gio/meson.build 2025-07-21 20:47:53.000000000 +0300
+++ glib-2.85.2-banan_os/gio/meson.build 2025-08-19 18:21:06.062294634 +0300
@@ -18,7 +18,7 @@
gnetworking_h_nameser_compat_include = ''
-if host_system not in ['windows', 'android']
+if host_system not in ['windows', 'android', 'banan_os']
# Don't check for C_IN on Android since it does not define it in public
# headers, we define it ourselves wherever necessary
if not cc.compiles('''#include <sys/types.h>
@@ -40,6 +40,7 @@
network_libs = [ ]
network_args = [ ]
if host_system != 'windows'
+ if host_system != 'banan_os'
# res_query()
res_query_test = '''#include <resolv.h>
int main (int argc, char ** argv) {
@@ -63,6 +64,7 @@
error('Could not find res_query()')
endif
endif
+ endif
# socket()
socket_test = '''#include <sys/types.h>

View File

@ -1,39 +0,0 @@
diff -ruN glib-2.85.2/gio/gunixmounts.c glib-2.85.2-banan_os/gio/gunixmounts.c
--- glib-2.85.2/gio/gunixmounts.c 2025-07-21 20:47:53.000000000 +0300
+++ glib-2.85.2-banan_os/gio/gunixmounts.c 2025-08-19 18:21:06.055332112 +0300
@@ -1114,7 +1114,7 @@
}
/* QNX {{{2 */
-#elif defined (HAVE_QNX)
+#elif defined (HAVE_QNX) || defined (__banan_os__)
static char *
get_mtab_monitor_file (void)
@@ -1754,6 +1754,26 @@
if (time_read_out != NULL)
*time_read_out = 0;
if (n_points_out != NULL)
+ *n_points_out = 0;
+ return NULL;
+}
+
+#elif defined (__banan_os__)
+
+static GList *
+_g_get_unix_mount_points (void)
+{
+ return NULL;
+}
+
+static GUnixMountPoint **
+_g_unix_mount_points_get_from_file (const char *table_path,
+ uint64_t *time_read_out,
+ size_t *n_points_out)
+{
+ if (time_read_out != NULL)
+ *time_read_out = 0;
+ if (n_points_out != NULL)
*n_points_out = 0;
return NULL;
}

View File

@ -1,11 +0,0 @@
#!/bin/bash ../install.sh
NAME='libffi'
VERSION='3.5.2'
DOWNLOAD_URL="https://github.com/libffi/libffi/releases/download/v$VERSION/libffi-$VERSION.tar.gz#f3a3082a23b37c293a4fcd1053147b371f2ff91fa7ea1b2a52e335676bac82dc"
CONFIG_SUB=('config.sub')
post_install() {
# remove libtool file
rm -f $BANAN_SYSROOT/usr/lib/libffi.la
}

View File

@ -1,48 +0,0 @@
diff -ruN libffi-3.5.2/configure libffi-3.5.2-banan_os/configure
--- libffi-3.5.2/configure 2025-08-02 09:44:34.000000000 +0300
+++ libffi-3.5.2-banan_os/configure 2025-08-08 18:24:29.271963294 +0300
@@ -7432,6 +7432,10 @@
lt_cv_deplibs_check_method=pass_all
;;
+banan_os*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
beos*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -12978,6 +12982,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"
@@ -17612,6 +17626,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"

View File

@ -1,14 +0,0 @@
#!/bin/bash ../install.sh
NAME='nano'
VERSION='8.5'
DOWNLOAD_URL="https://www.nano-editor.org/dist/v8/nano-$VERSION.tar.xz#000b011d339c141af9646d43288f54325ff5c6e8d39d6e482b787bbc6654c26a"
DEPENDENCIES=('ncurses')
CONFIG_SUB=('config.sub')
CONFIGURE_OPTIONS=(
'ac_cv_header_glob_h=no'
)
pre_configure() {
echo '#include_next <sys/types.h>' > lib/sys_types.in.h
}

View File

@ -1,21 +0,0 @@
diff -ruN nano-8.5/lib/getprogname.c nano-8.5-banan_os/lib/getprogname.c
--- nano-8.5/lib/getprogname.c 2025-06-12 10:29:39.000000000 +0300
+++ nano-8.5-banan_os/lib/getprogname.c 2025-08-19 01:25:56.020428849 +0300
@@ -50,7 +50,7 @@
# include <sys/procfs.h>
#endif
-#if defined __SCO_VERSION__ || defined __sysv5__
+#if defined __SCO_VERSION__ || defined __sysv5__ || defined __banan_os__
# include <fcntl.h>
# include <string.h>
#endif
@@ -265,7 +265,7 @@
}
}
return NULL;
-# elif defined __SCO_VERSION__ || defined __sysv5__ /* SCO OpenServer6/UnixWare */
+# elif defined __SCO_VERSION__ || defined __sysv5__ || defined __banan_os__ /* SCO OpenServer6/UnixWare */
char buf[80];
int fd;
sprintf (buf, "/proc/%d/cmdline", getpid());

View File

@ -1,13 +0,0 @@
#!/bin/bash ../install.sh
NAME='nyancat'
VERSION='git'
DOWNLOAD_URL="https://github.com/klange/nyancat.git#1.5.2"
configure() {
:
}
install() {
cp src/nyancat "$BANAN_SYSROOT/usr/bin/"
}

View File

@ -1,12 +0,0 @@
#!/bin/bash ../install.sh
NAME='pcre2'
VERSION='10.45'
DOWNLOAD_URL="https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$VERSION/pcre2-$VERSION.tar.gz#0e138387df7835d7403b8351e2226c1377da804e0737db0e071b48f07c9d12ee"
CONFIG_SUB=('config.sub')
post_install() {
# remove libtool files
rm -f $BANAN_SYSROOT/usr/lib/libpcre2-8.la
rm -f $BANAN_SYSROOT/usr/lib/libpcre2-posix.la
}

View File

@ -1,31 +0,0 @@
diff -ruN pcre2-10.45/configure pcre2-10.45-banan_os/configure
--- pcre2-10.45/configure 2025-02-04 15:48:33.000000000 +0200
+++ pcre2-10.45-banan_os/configure 2025-08-08 00:22:52.975889591 +0300
@@ -6536,6 +6536,10 @@
lt_cv_deplibs_check_method=pass_all
;;
+banan_os*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
beos*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -12197,6 +12201,16 @@
esac
;;
+banan_os*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker="$host_os DynamicLoader.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"

View File

@ -1,17 +0,0 @@
#!/bin/bash ../install.sh
NAME='qemu'
VERSION='10.0.2'
DOWNLOAD_URL="https://download.qemu.org/qemu-$VERSION.tar.xz#ef786f2398cb5184600f69aef4d5d691efd44576a3cff4126d38d4c6fec87759"
DEPENDENCIES=('glib' 'SDL2')
MAKE_BUILD_TARGETS=('qemu-system-x86_64')
CONFIGURE_OPTIONS=(
'--cross-prefix='
'--target-list=x86_64-softmmu'
'--disable-tpm'
'--disable-docs'
)
pre_configure() {
echo '' > tests/meson.build
}

View File

@ -1,12 +0,0 @@
diff -ruN qemu-10.0.2/configure qemu-10.0.2-banan_os/configure
--- qemu-10.0.2/configure 2025-05-29 01:05:46.000000000 +0300
+++ qemu-10.0.2-banan_os/configure 2025-05-31 00:03:10.361102831 +0300
@@ -360,6 +360,8 @@
host_os=netbsd
elif check_define __APPLE__; then
host_os=darwin
+elif check_define __banan_os__; then
+ host_os=banan_os
else
# This is a fatal error, but don't report it yet, because we
# might be going to just print the --help text, or it might

View File

@ -1,43 +0,0 @@
diff -ru qemu-10.0.2/util/oslib-posix.c qemu-10.0.2-x86_64/util/oslib-posix.c
--- qemu-10.0.2/util/oslib-posix.c 2025-05-29 01:05:47.000000000 +0300
+++ qemu-10.0.2-x86_64/util/oslib-posix.c 2025-08-18 02:38:04.839116456 +0300
@@ -128,7 +128,39 @@
int qemu_daemon(int nochdir, int noclose)
{
+#if defined(__banan_os__)
+ const pid_t pid = fork();
+ if (pid == -1) {
+ return -1;
+ }
+ if (pid > 0) {
+ exit(0);
+ }
+
+ if (setsid() == -1) {
+ return -1;
+ }
+
+ if (nochdir == 0) {
+ if (chdir("/") == -1) {
+ return -1;
+ }
+ }
+
+ if (noclose == 0) {
+ int fd = open("/dev/null", O_RDWR);
+ if (fd == -1) {
+ return -1;
+ }
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ }
+
+ return 0;
+#else
return daemon(nochdir, noclose);
+#endif
}
bool qemu_write_pidfile(const char *path, Error **errp)

View File

@ -1,24 +0,0 @@
diff -ru qemu-10.0.2/util/main-loop.c qemu-10.0.2-x86_64/util/main-loop.c
--- qemu-10.0.2/util/main-loop.c 2025-05-29 01:05:47.000000000 +0300
+++ qemu-10.0.2-x86_64/util/main-loop.c 2025-08-09 18:35:25.670990547 +0300
@@ -95,8 +95,10 @@
* not catch it reliably.
*/
sigemptyset(&set);
+#if !defined(__banan_os__)
sigaddset(&set, SIG_IPI);
sigaddset(&set, SIGIO);
+#endif
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGBUS);
/* SIGINT cannot be handled via signalfd, so that ^C can be used
@@ -106,7 +108,9 @@
*/
pthread_sigmask(SIG_BLOCK, &set, NULL);
+#if !defined(__banan_os__)
sigdelset(&set, SIG_IPI);
+#endif
sigfd = qemu_signalfd(&set);
if (sigfd == -1) {
error_setg_errno(errp, errno, "failed to create signalfd");

View File

@ -1,22 +0,0 @@
diff -ru qemu-10.0.2/net/colo.c qemu-10.0.2-x86_64/net/colo.c
--- qemu-10.0.2/net/colo.c 2025-05-29 01:05:46.000000000 +0300
+++ qemu-10.0.2-x86_64/net/colo.c 2025-08-09 19:24:57.624758915 +0300
@@ -123,14 +123,18 @@
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_DCCP:
+#if !defined(__banan_os__)
case IPPROTO_ESP:
+#endif
case IPPROTO_SCTP:
case IPPROTO_UDPLITE:
tmp_ports = *(uint32_t *)(pkt->transport_header);
break;
+#if !defined(__banan_os__)
case IPPROTO_AH:
tmp_ports = *(uint32_t *)(pkt->transport_header + 4);
break;
+#endif
default:
break;
}

View File

@ -1,32 +0,0 @@
diff -ru qemu-10.0.2/block/file-posix.c qemu-10.0.2-x86_64/block/file-posix.c
--- qemu-10.0.2/block/file-posix.c 2025-05-29 01:05:46.000000000 +0300
+++ qemu-10.0.2-x86_64/block/file-posix.c 2025-08-09 19:00:18.062695074 +0300
@@ -110,6 +110,10 @@
#include <sys/diskslice.h>
#endif
+#ifdef __banan_os__
+#include <sys/ioctl.h>
+#endif
+
/* OS X does not have O_DSYNC */
#ifndef O_DSYNC
#ifdef O_SYNC
Only in qemu-10.0.2-x86_64: build
Only in qemu-10.0.2-x86_64: .cache
diff -ru qemu-10.0.2/chardev/char-pty.c qemu-10.0.2-x86_64/chardev/char-pty.c
--- qemu-10.0.2/chardev/char-pty.c 2025-05-29 01:05:46.000000000 +0300
+++ qemu-10.0.2-x86_64/chardev/char-pty.c 2025-08-09 19:03:07.909515897 +0300
@@ -236,7 +236,11 @@
# include <termios.h>
#endif
-#ifdef __sun__
+#if defined(__banan_os__)
+# include <sys/ioctl.h>
+#endif
+
+#if defined(__sun__) || defined(__banan_os__)
#if !defined(HAVE_OPENPTY)
/* Once illumos has openpty(), this is going to be removed. */

View File

@ -19,6 +19,7 @@ setjmp:
xorl %eax, %eax
ret
.size setjmp, . - setjmp
// void longjmp(jmp_buf env, int val)
@ -38,27 +39,5 @@ longjmp:
movl 16(%edx), %edi
movl 20(%edx), %esi
jmp *%ecx
.size longjmp, . - longjmp
// int sigsetjmp(sigjmp_buf env, int savemask)
.global sigsetjmp
sigsetjmp:
movl 4(%esp), %edx
movl 8(%esp), %ecx
movl %ecx, 24(%edx)
testl %ecx, %ecx
jz setjmp
leal 24(%edx), %edx
xorl %ecx, %ecx
subl $12, %esp
movl %edx, 8(%esp)
movl %ecx, 4(%esp)
movl %ecx, 0(%esp)
call pthread_sigmask
addl $12, %esp
jmp setjmp
.size sigsetjmp, . - sigsetjmp

View File

@ -38,21 +38,3 @@ longjmp:
movq 56(%rdi), %r15
jmp *%rcx
.size longjmp, . - longjmp
// int sigsetjmp(sigjmp_buf env, int savemask)
.global sigsetjmp
sigsetjmp:
movq %rsi, 64(%rdi)
testq %rsi, %rsi
jz setjmp
subq $8, %rsp
movq %rdi, (%rsp)
leaq 72(%rsi), %rdx
xorq %rsi, %rsi
call pthread_sigmask
movq (%rsp), %rdi
addq $8, %rsp
jmp setjmp
.size sigsetjmp, . - sigsetjmp

View File

@ -1,13 +1,5 @@
#include <dlfcn.h>
extern "C" int __dladdr(const void*, Dl_info_t*) __attribute__((weak));
int dladdr(const void* __restrict addr, Dl_info_t* __restrict dlip)
{
if (&__dladdr == nullptr) [[unlikely]]
return 0;
return __dladdr(addr, dlip);
}
extern "C" int __dlclose(void*) __attribute__((weak));
int dlclose(void* handle)
{

View File

@ -26,8 +26,7 @@ typedef struct
typedef struct
{
pthread_mutexattr_t attr;
uint32_t futex;
uint32_t waiters;
pthread_t locker;
unsigned lock_depth;
} pthread_mutex_t;

View File

@ -15,18 +15,6 @@ __BEGIN_DECLS
#define RTLD_NEXT ((void*)-1)
#define RTLD_DEFAULT ((void*) 0)
struct Dl_info
{
const char* dli_fname; /* Pathname of mapped object file. */
void* dli_fbase; /* Base of mapped address range. */
const char* dli_sname; /* Sumbol name or null pointer. */
void* dli_saddr; /* Symbol address or null pointer. */
};
typedef struct Dl_info Dl_info_t; /* POSIX type */
typedef struct Dl_info Dl_info; /* Linux type */
int dladdr(const void* __restrict addr, Dl_info_t* __restrict dlip);
int dlclose(void* handle);
char* dlerror(void);
void* dlopen(const char* file, int mode);

View File

@ -79,7 +79,7 @@ struct uthread
#define PTHREAD_SPIN_INITIALIZER (pthread_spinlock_t)0
#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, 0 }
#define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t){ { PTHREAD_MUTEX_DEFAULT, 0 }, 0, 0 }
#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t){ { 0 }, 0, 0 }
#define _PTHREAD_ATFORK_PREPARE 0

View File

@ -132,9 +132,8 @@ struct sigevent
#define SA_SIGINFO 0x010
#define SA_NOCLDWAIT 0x020
#define SA_NODEFER 0x040
#define SS_ONSTACK 1
#define SS_DISABLE 2
#define SS_ONSTACK 0x080
#define SS_DISABLE 0x100
#define MINSIGSTKSZ 4096
#define SIGSTKSZ 4096

View File

@ -90,9 +90,6 @@ __BEGIN_DECLS
O(SYS_SIGACTION, sigaction) \
O(SYS_SIGPENDING, sigpending) \
O(SYS_SIGPROCMASK, sigprocmask) \
O(SYS_SIGSUSPEND, sigsuspend) \
O(SYS_SIGWAIT, sigwait) \
O(SYS_SIGALTSTACK, sigaltstack) \
O(SYS_SETITIMER, setitimer) \
O(SYS_POSIX_OPENPT, posix_openpt) \
O(SYS_PTSNAME, ptsname) \

View File

@ -146,7 +146,7 @@ __BEGIN_DECLS
#if !defined(__time_t_defined) && (defined(__need_all_types) || defined(__need_time_t))
#define __time_t_defined 1
typedef long long time_t;
typedef unsigned long long time_t;
#endif
#undef __need_time_t

View File

@ -17,7 +17,7 @@ __BEGIN_DECLS
#include <bits/types/locale_t.h>
typedef int mbstate_t;
typedef struct {} mbstate_t;
typedef int wctype_t;

View File

@ -736,6 +736,34 @@ int pthread_spin_unlock(pthread_spinlock_t* lock)
return 0;
}
template<typename T>
static int _pthread_timedlock(T* __restrict lock, const struct timespec* __restrict abstime, int (*trylock)(T*))
{
if (trylock(lock) == 0)
return 0;
constexpr auto has_timed_out =
[](const struct timespec* abstime) -> bool
{
struct timespec curtime;
clock_gettime(CLOCK_REALTIME, &curtime);
if (curtime.tv_sec < abstime->tv_sec)
return false;
if (curtime.tv_sec > abstime->tv_sec)
return true;
return curtime.tv_nsec >= abstime->tv_nsec;
};
while (!has_timed_out(abstime))
{
if (trylock(lock) == 0)
return 0;
sched_yield();
}
return ETIMEDOUT;
}
int pthread_mutexattr_destroy(pthread_mutexattr_t* attr)
{
(void)attr;
@ -807,8 +835,7 @@ int pthread_mutex_init(pthread_mutex_t* __restrict mutex, const pthread_mutexatt
attr = &default_attr;
*mutex = {
.attr = *attr,
.futex = 0,
.waiters = 0,
.locker = 0,
.lock_depth = 0,
};
return 0;
@ -816,28 +843,55 @@ int pthread_mutex_init(pthread_mutex_t* __restrict mutex, const pthread_mutexatt
int pthread_mutex_lock(pthread_mutex_t* mutex)
{
return pthread_mutex_timedlock(mutex, nullptr);
}
// NOTE: current yielding implementation supports shared
int pthread_mutex_trylock(pthread_mutex_t* mutex)
{
const uint32_t tid = pthread_self();
const auto tid = pthread_self();
switch (mutex->attr.type)
{
case PTHREAD_MUTEX_RECURSIVE:
if (mutex->futex != tid)
if (mutex->locker != tid)
break;
mutex->lock_depth++;
return 0;
case PTHREAD_MUTEX_ERRORCHECK:
if (mutex->futex != tid)
if (mutex->locker != tid)
break;
return EDEADLK;
}
uint32_t expected = 0;
if (!BAN::atomic_compare_exchange(mutex->futex, expected, tid, BAN::MemoryOrder::memory_order_acquire))
pthread_t expected = 0;
while (!BAN::atomic_compare_exchange(mutex->locker, expected, tid, BAN::MemoryOrder::memory_order_acquire))
{
sched_yield();
expected = 0;
}
mutex->lock_depth = 1;
return 0;
}
int pthread_mutex_trylock(pthread_mutex_t* mutex)
{
// NOTE: current yielding implementation supports shared
const auto tid = pthread_self();
switch (mutex->attr.type)
{
case PTHREAD_MUTEX_RECURSIVE:
if (mutex->locker != tid)
break;
mutex->lock_depth++;
return 0;
case PTHREAD_MUTEX_ERRORCHECK:
if (mutex->locker != tid)
break;
return EDEADLK;
}
pthread_t expected = 0;
if (!BAN::atomic_compare_exchange(mutex->locker, expected, tid, BAN::MemoryOrder::memory_order_acquire))
return EBUSY;
mutex->lock_depth = 1;
@ -846,42 +900,18 @@ int pthread_mutex_trylock(pthread_mutex_t* mutex)
int pthread_mutex_timedlock(pthread_mutex_t* __restrict mutex, const struct timespec* __restrict abstime)
{
// recursive/errorcheck handled in trylock to remove code duplication
if (const int ret = pthread_mutex_trylock(mutex); ret != EBUSY)
return ret;
const uint32_t tid = pthread_self();
uint32_t expected = 0;
while (!BAN::atomic_compare_exchange(mutex->futex, expected, tid, BAN::memory_order_acquire))
{
const int op = FUTEX_WAIT | (mutex->attr.shared ? 0 : FUTEX_PRIVATE) | FUTEX_REALTIME;
BAN::atomic_add_fetch(mutex->waiters, 1);
const auto ret = futex(op, &mutex->futex, expected, abstime);
BAN::atomic_sub_fetch(mutex->waiters, 1);
if (ret == -1 && errno == ETIMEDOUT)
return ETIMEDOUT;
expected = 0;
}
mutex->lock_depth = 1;
return 0;
return _pthread_timedlock(mutex, abstime, &pthread_mutex_trylock);
}
int pthread_mutex_unlock(pthread_mutex_t* mutex)
{
ASSERT(mutex->futex == static_cast<uint32_t>(pthread_self()));
// NOTE: current yielding implementation supports shared
ASSERT(mutex->locker == pthread_self());
mutex->lock_depth--;
if (mutex->lock_depth == 0)
{
BAN::atomic_store(mutex->futex, 0, BAN::memory_order_release);
if (BAN::atomic_load(mutex->waiters))
futex(FUTEX_WAKE, &mutex->futex, 1, nullptr);
}
BAN::atomic_store(mutex->locker, 0, BAN::MemoryOrder::memory_order_release);
return 0;
}
@ -941,36 +971,6 @@ int pthread_rwlock_init(pthread_rwlock_t* __restrict rwlock, const pthread_rwloc
return 0;
}
// TODO: rewrite rwlock with futexes
template<typename T>
static int pthread_rwlock_timedlock(T* __restrict lock, const struct timespec* __restrict abstime, int (*trylock)(T*))
{
if (trylock(lock) == 0)
return 0;
constexpr auto has_timed_out =
[](const struct timespec* abstime) -> bool
{
struct timespec curtime;
clock_gettime(CLOCK_REALTIME, &curtime);
if (curtime.tv_sec < abstime->tv_sec)
return false;
if (curtime.tv_sec > abstime->tv_sec)
return true;
return curtime.tv_nsec >= abstime->tv_nsec;
};
while (!has_timed_out(abstime))
{
if (trylock(lock) == 0)
return 0;
sched_yield();
}
return ETIMEDOUT;
}
int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
{
unsigned expected = BAN::atomic_load(rwlock->lockers);
@ -995,7 +995,7 @@ int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock)
int pthread_rwlock_timedrdlock(pthread_rwlock_t* __restrict rwlock, const struct timespec* __restrict abstime)
{
return pthread_rwlock_timedlock(rwlock, abstime, &pthread_rwlock_tryrdlock);
return _pthread_timedlock(rwlock, abstime, &pthread_rwlock_tryrdlock);
}
int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
@ -1021,7 +1021,7 @@ int pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock)
int pthread_rwlock_timedwrlock(pthread_rwlock_t* __restrict rwlock, const struct timespec* __restrict abstime)
{
return pthread_rwlock_timedlock(rwlock, abstime, &pthread_rwlock_trywrlock);
return _pthread_timedlock(rwlock, abstime, &pthread_rwlock_trywrlock);
}
int pthread_rwlock_unlock(pthread_rwlock_t* rwlock)

View File

@ -7,5 +7,13 @@ void siglongjmp(sigjmp_buf env, int val)
{
if (env[_JMP_BUF_REGS])
pthread_sigmask(SIG_SETMASK, reinterpret_cast<sigset_t*>(&env[_JMP_BUF_REGS + 1]), nullptr);
longjmp(env, val);
return longjmp(env, val);
}
int sigsetjmp(sigjmp_buf env, int savemask)
{
env[_JMP_BUF_REGS] = savemask;
if (savemask)
pthread_sigmask(0, nullptr, reinterpret_cast<sigset_t*>(&env[_JMP_BUF_REGS + 1]));
return setjmp(env);
}

View File

@ -164,22 +164,3 @@ int sigrelse(int sig)
(void)sigaddset(&set, sig);
return sigprocmask(SIG_UNBLOCK, &set, nullptr);
}
int sigsuspend(const sigset_t* sigmask)
{
return syscall(SYS_SIGSUSPEND, sigmask);
}
int sigwait(const sigset_t* __restrict set, int* __restrict sig)
{
if (syscall(SYS_SIGWAIT, set, sig) == -1)
return errno;
return 0;
}
int sigaltstack(const stack_t* __restrict ss, stack_t* __restrict oss)
{
if (syscall(SYS_SIGALTSTACK, ss, oss) == -1)
return errno;
return 0;
}

View File

@ -606,7 +606,6 @@ int mbtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n)
return wch ? length : 0;
}
ASSERT_NOT_REACHED();
}
@ -646,31 +645,6 @@ size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n)
return written;
}
int wctomb(char* s, wchar_t wchar)
{
// no state-dependent encodings
if (s == nullptr)
return 0;
switch (__getlocale(LC_CTYPE))
{
case locale_t::LOCALE_INVALID:
ASSERT_NOT_REACHED();
case locale_t::LOCALE_POSIX:
*s = wchar;
return wchar ? 1 : 0;
case locale_t::LOCALE_UTF8:
char buffer[5];
if (!BAN::UTF8::from_codepoints(&wchar, 1, buffer))
return -1;
const size_t length = strlen(buffer);
memcpy(s, buffer, length);
return length;
}
ASSERT_NOT_REACHED();
}
size_t wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n)
{
size_t written = 0;

View File

@ -1,4 +1,3 @@
#include <BAN/Assert.h>
#include <BAN/Debug.h>
#include <BAN/Math.h>
@ -168,18 +167,15 @@ time_t mktime(struct tm* tm)
struct tm* gmtime_r(const time_t* timer, struct tm* __restrict result)
{
// FIXME: allow negative times :)
ASSERT(*timer >= 0);
constexpr uint64_t month_days[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
unsigned long long time = *timer;
time_t time = *timer;
result->tm_sec = time % 60; time /= 60;
result->tm_min = time % 60; time /= 60;
result->tm_hour = time % 24; time /= 24;
unsigned long long total_days = time;
time_t total_days = time;
result->tm_wday = (total_days + 4) % 7;
result->tm_year = 1970;
while (total_days >= 365U + is_leap_year(result->tm_year))

View File

@ -335,10 +335,6 @@ namespace LibGUI
if (m_window_shown_event_callback)
m_window_shown_event_callback(TRY_OR_BREAK(EventPacket::WindowShownEvent::deserialize(packet_data.span())).event);
break;
case PacketType::WindowFocusEvent:
if (m_window_focus_event_callback)
m_window_focus_event_callback(TRY_OR_BREAK(EventPacket::WindowFocusEvent::deserialize(packet_data.span())).event);
break;
case PacketType::KeyEvent:
if (m_key_event_callback)
m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_data.span())).event);

View File

@ -217,7 +217,6 @@ namespace LibGUI
CloseWindowEvent,
ResizeWindowEvent,
WindowShownEvent,
WindowFocusEvent,
KeyEvent,
MouseButtonEvent,
MouseMoveEvent,
@ -334,14 +333,6 @@ namespace LibGUI
event_t, event
);
DEFINE_PACKET_EXTRA(
WindowFocusEvent,
struct event_t {
bool focused;
},
event_t, event
);
DEFINE_PACKET_EXTRA(
KeyEvent,
using event_t = LibInput::KeyEvent,

View File

@ -76,7 +76,6 @@ namespace LibGUI
void set_mouse_move_event_callback(BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> callback) { m_mouse_move_event_callback = callback; }
void set_mouse_scroll_event_callback(BAN::Function<void(EventPacket::MouseScrollEvent::event_t)> callback) { m_mouse_scroll_event_callback = callback; }
void set_window_shown_event_callback(BAN::Function<void(EventPacket::WindowShownEvent::event_t)> callback) { m_window_shown_event_callback = callback; }
void set_window_focus_event_callback(BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> callback) { m_window_focus_event_callback = callback; }
int server_fd() const { return m_server_fd; }
@ -109,7 +108,6 @@ namespace LibGUI
BAN::Function<void()> m_close_window_event_callback;
BAN::Function<void()> m_resize_window_event_callback;
BAN::Function<void(EventPacket::WindowShownEvent::event_t)> m_window_shown_event_callback;
BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> m_window_focus_event_callback;
BAN::Function<void(EventPacket::KeyEvent::event_t)> m_key_event_callback;
BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_event_callback;
BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> m_mouse_move_event_callback;

View File

@ -58,7 +58,7 @@ namespace LibInput
"å", "ä", "ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
/*"Insert", "PrintScreen", "Delete", "Home", "End", "PageUp", "PageDown",*/ nullptr, nullptr, "\x7F", nullptr, nullptr, nullptr, nullptr, "\r", " ",
/*"Insert", "PrintScreen", "Delete", "Home", "End", "PageUp", "PageDown",*/ nullptr, nullptr, "\x7F", nullptr, nullptr, nullptr, nullptr, "\n", " ",
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
"(", ")", "[", "]", "{", "}",
"=", "?", "+", "\\", "´", "`", "¨", "¸", "\b", "@", "£", "$", "",
@ -77,7 +77,7 @@ namespace LibInput
"Å", "Ä", "Ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
/*"Insert", "PrintScreen", "Delete", "Home", "End", "PageUp", "PageDown",*/ nullptr, nullptr, "\x7F", nullptr, nullptr, nullptr, nullptr, "\r", " ",
/*"Insert", "PrintScreen", "Delete", "Home", "End", "PageUp", "PageDown",*/ nullptr, nullptr, "\x7F", nullptr, nullptr, nullptr, nullptr, "\n", " ",
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
"(", ")", "[", "]", "{", "}",
"=", "?", "+", "\\", "´", "`", "¨", "¸", "\b", "@", "£", "$", "",
@ -96,7 +96,7 @@ namespace LibInput
"Å", "Ä", "Ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
/*"Insert", "PrintScreen", "Delete", "Home", "End", "PageUp", "PageDown",*/ nullptr, nullptr, "\x7F", nullptr, nullptr, nullptr, nullptr, "\r", " ",
/*"Insert", "PrintScreen", "Delete", "Home", "End", "PageUp", "PageDown",*/ nullptr, nullptr, "\x7F", nullptr, nullptr, nullptr, nullptr, "\n", " ",
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
"(", ")", "[", "]", "{", "}",
"=", "?", "+", "\\", "´", "`", "¨", "¸", "\b", "@", "£", "$", "",

View File

@ -22,15 +22,15 @@ namespace LibInput
consteval uint8_t keycode_normal(uint8_t row, uint8_t col)
{
BANAN_CONSTEVAL_STATIC_ASSERT(row <= 0b111 - 1);
BANAN_CONSTEVAL_STATIC_ASSERT(col <= 0b11111 - 8);
BANAN_CONSTEVAL_STATIC_ASSERT(col < 0b11111 - 8);
return ((row + 1) << 5) | col;
}
consteval uint8_t keycode_numpad(uint8_t row, uint8_t col)
{
BANAN_CONSTEVAL_STATIC_ASSERT(row <= 0b111 - 1);
BANAN_CONSTEVAL_STATIC_ASSERT(col < 8);
return ((row + 1) << 5) | (col + 0b11111 - 8 + 1);
BANAN_CONSTEVAL_STATIC_ASSERT(col <= 8);
return ((row + 1) << 5) | (col + 0b11111 - 8);
}
enum class Key

View File

@ -116,14 +116,11 @@ uint64_t AudioServer::update()
if (!anyone_playing)
return 60'000;
const uint32_t sample_frames_per_10ms = m_sample_rate / 100;
if (max_sample_frames_to_queue < sample_frames_per_10ms)
{
const uint32_t sample_frames_sent = m_samples_sent / m_channels;
if (sample_frames_sent >= sample_frames_per_10ms)
return 1;
max_sample_frames_to_queue = sample_frames_per_10ms;
}
// FIXME: this works but if any client stops producing audio samples
// the whole audio server halts
const uint32_t samples_per_10ms = m_sample_rate / 100;
if (max_sample_frames_to_queue < samples_per_10ms)
return 1;
for (auto& [_, buffer] : m_audio_buffers)
{
@ -138,7 +135,7 @@ uint64_t AudioServer::update()
continue;
const size_t sample_frames_to_queue = BAN::Math::min<size_t>(max_sample_frames_to_queue, buffer_sample_frames_available);
if (sample_frames_to_queue < sample_frames_per_10ms)
if (sample_frames_to_queue < samples_per_10ms)
continue;
while (m_samples.size() < queued_samples_end + sample_frames_to_queue * m_channels)

View File

@ -190,19 +190,6 @@ struct LoadedElf
bool is_relocating;
char path[PATH_MAX];
struct LoadedPHDR
{
uintptr_t base;
size_t size;
};
LoadedPHDR loaded_phdrs[16];
size_t loaded_phdr_count;
size_t real_symtab_size;
size_t real_symtab_entsize;
const uint8_t* real_symtab_addr;
const uint8_t* real_strtab_addr;
};
static LoadedElf s_loaded_files[128];
@ -446,7 +433,6 @@ extern "C" int __dlclose(void* handle);
extern "C" char* __dlerror(void);
extern "C" void* __dlopen(const char* file, int mode);
extern "C" void* __dlsym(void* __restrict handle, const char* __restrict name);
extern "C" int __dladdr(const void* addr, Dl_info_t* dlip);
template<typename RelocT> requires BAN::is_same_v<RelocT, ElfNativeRelocation> || BAN::is_same_v<RelocT, ElfNativeRelocationA>
static uintptr_t handle_relocation(const LoadedElf& elf, const RelocT& reloc, bool resolve_symbols)
@ -472,7 +458,6 @@ static uintptr_t handle_relocation(const LoadedElf& elf, const RelocT& reloc, bo
CHECK_SYM(__dlerror);
CHECK_SYM(__dlopen);
CHECK_SYM(__dlsym);
CHECK_SYM(__dladdr);
#undef CHECK_SYM
else if (symbol.st_shndx && ELF_ST_BIND(symbol.st_info) != STB_WEAK)
symbol_address = elf.base + symbol.st_value;
@ -962,64 +947,6 @@ static void load_program_header(const ElfNativeProgramHeader& program_header, in
}
}
static bool read_section_header(const LoadedElf& elf, size_t index, ElfNativeSectionHeader& header)
{
if (index >= elf.file_header.e_shnum)
return false;
const auto& file_header = elf.file_header;
if (syscall(SYS_PREAD, elf.fd, &header, sizeof(header), file_header.e_shoff + index * file_header.e_shentsize) != sizeof(header))
return false;
return true;
}
static const uint8_t* mmap_section_header_data(const LoadedElf& elf, const ElfNativeSectionHeader& header)
{
const size_t offset_in_page = header.sh_offset % PAGE_SIZE;
const sys_mmap_t mmap_args {
.addr = nullptr,
.len = header.sh_size + offset_in_page,
.prot = PROT_READ,
.flags = MAP_SHARED,
.fildes = elf.fd,
.off = static_cast<off_t>(header.sh_offset - offset_in_page),
};
const uint8_t* mmap_ret = reinterpret_cast<const uint8_t*>(syscall(SYS_MMAP, &mmap_args));
if (mmap_ret == MAP_FAILED)
return nullptr;
return mmap_ret + offset_in_page;
}
static bool load_symbol_table(LoadedElf& elf)
{
if (elf.file_header.e_shentsize < sizeof(ElfNativeSectionHeader))
return false;
for (size_t i = 0; i < elf.file_header.e_shnum; i++)
{
ElfNativeSectionHeader symtab_header;
if (!read_section_header(elf, i, symtab_header))
return false;
if (symtab_header.sh_type != SHT_SYMTAB)
continue;
ElfNativeSectionHeader strtab_header;
if (!read_section_header(elf, symtab_header.sh_link, strtab_header))
return false;
elf.real_symtab_entsize = symtab_header.sh_entsize;
elf.real_symtab_size = symtab_header.sh_size;
elf.real_symtab_addr = mmap_section_header_data(elf, symtab_header);
elf.real_strtab_addr = mmap_section_header_data(elf, strtab_header);
return true;
}
return false;
}
static LoadedElf& load_elf(const char* path, int fd)
{
for (size_t i = 0; i < s_loaded_file_count; i++)
@ -1094,13 +1021,8 @@ static LoadedElf& load_elf(const char* path, int fd)
break;
}
auto& elf = s_loaded_files[s_loaded_file_count++];
elf.tls_header.p_type = PT_NULL;
elf.base = base;
elf.fd = fd;
elf.dynamics = nullptr;
memcpy(&elf.file_header, &file_header, sizeof(file_header));
strcpy(elf.path, path);
ElfNativeProgramHeader tls_header {};
tls_header.p_type = PT_NULL;
for (size_t i = 0; i < file_header.e_phnum; i++)
{
@ -1121,20 +1043,10 @@ static LoadedElf& load_elf(const char* path, int fd)
case PT_GNU_RELRO:
break;
case PT_TLS:
elf.tls_header = program_header;
tls_header = program_header;
break;
case PT_LOAD:
if (elf.loaded_phdr_count >= sizeof(elf.loaded_phdrs) / sizeof(*elf.loaded_phdrs))
{
print(STDERR_FILENO, "file '");
print(STDERR_FILENO, elf.path);
print_error_and_exit("' has too many PT_LOAD headers", 0);
}
program_header.p_vaddr += base;
elf.loaded_phdrs[elf.loaded_phdr_count++] = {
.base = program_header.p_vaddr,
.size = program_header.p_memsz,
};
load_program_header(program_header, fd, needs_writable);
break;
default:
@ -1144,6 +1056,13 @@ static LoadedElf& load_elf(const char* path, int fd)
}
}
auto& elf = s_loaded_files[s_loaded_file_count++];
elf.tls_header = tls_header;
elf.base = base;
elf.fd = fd;
elf.dynamics = nullptr;
memcpy(&elf.file_header, &file_header, sizeof(file_header));
strcpy(elf.path, path);
if (has_dynamic_pheader)
{
@ -1165,8 +1084,6 @@ static LoadedElf& load_elf(const char* path, int fd)
handle_dynamic(elf);
}
load_symbol_table(elf);
return elf;
}
@ -1502,88 +1419,6 @@ void* __dlsym(void* __restrict handle, const char* __restrict name)
return nullptr;
}
static bool elf_contains_address(const LoadedElf& elf, const void* address)
{
const uintptr_t addr_uptr = reinterpret_cast<uintptr_t>(address);
for (size_t i = 0; i < elf.loaded_phdr_count; i++)
{
const auto& phdr = elf.loaded_phdrs[i];
if (phdr.base <= addr_uptr && addr_uptr < phdr.base + phdr.size)
return true;
}
return false;
}
struct FindSymbolResult
{
const char* name;
void* addr;
};
static FindSymbolResult find_symbol_containing(const LoadedElf& elf, const void* address)
{
const uintptr_t addr_uptr = reinterpret_cast<uintptr_t>(address);
const size_t symbol_count = reinterpret_cast<const uint32_t*>(elf.hash)[1];
for (size_t i = 1; i < symbol_count; i++)
{
const auto& symbol = *reinterpret_cast<const ElfNativeSymbol*>(elf.symtab + i * elf.syment);
const uintptr_t symbol_base = elf.base + symbol.st_value;
if (!(symbol_base <= addr_uptr && addr_uptr < symbol_base + symbol.st_size))
continue;
return {
.name = reinterpret_cast<const char*>(elf.strtab + symbol.st_name),
.addr = reinterpret_cast<void*>(symbol_base),
};
}
if (!elf.real_symtab_addr || !elf.real_strtab_addr)
return {};
for (size_t i = 1; i < elf.real_symtab_size / elf.real_symtab_entsize; i++)
{
const auto& symbol = *reinterpret_cast<const ElfNativeSymbol*>(elf.real_symtab_addr + i * elf.real_symtab_entsize);
const uintptr_t symbol_base = elf.base + symbol.st_value;
if (!(symbol_base <= addr_uptr && addr_uptr < symbol_base + symbol.st_size))
continue;
return {
.name = reinterpret_cast<const char*>(elf.real_strtab_addr + symbol.st_name),
.addr = reinterpret_cast<void*>(symbol_base),
};
}
return {};
}
int __dladdr(const void* addr, Dl_info_t* dlip)
{
for (size_t i = 0; i < s_loaded_file_count; i++)
{
const auto& elf = s_loaded_files[i];
if (!elf_contains_address(elf, addr))
continue;
dlip->dli_fname = elf.path;
dlip->dli_fbase = reinterpret_cast<void*>(elf.base);
if (const auto symbol = find_symbol_containing(elf, addr); symbol.addr && symbol.name)
{
dlip->dli_sname = symbol.name;
dlip->dli_saddr = symbol.addr;
}
else
{
dlip->dli_sname = nullptr;
dlip->dli_saddr = nullptr;
}
return 1;
}
s_dlerror_string = "address is not contained in any file";
return 0;
}
static LibELF::AuxiliaryVector* find_auxv(char** envp)
{
if (envp == nullptr)

View File

@ -181,6 +181,13 @@ void Terminal::run()
perror("ioctl");
return;
}
const pid_t fgpgrp = tcgetpgrp(m_shell_info.pts_master);
if (fgpgrp == -1)
{
perror("tcgetpgrp");
return;
}
});
const int max_fd = BAN::Math::max(m_shell_info.pts_master, m_window->server_fd());
@ -669,14 +676,6 @@ Rectangle Terminal::putcodepoint(uint32_t codepoint)
auto& texture = m_window->texture();
switch (codepoint)
{
case 0x00: // null
case 0x01: // start of heading
case 0x02: // start of text
case 0x1C: // file separator
case 0x1D: // group separator
case 0x1E: // record separator
case 0x1F: // unit separator
break;
case '\a':
// TODO: bell
break;

View File

@ -90,7 +90,7 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
window_popper.disable();
if (packet.attributes.shown && packet.attributes.focusable)
if (packet.attributes.focusable)
set_focused_window(window);
else if (m_client_windows.size() > 1)
BAN::swap(m_client_windows[m_client_windows.size() - 1], m_client_windows[m_client_windows.size() - 2]);
@ -197,9 +197,6 @@ void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket::
};
if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error())
dwarnln("could not send window shown event: {}", ret.error());
if (packet.attributes.focusable && packet.attributes.shown)
set_focused_window(target_window);
}
void WindowServer::on_window_set_mouse_relative(int fd, const LibGUI::WindowPacket::WindowSetMouseRelative& packet)
@ -515,9 +512,7 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
}
BAN::RefPtr<Window> target_window;
if (m_state == State::Fullscreen)
target_window = m_focused_window;
if (!event.pressed && !target_window)
if (!event.pressed)
target_window = m_mouse_button_windows[button_idx];
for (size_t i = m_client_windows.size(); i > 0 && !target_window; i--)
if (m_client_windows[i - 1]->full_area().contains(m_cursor) && m_client_windows[i - 1]->get_attributes().shown)
@ -561,7 +556,7 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
if (event.button == LibInput::MouseButton::Left && !event.pressed && target_window->close_button_area().contains(m_cursor))
{
LibGUI::EventPacket::CloseWindowEvent packet;
if (auto ret = packet.send_serialized(target_window->client_fd()); ret.is_error())
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
dwarnln("could not send close window event: {}", ret.error());
break;
}
@ -573,9 +568,9 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
LibGUI::EventPacket::MouseButtonEvent packet;
packet.event.button = event.button;
packet.event.pressed = event.pressed;
packet.event.x = m_cursor.x - target_window->client_x();
packet.event.y = m_cursor.y - target_window->client_y();
if (auto ret = packet.send_serialized(target_window->client_fd()); ret.is_error())
packet.event.x = m_cursor.x - m_focused_window->client_x();
packet.event.y = m_cursor.y - m_focused_window->client_y();
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
{
dwarnln("could not send mouse button event: {}", ret.error());
return;
@ -784,17 +779,6 @@ void WindowServer::set_focused_window(BAN::RefPtr<Window> window)
invalidate(cursor_area());
}
if (m_focused_window)
{
LibGUI::EventPacket::WindowFocusEvent packet;
packet.event.focused = false;
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
{
dwarnln("could not send window focus event: {}", ret.error());
return;
}
}
for (size_t i = m_client_windows.size(); i > 0; i--)
{
if (m_client_windows[i - 1] == window)
@ -806,17 +790,6 @@ void WindowServer::set_focused_window(BAN::RefPtr<Window> window)
break;
}
}
if (m_focused_window)
{
LibGUI::EventPacket::WindowFocusEvent packet;
packet.event.focused = true;
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
{
dwarnln("could not send window focus event: {}", ret.error());
return;
}
}
}
static uint32_t alpha_blend(uint32_t color_a, uint32_t color_b)
@ -1437,10 +1410,6 @@ void WindowServer::remove_client_fd(int fd)
invalidate(m_framebuffer.area());
}
for (auto& window : m_mouse_button_windows)
if (window && window->client_fd() == fd)
window.clear();
for (size_t i = 0; i < m_client_windows.size(); i++)
{
auto window = m_client_windows[i];