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 addl $8, %esp
popf popf
movl (%esp), %esp
ret ret

View File

@ -59,7 +59,5 @@ signal_trampoline:
addq $16, %rsp addq $16, %rsp
popfq popfq
movq (%rsp), %rsp
// return over red-zone // return over red-zone
ret $128 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_sigaction(int signal, const struct sigaction* act, struct sigaction* oact);
BAN::ErrorOr<long> sys_sigpending(sigset_t* set); 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_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_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime);
BAN::ErrorOr<long> sys_yield(); BAN::ErrorOr<long> sys_yield();
@ -350,6 +347,14 @@ namespace Kernel
BAN::UniqPtr<PageTable> m_page_table; BAN::UniqPtr<PageTable> m_page_table;
BAN::RefPtr<TTY> m_controlling_terminal; 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; friend class Thread;
}; };

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <BAN/NoCopyMove.h> #include <BAN/NoCopyMove.h>
#include <BAN/Optional.h>
#include <BAN/RefPtr.h> #include <BAN/RefPtr.h>
#include <BAN/UniqPtr.h> #include <BAN/UniqPtr.h>
#include <kernel/InterruptStack.h> #include <kernel/InterruptStack.h>
@ -60,10 +59,7 @@ namespace Kernel
bool will_execute_signal() const; bool will_execute_signal() const;
// Returns true if handled signal had SA_RESTART // Returns true if handled signal had SA_RESTART
bool handle_signal(int signal = 0); bool handle_signal(int signal = 0);
void add_signal(int signal); bool add_signal(int signal);
void set_suspend_signal_mask(uint64_t sigmask);
BAN::ErrorOr<void> sigaltstack(const stack_t* ss, stack_t* oss);
// blocks current thread and returns either on unblock, eintr, spuriously or after timeout // 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 // 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*); static void on_exit_trampoline(Thread*);
void on_exit(); void on_exit();
bool currently_on_alternate_stack() const;
private: private:
// NOTE: this is the first member to force it being last destructed // NOTE: this is the first member to force it being last destructed
// {kernel,userspace}_stack has to be destroyed before page table // {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_pending_mask { 0 };
uint64_t m_signal_block_mask { 0 }; uint64_t m_signal_block_mask { 0 };
BAN::Optional<uint64_t> m_signal_suspend_mask;
SpinLock m_signal_lock; SpinLock m_signal_lock;
stack_t m_signal_alt_stack { nullptr, 0, SS_DISABLE };
static_assert(_SIGMAX < 64); static_assert(_SIGMAX < 64);
mutable SpinLock m_cpu_time_lock; 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); 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 // Absolute path
@ -460,15 +460,23 @@ namespace Kernel::ACPI::AML
// Relative path // Relative path
Scope path_guess; Scope path_guess;
TRY(path_guess.parts.reserve(scope.parts.size() + 1)); TRY(path_guess.parts.reserve(scope.parts.size() + name_string.parts.size()));
const uint32_t name_seg = name_string.parts.front();
for (const auto& part : scope.parts) for (const auto& part : scope.parts)
TRY(path_guess.parts.push_back(part)); 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); auto it = m_named_objects.find(path_guess);
if (it != m_named_objects.end()) { if (it != m_named_objects.end()) {
return FindResult { return FindResult {
@ -476,17 +484,12 @@ namespace Kernel::ACPI::AML
.node = it->value, .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) BAN::ErrorOr<Scope> Namespace::find_reference_scope(const Reference* reference)

View File

@ -30,19 +30,19 @@ namespace Kernel
timespec FATInode::atime() const 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 }; return timespec { .tv_sec = epoch, .tv_nsec = 0 };
} }
timespec FATInode::mtime() const 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 }; return timespec { .tv_sec = epoch, .tv_nsec = 0 };
} }
timespec FATInode::ctime() const 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 }; return timespec { .tv_sec = epoch, .tv_nsec = 0 };
} }

View File

@ -256,84 +256,84 @@ namespace Kernel::Input
void PS2Keymap::initialize_scancode_set3() void PS2Keymap::initialize_scancode_set3()
{ {
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 0); 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[0x16] = keycode_normal(0, 1);
m_scancode_to_keycode_normal[0x1E] = keycode_normal(0, 2); 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[0x26] = keycode_normal(0, 3);
m_scancode_to_keycode_normal[0x25] = keycode_normal(0, 4); 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[0x2E] = keycode_normal(0, 5);
m_scancode_to_keycode_normal[0x36] = keycode_normal(0, 6); 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[0x3D] = keycode_normal(0, 7);
m_scancode_to_keycode_normal[0x3E] = keycode_normal(0, 8); 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[0x46] = keycode_normal(0, 9);
m_scancode_to_keycode_normal[0x45] = keycode_normal(0, 10); 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[0x4E] = keycode_normal(0, 11);
m_scancode_to_keycode_normal[0x55] = keycode_normal(0, 12); 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[0x66] = keycode_normal(0, 13);
m_scancode_to_keycode_normal[0x0D] = keycode_normal(1, 0); 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[0x15] = keycode_normal(1, 1);
m_scancode_to_keycode_normal[0x1D] = keycode_normal(1, 2); 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[0x24] = keycode_normal(1, 3);
m_scancode_to_keycode_normal[0x2D] = keycode_normal(1, 4); 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[0x2C] = keycode_normal(1, 5);
m_scancode_to_keycode_normal[0x35] = keycode_normal(1, 6); 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[0x3C] = keycode_normal(1, 7);
m_scancode_to_keycode_normal[0x43] = keycode_normal(1, 8); 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[0x44] = keycode_normal(1, 9);
m_scancode_to_keycode_normal[0x4D] = keycode_normal(1, 10); 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[0x54] = keycode_normal(1, 11);
m_scancode_to_keycode_normal[0x5B] = keycode_normal(1, 12); 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[0x14] = keycode_normal(2, 0);
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 1); 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[0x1B] = keycode_normal(2, 2);
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 3); 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[0x2B] = keycode_normal(2, 4);
m_scancode_to_keycode_normal[0x34] = keycode_normal(2, 5); 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[0x33] = keycode_normal(2, 6);
m_scancode_to_keycode_normal[0x3B] = keycode_normal(2, 7); 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[0x42] = keycode_normal(2, 8);
m_scancode_to_keycode_normal[0x4B] = keycode_normal(2, 9); 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[0x4C] = keycode_normal(2, 10);
m_scancode_to_keycode_normal[0x52] = keycode_normal(2, 11); 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[0x5C] = keycode_normal(2, 12);
m_scancode_to_keycode_normal[0x5A] = keycode_normal(2, 13); 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[0x12] = keycode_normal(3, 0);
m_scancode_to_keycode_normal[0x13] = keycode_normal(3, 1); 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[0x1A] = keycode_normal(3, 2);
m_scancode_to_keycode_normal[0x22] = keycode_normal(3, 3); 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[0x21] = keycode_normal(3, 4);
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 5); 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[0x32] = keycode_normal(3, 6);
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7); 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[0x3A] = keycode_normal(3, 8);
m_scancode_to_keycode_normal[0x41] = keycode_normal(3, 9); 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[0x49] = keycode_normal(3, 10);
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11); 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[0x59] = keycode_normal(3, 12);
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 0); 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[0x8B] = keycode_normal(4, 1);
m_scancode_to_keycode_normal[0x19] = keycode_normal(4, 2); 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[0x29] = keycode_normal(4, 3);
m_scancode_to_keycode_normal[0x39] = keycode_normal(4, 4); 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[0x58] = keycode_normal(4, 5);
m_scancode_to_keycode_normal[0x76] = keycode_numpad(0, 0); 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[0x7E] = keycode_numpad(0, 2);
m_scancode_to_keycode_normal[0x4E] = keycode_numpad(0, 3); //m_scancode_to_keycode_normal[0x] = keycode_numpad(0, 3);
m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 0); m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 1);
m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 1); m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 2);
m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 2); m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 3);
m_scancode_to_keycode_normal[0x7C] = keycode_numpad(1, 3); m_scancode_to_keycode_normal[0x7C] = keycode_numpad(1, 4);
m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 0); m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 1);
m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 1); m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 2);
m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 2); m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 3);
m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 0); m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 1);
m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 1); m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 2);
m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 2); m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 3);
m_scancode_to_keycode_normal[0x79] = keycode_numpad(3, 3); m_scancode_to_keycode_normal[0x79] = keycode_numpad(3, 4);
m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 0); m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 1);
m_scancode_to_keycode_normal[0x71] = 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[0x08] = keycode_function(0);
m_scancode_to_keycode_normal[0x07] = keycode_function(1); 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) 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) 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)); 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_sizes.push(packet.size());
m_packet_thread_blocker.unblock(); m_packet_thread_blocker.unblock();
m_packet_lock.unlock(state);
epoll_notify(EPOLLIN); epoll_notify(EPOLLIN);
@ -413,7 +414,7 @@ namespace Kernel
BAN::ErrorOr<size_t> UnixDomainSocket::recvfrom_impl(BAN::ByteSpan buffer, sockaddr*, socklen_t*) 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) while (m_packet_size_total == 0)
{ {
if (m_info.has<ConnectionInfo>()) if (m_info.has<ConnectionInfo>())
@ -421,12 +422,18 @@ namespace Kernel
auto& connection_info = m_info.get<ConnectionInfo>(); auto& connection_info = m_info.get<ConnectionInfo>();
bool expected = true; bool expected = true;
if (connection_info.target_closed.compare_exchange(expected, false)) if (connection_info.target_closed.compare_exchange(expected, false))
{
m_packet_lock.unlock(state);
return 0; return 0;
}
if (!connection_info.connection) if (!connection_info.connection)
{
m_packet_lock.unlock(state);
return BAN::Error::from_errno(ENOTCONN); 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)); 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_size_total -= nread;
m_packet_thread_blocker.unblock(); m_packet_thread_blocker.unblock();
m_packet_lock.unlock(state);
epoll_notify(EPOLLOUT); epoll_notify(EPOLLOUT);

View File

@ -37,15 +37,6 @@ namespace Kernel
static BAN::Vector<Process*> s_processes; static BAN::Vector<Process*> s_processes;
static RecursiveSpinLock s_process_lock; 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) static void for_each_process(const BAN::Function<BAN::Iteration(Process&)>& callback)
{ {
SpinLockGuard _(s_process_lock); SpinLockGuard _(s_process_lock);
@ -318,7 +309,7 @@ namespace Kernel
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
for (auto* thread : m_threads) for (auto* thread : m_threads)
if (thread != &Thread::current()) if (thread != &Thread::current())
thread->add_signal(SIGKILL); ASSERT(thread->add_signal(SIGKILL));
} }
while (m_threads.size() > 1) 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) BAN::ErrorOr<long> Process::sys_hardlinkat(int fd1, const char* path1, int fd2, const char* path2, int flag)
{ {
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
if (path1 != nullptr) TRY(validate_string_access(path1));
TRY(validate_string_access(path1)); TRY(validate_string_access(path2));
if (path2 != nullptr)
TRY(validate_string_access(path2));
auto inode = TRY(find_file(fd1, path1, flag)).inode; auto inode = TRY(find_file(fd1, path1, flag)).inode;
if (inode->mode().ifdir()) if (inode->mode().ifdir())
@ -1191,8 +1180,7 @@ namespace Kernel
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
LockGuard _(m_process_lock); 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)); 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) BAN::ErrorOr<long> Process::sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize)
{ {
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
if (path != nullptr) TRY(validate_string_access(path));
TRY(validate_string_access(path));
TRY(validate_pointer_access(buffer, bufsize, true)); TRY(validate_pointer_access(buffer, bufsize, true));
auto inode = TRY(find_file(fd, path, O_NOFOLLOW | O_RDONLY)).inode; auto inode = TRY(find_file(fd, path, O_NOFOLLOW | O_RDONLY)).inode;
@ -1275,8 +1262,7 @@ namespace Kernel
flag = O_NOFOLLOW; flag = O_NOFOLLOW;
LockGuard _(m_process_lock); 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; auto inode = TRY(find_file(fd, path, flag)).inode;
@ -1299,8 +1285,7 @@ namespace Kernel
flag = O_NOFOLLOW; flag = O_NOFOLLOW;
LockGuard _(m_process_lock); 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; auto inode = TRY(find_file(fd, path, flag)).inode;
@ -1986,8 +1971,6 @@ namespace Kernel
flag = O_NOFOLLOW; flag = O_NOFOLLOW;
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_pointer_access(buf, sizeof(struct stat), true)); TRY(validate_pointer_access(buf, sizeof(struct stat), true));
auto inode = TRY(find_file(fd, path, flag)).inode; 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) BAN::ErrorOr<long> Process::sys_fstatvfsat(int fd, const char* path, struct statvfs* buf)
{ {
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
if (path != nullptr)
TRY(validate_string_access(path));
TRY(validate_pointer_access(buf, sizeof(struct statvfs), true)); TRY(validate_pointer_access(buf, sizeof(struct statvfs), true));
auto inode = TRY(find_file(fd, path, 0)).inode; 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); 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.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; 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) if (args.flags & MAP_ANONYMOUS)
@ -2671,81 +2641,23 @@ namespace Kernel
return 0; 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) 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); const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
if (vaddr % 4) if (vaddr % 4)
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
const bool is_private = (op & FUTEX_PRIVATE);
const bool is_realtime = (op & FUTEX_REALTIME); const bool is_realtime = (op & FUTEX_REALTIME);
op &= ~(FUTEX_PRIVATE | 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)); auto* buffer_region = TRY(validate_and_pin_pointer_access(addr, sizeof(uint32_t), false));
BAN::ScopeGuard pin_guard([&] { if (buffer_region) buffer_region->unpin(); }); 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); return SystemTimer::get().ns_since_boot() + (abs_ns - real_ns);
}()); }());
auto it = s_futexes.find(paddr); auto it = m_futexes.find(paddr);
if (it == s_futexes.end()) if (it == m_futexes.end())
it = TRY(s_futexes.emplace(paddr, TRY(BAN::UniqPtr<futex_t>::create()))); it = TRY(m_futexes.emplace(paddr, TRY(BAN::UniqPtr<futex_t>::create())));
futex_t* const futex = it->value.ptr(); futex_t* const futex = it->value.ptr();
futex->waiters++; futex->waiters++;
BAN::ScopeGuard _([futex, paddr] { BAN::ScopeGuard _([futex, paddr, this] {
if (--futex->waiters == 0) if (--futex->waiters == 0)
s_futexes.remove(paddr); m_futexes.remove(paddr);
}); });
for (;;) 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) if (BAN::atomic_load(*addr) == val || futex->to_wakeup == 0)
continue; continue;
futex->to_wakeup--; futex->to_wakeup--;
@ -2798,8 +2710,8 @@ namespace Kernel
} }
case FUTEX_WAKE: case FUTEX_WAKE:
{ {
auto it = s_futexes.find(paddr); auto it = m_futexes.find(paddr);
if (it == s_futexes.end()) if (it == m_futexes.end())
return 0; return 0;
futex_t* const futex = it->value.ptr(); 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) BAN::ErrorOr<long> Process::sys_getgroups(gid_t groups[], size_t count)
{ {
LockGuard _(m_process_lock); 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)); TRY(validate_pointer_access(groups, count * sizeof(gid_t), true));
auto current = m_credentials.groups();
if (current.size() > count) if (current.size() > count)
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
for (size_t i = 0; i < current.size(); i++) 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 // 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)); TRY(validate_pointer_access_check(ptr, size, needs_write));
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(ptr); 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()) if (ret.is_error() && ret.error().is_kernel_error())
Kernel::panic("Kernel error while returning to userspace {}", ret.error()); Kernel::panic("Kernel error while returning to userspace {}", ret.error());
Processor::set_interrupt_state(InterruptState::Disabled);
auto& current_thread = Thread::current(); auto& current_thread = Thread::current();
if (current_thread.can_add_signal_to_execute()) if (current_thread.can_add_signal_to_execute())
if (current_thread.handle_signal()) if (current_thread.handle_signal())
if (ret.is_error() && ret.error().get_error_code() == EINTR && is_restartable_syscall(syscall)) if (ret.is_error() && ret.error().get_error_code() == EINTR && is_restartable_syscall(syscall))
ret = BAN::Error::from_errno(ERESTART); ret = BAN::Error::from_errno(ERESTART);
Processor::set_interrupt_state(InterruptState::Disabled);
ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing); ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing);
if (ret.is_error()) 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) PseudoTerminalSlave::PseudoTerminalSlave(BAN::String&& name, uint32_t number, mode_t mode, uid_t uid, gid_t gid)
: TTY({ : TTY({
.c_iflag = ICRNL, .c_iflag = 0,
.c_oflag = 0, .c_oflag = 0,
.c_cflag = CS8, .c_cflag = CS8,
.c_lflag = ECHO | ECHOE | ECHOK | ICANON | ISIG, .c_lflag = ECHO | ECHOE | ECHOK | ICANON | ISIG,

View File

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

View File

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

View File

@ -69,20 +69,6 @@ namespace Kernel
s_default_sse_storage_initialized = true; 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) BAN::ErrorOr<Thread*> Thread::create_kernel(entry_t entry, void* data)
{ {
// Create the thread object // Create the thread object
@ -481,7 +467,7 @@ namespace Kernel
} }
if (signal_handler == (vaddr_t)SIG_IGN) if (signal_handler == (vaddr_t)SIG_IGN)
continue; 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; continue;
return true; return true;
} }
@ -507,7 +493,6 @@ namespace Kernel
ASSERT(is_userspace()); ASSERT(is_userspace());
auto state = m_signal_lock.lock(); auto state = m_signal_lock.lock();
ASSERT(state == InterruptState::Disabled);
auto& interrupt_stack = *reinterpret_cast<InterruptStack*>(kernel_stack_top() - sizeof(InterruptStack)); auto& interrupt_stack = *reinterpret_cast<InterruptStack*>(kernel_stack_top() - sizeof(InterruptStack));
ASSERT(GDT::is_user_segment(interrupt_stack.cs)); ASSERT(GDT::is_user_segment(interrupt_stack.cs));
@ -531,7 +516,6 @@ namespace Kernel
vaddr_t signal_handler; vaddr_t signal_handler;
bool has_sa_restart; bool has_sa_restart;
vaddr_t signal_stack_top = 0;
{ {
SpinLockGuard _(m_process->m_signal_lock); SpinLockGuard _(m_process->m_signal_lock);
@ -544,23 +528,11 @@ namespace Kernel
handler.sa_handler = SIG_DFL; handler.sa_handler = SIG_DFL;
has_sa_restart = !!(handler.sa_flags & SA_RESTART); 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); m_signal_pending_mask &= ~(1ull << signal);
process().remove_pending_signal(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) if (signal_handler == (vaddr_t)SIG_IGN)
; ;
else if (signal_handler != (vaddr_t)SIG_DFL) else if (signal_handler != (vaddr_t)SIG_DFL)
@ -569,32 +541,7 @@ namespace Kernel
#if ARCH(x86_64) #if ARCH(x86_64)
interrupt_stack.sp -= 128; // skip possible red-zone interrupt_stack.sp -= 128; // skip possible red-zone
#endif #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); 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, interrupt_stack.flags);
write_to_stack(interrupt_stack.sp, signal); write_to_stack(interrupt_stack.sp, signal);
write_to_stack(interrupt_stack.sp, signal_handler); write_to_stack(interrupt_stack.sp, signal_handler);
@ -615,6 +562,7 @@ namespace Kernel
case SIGTRAP: case SIGTRAP:
case SIGXCPU: case SIGXCPU:
case SIGXFSZ: case SIGXFSZ:
m_signal_lock.unlock(state);
process().exit(128 + signal, signal | 0x80); process().exit(128 + signal, signal | 0x80);
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -630,11 +578,18 @@ namespace Kernel
case SIGPOLL: case SIGPOLL:
case SIGPROF: case SIGPROF:
case SIGVTALRM: case SIGVTALRM:
m_signal_lock.unlock(state);
process().exit(128 + signal, signal); process().exit(128 + signal, signal);
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
// Ignore the signal
case SIGCHLD:
case SIGURG:
case SIGWINCH:
case SIGCANCEL:
break;
// Stop the process: // Stop the process:
case SIGSTOP:
case SIGTSTP: case SIGTSTP:
case SIGTTIN: case SIGTTIN:
case SIGTTOU: case SIGTTOU:
@ -643,18 +598,15 @@ namespace Kernel
// Continue the process, if it is stopped; otherwise, ignore the signal. // Continue the process, if it is stopped; otherwise, ignore the signal.
case SIGCONT: case SIGCONT:
ASSERT_NOT_REACHED(); 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; return has_sa_restart;
} }
void Thread::add_signal(int signal) bool Thread::add_signal(int signal)
{ {
SpinLockGuard _(m_signal_lock); SpinLockGuard _(m_signal_lock);
if (m_process) if (m_process)
@ -666,64 +618,19 @@ namespace Kernel
signal_handler = (vaddr_t)m_process->m_signal_handlers[signal].sa_handler; signal_handler = (vaddr_t)m_process->m_signal_handlers[signal].sa_handler;
} }
if (signal_handler == (vaddr_t)SIG_IGN) if (signal_handler == (vaddr_t)SIG_IGN)
return; return false;
if (signal_handler == (vaddr_t)SIG_DFL && is_default_ignored_signal(signal)) if (signal_handler == (vaddr_t)SIG_DFL && (signal == SIGCHLD || signal == SIGURG))
return; return false;
} }
uint64_t mask = 1ull << signal;
const uint64_t mask = 1ull << signal; if (!(m_signal_block_mask & mask))
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)
{ {
*oss = m_signal_alt_stack; m_signal_pending_mask |= mask;
if (on_alt_stack) if (this != &Thread::current())
oss->ss_flags = SS_ONSTACK; Processor::scheduler().unblock_thread(this);
return true;
} }
return false;
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 {};
} }
BAN::ErrorOr<void> Thread::sleep_or_eintr_ns(uint64_t ns) 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; long ns_this_second = ticks_this_second * regs.counter_clk_period / FS_PER_NS;
return timespec { return timespec {
.tv_sec = static_cast<time_t>(seconds), .tv_sec = seconds,
.tv_nsec = ns_this_second .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: */ +/* 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 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/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 +++ 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,724 @@ @@ -0,0 +1,718 @@
+/* +/*
+ Simple DirectMedia Layer + Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> + 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( + ban_window->window->set_close_window_event_callback(
+ [window]() { + [window]() {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0);

View File

@ -3,16 +3,15 @@
NAME='SDL2_mixer' NAME='SDL2_mixer'
VERSION='2.8.1' VERSION='2.8.1'
DOWNLOAD_URL="https://github.com/libsdl-org/SDL_mixer/releases/download/release-$VERSION/SDL2_mixer-$VERSION.tar.gz#cb760211b056bfe44f4a1e180cc7cb201137e4d1572f2002cc1be728efd22660" 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() { configure() {
$BANAN_CMAKE --fresh -S . -B build -G Ninja \ $BANAN_CMAKE --fresh -S . -B build -G Ninja \
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \ --toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
-DCMAKE_INSTALL_PREFIX='/usr' \ -DCMAKE_INSTALL_PREFIX='/usr' \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DSDL2MIXER_DEPS_SHARED=OFF \
-DSDL2MIXER_MIDI_FLUIDSYNTH=OFF \
-DSDL2MIXER_WAVPACK=OFF \ -DSDL2MIXER_WAVPACK=OFF \
-DSDL2MIXER_MIDI=OFF \
-DSDL2MIXER_OPUS=OFF \ -DSDL2MIXER_OPUS=OFF \
-DSDL2MIXER_MOD=OFF \ -DSDL2MIXER_MOD=OFF \
|| exit 1 || 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 xorl %eax, %eax
ret ret
.size setjmp, . - setjmp .size setjmp, . - setjmp
// void longjmp(jmp_buf env, int val) // void longjmp(jmp_buf env, int val)
@ -38,27 +39,5 @@ longjmp:
movl 16(%edx), %edi movl 16(%edx), %edi
movl 20(%edx), %esi movl 20(%edx), %esi
jmp *%ecx jmp *%ecx
.size longjmp, . - longjmp .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 movq 56(%rdi), %r15
jmp *%rcx jmp *%rcx
.size longjmp, . - longjmp .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> #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)); extern "C" int __dlclose(void*) __attribute__((weak));
int dlclose(void* handle) int dlclose(void* handle)
{ {

View File

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

View File

@ -15,18 +15,6 @@ __BEGIN_DECLS
#define RTLD_NEXT ((void*)-1) #define RTLD_NEXT ((void*)-1)
#define RTLD_DEFAULT ((void*) 0) #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); int dlclose(void* handle);
char* dlerror(void); char* dlerror(void);
void* dlopen(const char* file, int mode); 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_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, 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_RWLOCK_INITIALIZER (pthread_rwlock_t){ { 0 }, 0, 0 }
#define _PTHREAD_ATFORK_PREPARE 0 #define _PTHREAD_ATFORK_PREPARE 0

View File

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

View File

@ -90,9 +90,6 @@ __BEGIN_DECLS
O(SYS_SIGACTION, sigaction) \ O(SYS_SIGACTION, sigaction) \
O(SYS_SIGPENDING, sigpending) \ O(SYS_SIGPENDING, sigpending) \
O(SYS_SIGPROCMASK, sigprocmask) \ O(SYS_SIGPROCMASK, sigprocmask) \
O(SYS_SIGSUSPEND, sigsuspend) \
O(SYS_SIGWAIT, sigwait) \
O(SYS_SIGALTSTACK, sigaltstack) \
O(SYS_SETITIMER, setitimer) \ O(SYS_SETITIMER, setitimer) \
O(SYS_POSIX_OPENPT, posix_openpt) \ O(SYS_POSIX_OPENPT, posix_openpt) \
O(SYS_PTSNAME, ptsname) \ 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)) #if !defined(__time_t_defined) && (defined(__need_all_types) || defined(__need_time_t))
#define __time_t_defined 1 #define __time_t_defined 1
typedef long long time_t; typedef unsigned long long time_t;
#endif #endif
#undef __need_time_t #undef __need_time_t

View File

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

View File

@ -736,6 +736,34 @@ int pthread_spin_unlock(pthread_spinlock_t* lock)
return 0; 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) int pthread_mutexattr_destroy(pthread_mutexattr_t* attr)
{ {
(void)attr; (void)attr;
@ -807,8 +835,7 @@ int pthread_mutex_init(pthread_mutex_t* __restrict mutex, const pthread_mutexatt
attr = &default_attr; attr = &default_attr;
*mutex = { *mutex = {
.attr = *attr, .attr = *attr,
.futex = 0, .locker = 0,
.waiters = 0,
.lock_depth = 0, .lock_depth = 0,
}; };
return 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) 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 auto tid = pthread_self();
{
const uint32_t tid = pthread_self();
switch (mutex->attr.type) switch (mutex->attr.type)
{ {
case PTHREAD_MUTEX_RECURSIVE: case PTHREAD_MUTEX_RECURSIVE:
if (mutex->futex != tid) if (mutex->locker != tid)
break; break;
mutex->lock_depth++; mutex->lock_depth++;
return 0; return 0;
case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_ERRORCHECK:
if (mutex->futex != tid) if (mutex->locker != tid)
break; break;
return EDEADLK; return EDEADLK;
} }
uint32_t expected = 0; pthread_t expected = 0;
if (!BAN::atomic_compare_exchange(mutex->futex, expected, tid, BAN::MemoryOrder::memory_order_acquire)) 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; return EBUSY;
mutex->lock_depth = 1; 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) int pthread_mutex_timedlock(pthread_mutex_t* __restrict mutex, const struct timespec* __restrict abstime)
{ {
// recursive/errorcheck handled in trylock to remove code duplication return _pthread_timedlock(mutex, abstime, &pthread_mutex_trylock);
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;
} }
int pthread_mutex_unlock(pthread_mutex_t* mutex) 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--; mutex->lock_depth--;
if (mutex->lock_depth == 0) if (mutex->lock_depth == 0)
{ BAN::atomic_store(mutex->locker, 0, BAN::MemoryOrder::memory_order_release);
BAN::atomic_store(mutex->futex, 0, BAN::memory_order_release);
if (BAN::atomic_load(mutex->waiters))
futex(FUTEX_WAKE, &mutex->futex, 1, nullptr);
}
return 0; return 0;
} }
@ -941,36 +971,6 @@ int pthread_rwlock_init(pthread_rwlock_t* __restrict rwlock, const pthread_rwloc
return 0; 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) int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
{ {
unsigned expected = BAN::atomic_load(rwlock->lockers); 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) 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) 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) 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) 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]) if (env[_JMP_BUF_REGS])
pthread_sigmask(SIG_SETMASK, reinterpret_cast<sigset_t*>(&env[_JMP_BUF_REGS + 1]), nullptr); 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); (void)sigaddset(&set, sig);
return sigprocmask(SIG_UNBLOCK, &set, nullptr); 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; return wch ? length : 0;
} }
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
@ -646,31 +645,6 @@ size_t mbstowcs(wchar_t* __restrict pwcs, const char* __restrict s, size_t n)
return written; 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 wcstombs(char* __restrict s, const wchar_t* __restrict pwcs, size_t n)
{ {
size_t written = 0; size_t written = 0;

View File

@ -1,4 +1,3 @@
#include <BAN/Assert.h>
#include <BAN/Debug.h> #include <BAN/Debug.h>
#include <BAN/Math.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) 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 }; 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_sec = time % 60; time /= 60;
result->tm_min = time % 60; time /= 60; result->tm_min = time % 60; time /= 60;
result->tm_hour = time % 24; time /= 24; 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_wday = (total_days + 4) % 7;
result->tm_year = 1970; result->tm_year = 1970;
while (total_days >= 365U + is_leap_year(result->tm_year)) while (total_days >= 365U + is_leap_year(result->tm_year))

View File

@ -335,10 +335,6 @@ namespace LibGUI
if (m_window_shown_event_callback) if (m_window_shown_event_callback)
m_window_shown_event_callback(TRY_OR_BREAK(EventPacket::WindowShownEvent::deserialize(packet_data.span())).event); m_window_shown_event_callback(TRY_OR_BREAK(EventPacket::WindowShownEvent::deserialize(packet_data.span())).event);
break; 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: case PacketType::KeyEvent:
if (m_key_event_callback) if (m_key_event_callback)
m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_data.span())).event); m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_data.span())).event);

View File

@ -217,7 +217,6 @@ namespace LibGUI
CloseWindowEvent, CloseWindowEvent,
ResizeWindowEvent, ResizeWindowEvent,
WindowShownEvent, WindowShownEvent,
WindowFocusEvent,
KeyEvent, KeyEvent,
MouseButtonEvent, MouseButtonEvent,
MouseMoveEvent, MouseMoveEvent,
@ -334,14 +333,6 @@ namespace LibGUI
event_t, event event_t, event
); );
DEFINE_PACKET_EXTRA(
WindowFocusEvent,
struct event_t {
bool focused;
},
event_t, event
);
DEFINE_PACKET_EXTRA( DEFINE_PACKET_EXTRA(
KeyEvent, KeyEvent,
using event_t = LibInput::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_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_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_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; } 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_close_window_event_callback;
BAN::Function<void()> m_resize_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::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::KeyEvent::event_t)> m_key_event_callback;
BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_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; 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", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 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", "@", "£", "$", "", "=", "?", "+", "\\", "´", "`", "¨", "¸", "\b", "@", "£", "$", "",
@ -77,7 +77,7 @@ namespace LibInput
"Å", "Ä", "Ö", "Å", "Ä", "Ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 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", "@", "£", "$", "", "=", "?", "+", "\\", "´", "`", "¨", "¸", "\b", "@", "£", "$", "",
@ -96,7 +96,7 @@ namespace LibInput
"Å", "Ä", "Ö", "Å", "Ä", "Ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 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", "@", "£", "$", "", "=", "?", "+", "\\", "´", "`", "¨", "¸", "\b", "@", "£", "$", "",

View File

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

View File

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

View File

@ -190,19 +190,6 @@ struct LoadedElf
bool is_relocating; bool is_relocating;
char path[PATH_MAX]; 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]; static LoadedElf s_loaded_files[128];
@ -446,7 +433,6 @@ extern "C" int __dlclose(void* handle);
extern "C" char* __dlerror(void); extern "C" char* __dlerror(void);
extern "C" void* __dlopen(const char* file, int mode); extern "C" void* __dlopen(const char* file, int mode);
extern "C" void* __dlsym(void* __restrict handle, const char* __restrict name); 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> 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) 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(__dlerror);
CHECK_SYM(__dlopen); CHECK_SYM(__dlopen);
CHECK_SYM(__dlsym); CHECK_SYM(__dlsym);
CHECK_SYM(__dladdr);
#undef CHECK_SYM #undef CHECK_SYM
else if (symbol.st_shndx && ELF_ST_BIND(symbol.st_info) != STB_WEAK) else if (symbol.st_shndx && ELF_ST_BIND(symbol.st_info) != STB_WEAK)
symbol_address = elf.base + symbol.st_value; 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) static LoadedElf& load_elf(const char* path, int fd)
{ {
for (size_t i = 0; i < s_loaded_file_count; i++) 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; break;
} }
auto& elf = s_loaded_files[s_loaded_file_count++]; ElfNativeProgramHeader tls_header {};
elf.tls_header.p_type = PT_NULL; 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);
for (size_t i = 0; i < file_header.e_phnum; i++) 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: case PT_GNU_RELRO:
break; break;
case PT_TLS: case PT_TLS:
elf.tls_header = program_header; tls_header = program_header;
break; break;
case PT_LOAD: 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; 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); load_program_header(program_header, fd, needs_writable);
break; break;
default: 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) if (has_dynamic_pheader)
{ {
@ -1165,8 +1084,6 @@ static LoadedElf& load_elf(const char* path, int fd)
handle_dynamic(elf); handle_dynamic(elf);
} }
load_symbol_table(elf);
return elf; return elf;
} }
@ -1502,88 +1419,6 @@ void* __dlsym(void* __restrict handle, const char* __restrict name)
return nullptr; 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) static LibELF::AuxiliaryVector* find_auxv(char** envp)
{ {
if (envp == nullptr) if (envp == nullptr)

View File

@ -181,6 +181,13 @@ void Terminal::run()
perror("ioctl"); perror("ioctl");
return; 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()); 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(); auto& texture = m_window->texture();
switch (codepoint) 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': case '\a':
// TODO: bell // TODO: bell
break; break;

View File

@ -90,7 +90,7 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
window_popper.disable(); window_popper.disable();
if (packet.attributes.shown && packet.attributes.focusable) if (packet.attributes.focusable)
set_focused_window(window); set_focused_window(window);
else if (m_client_windows.size() > 1) 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]); 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()) if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error())
dwarnln("could not send window shown event: {}", ret.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) 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; BAN::RefPtr<Window> target_window;
if (m_state == State::Fullscreen) if (!event.pressed)
target_window = m_focused_window;
if (!event.pressed && !target_window)
target_window = m_mouse_button_windows[button_idx]; target_window = m_mouse_button_windows[button_idx];
for (size_t i = m_client_windows.size(); i > 0 && !target_window; i--) 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) 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)) if (event.button == LibInput::MouseButton::Left && !event.pressed && target_window->close_button_area().contains(m_cursor))
{ {
LibGUI::EventPacket::CloseWindowEvent packet; 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()); dwarnln("could not send close window event: {}", ret.error());
break; break;
} }
@ -573,9 +568,9 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
LibGUI::EventPacket::MouseButtonEvent packet; LibGUI::EventPacket::MouseButtonEvent packet;
packet.event.button = event.button; packet.event.button = event.button;
packet.event.pressed = event.pressed; packet.event.pressed = event.pressed;
packet.event.x = m_cursor.x - target_window->client_x(); packet.event.x = m_cursor.x - m_focused_window->client_x();
packet.event.y = m_cursor.y - target_window->client_y(); packet.event.y = m_cursor.y - m_focused_window->client_y();
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 mouse button event: {}", ret.error()); dwarnln("could not send mouse button event: {}", ret.error());
return; return;
@ -784,17 +779,6 @@ void WindowServer::set_focused_window(BAN::RefPtr<Window> window)
invalidate(cursor_area()); 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--) for (size_t i = m_client_windows.size(); i > 0; i--)
{ {
if (m_client_windows[i - 1] == window) if (m_client_windows[i - 1] == window)
@ -806,17 +790,6 @@ void WindowServer::set_focused_window(BAN::RefPtr<Window> window)
break; 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) 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()); 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++) for (size_t i = 0; i < m_client_windows.size(); i++)
{ {
auto window = m_client_windows[i]; auto window = m_client_windows[i];