Compare commits

..

No commits in common. "06015d006d9ed080c27f32febc9bd22ce3812e96" and "3aa20a3a3263e025fbaef93e8e5ba28f49fe4841" have entirely different histories.

48 changed files with 1489 additions and 723 deletions

View File

@ -35,8 +35,10 @@ namespace Kernel
bool has_egid(gid_t) const;
BAN::Span<const gid_t> groups() const { return m_supplementary.span(); }
BAN::ErrorOr<void> set_groups(BAN::Span<const gid_t> groups);
BAN::ErrorOr<void> initialize_supplementary_groups();
private:
BAN::ErrorOr<BAN::String> find_username() const;
private:
uid_t m_ruid, m_euid, m_suid;

View File

@ -20,6 +20,6 @@ namespace Kernel::ELF
BAN::Vector<BAN::UniqPtr<MemoryRegion>> regions;
};
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials&, PageTable&);
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode>, const Credentials&, PageTable&);
}

View File

@ -71,13 +71,13 @@ namespace Kernel
File root_file()
{
return File { root_inode(), "/"_sv };
return File(root_inode(), "/"_sv);
}
BAN::ErrorOr<File> file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials&, BAN::StringView, int);
BAN::ErrorOr<File> file_from_absolute_path(BAN::RefPtr<Inode> root_inode, const Credentials& credentials, BAN::StringView path, int flags)
BAN::ErrorOr<File> file_from_relative_path(const File& parent, const Credentials&, BAN::StringView, int);
BAN::ErrorOr<File> file_from_absolute_path(const Credentials& credentials, BAN::StringView path, int flags)
{
return file_from_relative_path(root_inode, File { root_inode, "/"_sv }, credentials, path, flags);
return file_from_relative_path(root_file(), credentials, path, flags);
}
private:

View File

@ -1,6 +1,5 @@
#pragma once
#include <BAN/HashMap.h>
#include <BAN/Endianness.h>
#include <BAN/Queue.h>
#include <kernel/Lock/Mutex.h>
@ -64,8 +63,6 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
virtual bool can_read_impl() const override;

View File

@ -38,8 +38,6 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len) override;
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
virtual bool can_read_impl() const override { return !m_packets.empty(); }
virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; }
@ -61,7 +59,7 @@ namespace Kernel
BAN::CircularQueue<PacketInfo, 32> m_packets;
size_t m_packet_total_size { 0 };
SpinLock m_packet_lock;
ThreadBlocker m_packet_thread_blocker;
ThreadBlocker m_packet_thread_blocker;
friend class BAN::RefPtr<UDPSocket>;
};

View File

@ -5,7 +5,6 @@
#include <BAN/WeakPtr.h>
#include <kernel/FS/Socket.h>
#include <kernel/FS/TmpFS/Inode.h>
#include <kernel/FS/VirtualFileSystem.h>
#include <kernel/Lock/SpinLock.h>
namespace Kernel
@ -40,8 +39,8 @@ namespace Kernel
BAN::ErrorOr<void> add_packet(BAN::ConstByteSpan);
bool is_bound() const { return !m_bound_file.canonical_path.empty(); }
bool is_bound_to_unused() const { return !m_bound_file.inode; }
bool is_bound() const { return !m_bound_path.empty(); }
bool is_bound_to_unused() const { return m_bound_path == "X"_sv; }
bool is_streaming() const;
@ -63,8 +62,8 @@ namespace Kernel
};
private:
const Socket::Type m_socket_type;
VirtualFileSystem::File m_bound_file;
const Socket::Type m_socket_type;
BAN::String m_bound_path;
BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info;

View File

@ -76,7 +76,6 @@ namespace Kernel
BAN::ErrorOr<long> sys_getcwd(char* buffer, size_t size);
BAN::ErrorOr<long> sys_chdir(const char* path);
BAN::ErrorOr<long> sys_fchdir(int fildes);
BAN::ErrorOr<long> sys_chroot(const char* path);
BAN::ErrorOr<long> sys_setuid(uid_t);
BAN::ErrorOr<long> sys_setgid(gid_t);
@ -96,9 +95,6 @@ namespace Kernel
BAN::ErrorOr<long> sys_getppid() const { return m_parent; }
BAN::ErrorOr<long> sys_getpid() const { return pid(); }
BAN::ErrorOr<long> sys_getgroups(gid_t groups[], size_t count);
BAN::ErrorOr<long> sys_setgroups(const gid_t groups[], size_t count);
BAN::ErrorOr<long> open_inode(VirtualFileSystem::File&&, int flags);
BAN::ErrorOr<void> create_file_or_dir(int fd, const char* path, mode_t mode) const;
@ -235,7 +231,6 @@ namespace Kernel
static void update_alarm_queue();
const VirtualFileSystem::File& working_directory() const { return m_working_directory; }
const VirtualFileSystem::File& root_file() const { return m_root_file; }
private:
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
@ -315,7 +310,6 @@ namespace Kernel
mutable Mutex m_process_lock;
VirtualFileSystem::File m_working_directory;
VirtualFileSystem::File m_root_file;
BAN::Vector<Thread*> m_threads;
@ -340,8 +334,6 @@ namespace Kernel
BAN::Vector<ChildExitStatus> m_child_exit_statuses;
ThreadBlocker m_child_exit_blocker;
BAN::Atomic<bool> m_is_exiting { false };
bool m_has_called_exec { false };
BAN::UniqPtr<PageTable> m_page_table;

View File

@ -243,26 +243,13 @@ namespace Kernel::ACPI::AML
BAN::ErrorOr<void> Namespace::initialize_op_regions()
{
struct FullNode
{
Scope scope;
Reference* reference;
};
BAN::Vector<FullNode> op_regions;
for (const auto& [obj_path, obj_ref] : m_named_objects)
{
if (obj_ref->node.type != Node::Type::OpRegion)
continue;
TRY(op_regions.emplace_back(
TRY(obj_path.copy()),
obj_ref
));
}
for (const auto& [obj_path, obj_ref] : op_regions)
// FIXME: if _REG adds stuff to namespace, iterators are invalidated
(void)opregion_call_reg(obj_path, obj_ref->node);
}
return {};
}

View File

@ -1,9 +1,157 @@
#include <kernel/Credentials.h>
#include <kernel/FS/VirtualFileSystem.h>
#include <ctype.h>
#include <fcntl.h>
namespace Kernel
{
static id_t parse_id(BAN::StringView line)
{
id_t id = 0;
for (char c : line)
{
if (!isdigit(c))
return -1;
id = (id * 10) + (c - '0');
}
return id;
};
BAN::ErrorOr<BAN::String> Credentials::find_username() const
{
auto inode = TRY(VirtualFileSystem::get().file_from_absolute_path(*this, "/etc/passwd"_sv, O_RDONLY)).inode;
BAN::String line;
off_t offset = 0;
uint8_t buffer[128];
while (offset < inode->size())
{
size_t nread = TRY(inode->read(offset, { buffer, sizeof(buffer) }));
bool line_done = false;
for (size_t i = 0; i < nread; i++)
{
if (buffer[i] == '\n')
{
TRY(line.append({ (const char*)buffer, i }));
line_done = true;
offset += i + 1;
break;
}
}
if (!line_done)
{
offset += nread;
TRY(line.append({ (const char*)buffer, nread }));
continue;
}
auto parts = TRY(line.sv().split(':', true));
if (parts.size() == 7 && m_euid == parse_id(parts[2]))
{
BAN::String result;
TRY(result.append(parts[0]));
return result;
}
line.clear();
}
auto parts = TRY(line.sv().split(':', true));
if (parts.size() == 7 && m_euid == parse_id(parts[2]))
{
BAN::String result;
TRY(result.append(parts[0]));
return result;
}
return BAN::Error::from_errno(EINVAL);
}
BAN::ErrorOr<void> Credentials::initialize_supplementary_groups()
{
m_supplementary.clear();
auto username = TRY(find_username());
auto file_or_error = VirtualFileSystem::get().file_from_absolute_path(*this, "/etc/group", O_RDONLY);
if (file_or_error.is_error())
{
if (file_or_error.error().get_error_code() == ENOENT)
return {};
return file_or_error.error();
}
auto inode = file_or_error.value().inode;
BAN::String line;
off_t offset = 0;
uint8_t buffer[128];
while (offset < inode->size())
{
size_t nread = TRY(inode->read(offset, { buffer, sizeof(buffer) }));
bool line_done = false;
for (size_t i = 0; i < nread; i++)
{
if (buffer[i] == '\n')
{
TRY(line.append({ (const char*)buffer, i }));
line_done = true;
offset += i + 1;
break;
}
}
if (!line_done)
{
offset += nread;
TRY(line.append({ (const char*)buffer, nread }));
continue;
}
auto parts = TRY(line.sv().split(':', true));
if (parts.size() != 4)
{
line.clear();
continue;
}
auto users = TRY(parts[3].split(','));
for (auto user : users)
{
if (user != username)
continue;
if (gid_t gid = parse_id(parts[2]); gid != -1)
{
TRY(m_supplementary.push_back(gid));
break;
}
}
line.clear();
}
auto parts = TRY(line.sv().split(':', true));
if (parts.size() == 4)
{
auto users = TRY(parts[3].split(','));
for (auto user : users)
{
if (user != username)
continue;
if (gid_t gid = parse_id(parts[2]); gid != -1)
{
TRY(m_supplementary.push_back(gid));
break;
}
}
}
return {};
}
bool Credentials::has_egid(gid_t gid) const
{
if (m_egid == gid)
@ -14,13 +162,4 @@ namespace Kernel
return false;
}
BAN::ErrorOr<void> Credentials::set_groups(BAN::Span<const gid_t> groups)
{
m_supplementary.clear();
TRY(m_supplementary.resize(groups.size()));
for (size_t i = 0; i < groups.size(); i++)
m_supplementary[i] = groups[i];
return {};
}
}

View File

@ -104,7 +104,7 @@ namespace Kernel::ELF
return BAN::move(program_headers);
}
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table)
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table)
{
auto file_header = TRY(read_and_validate_file_header(inode));
auto program_headers = TRY(read_program_headers(inode, file_header));
@ -143,7 +143,7 @@ namespace Kernel::ELF
if (!interpreter.empty())
{
auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(root, credentials, interpreter, O_EXEC)).inode;
auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(credentials, interpreter, O_EXEC)).inode;
auto interpreter_file_header = TRY(read_and_validate_file_header(interpreter_inode));
auto interpreter_program_headers = TRY(read_program_headers(interpreter_inode, interpreter_file_header));

View File

@ -186,8 +186,7 @@ namespace Kernel
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::StringView block_device_path, BAN::StringView target)
{
// TODO: allow custom root
auto block_device_file = TRY(file_from_absolute_path(root_inode(), credentials, block_device_path, true));
auto block_device_file = TRY(file_from_absolute_path(credentials, block_device_path, true));
if (!block_device_file.inode->is_device())
return BAN::Error::from_errno(ENOTBLK);
@ -201,8 +200,7 @@ namespace Kernel
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::RefPtr<FileSystem> file_system, BAN::StringView path)
{
// TODO: allow custom root
auto file = TRY(file_from_absolute_path(root_inode(), credentials, path, true));
auto file = TRY(file_from_absolute_path(credentials, path, true));
if (!file.inode->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);
@ -229,7 +227,7 @@ namespace Kernel
return nullptr;
}
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials& credentials, BAN::StringView path, int flags)
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(const File& parent, const Credentials& credentials, BAN::StringView path, int flags)
{
LockGuard _(m_mutex);
@ -272,16 +270,13 @@ namespace Kernel
// resolve file name
{
if (!(inode == root_inode && path_part == ".."_sv))
{
auto parent_inode = inode;
if (path_part == ".."_sv)
if (auto* mount_point = mount_from_root_inode(inode))
parent_inode = mount_point->host.inode;
if (!parent_inode->can_access(credentials, O_SEARCH))
return BAN::Error::from_errno(EACCES);
inode = TRY(parent_inode->find_inode(path_part));
}
auto parent_inode = inode;
if (path_part == ".."_sv)
if (auto* mount_point = mount_from_root_inode(inode))
parent_inode = mount_point->host.inode;
if (!parent_inode->can_access(credentials, O_SEARCH))
return BAN::Error::from_errno(EACCES);
inode = TRY(parent_inode->find_inode(path_part));
if (path_part == ".."_sv)
{
@ -315,7 +310,7 @@ namespace Kernel
if (link_target.front() == '/')
{
inode = root_inode;
inode = root_inode();
canonical_path.clear();
}
else

View File

@ -8,7 +8,6 @@
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
namespace Kernel
{
@ -256,18 +255,6 @@ namespace Kernel
return {};
}
BAN::ErrorOr<long> TCPSocket::ioctl_impl(int request, void* argument)
{
switch (request)
{
case FIONREAD:
*static_cast<int*>(argument) = m_recv_window.data_size;
return 0;
}
return NetworkSocket::ioctl_impl(request, argument);
}
bool TCPSocket::can_read_impl() const
{
if (m_has_connected && !m_has_sent_zero && m_state != State::Established && m_state != State::Listen)

View File

@ -4,7 +4,6 @@
#include <kernel/Thread.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
namespace Kernel
{
@ -139,22 +138,4 @@ namespace Kernel
return TRY(m_network_layer.sendto(*this, message, address, address_len));
}
BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument)
{
switch (request)
{
case FIONREAD:
{
SpinLockGuard guard(m_packet_lock);
if (m_packets.empty())
*static_cast<int*>(argument) = 0;
else
*static_cast<int*>(argument) = m_packets.front().packet_size;
return 0;
}
}
return NetworkSocket::ioctl_impl(request, argument);
}
}

View File

@ -13,16 +13,8 @@
namespace Kernel
{
struct UnixSocketHash
{
BAN::hash_t operator()(const BAN::RefPtr<Inode>& socket)
{
return BAN::hash<const Inode*>{}(socket.ptr());
}
};
static BAN::HashMap<BAN::RefPtr<Inode>, BAN::WeakPtr<UnixDomainSocket>, UnixSocketHash> s_bound_sockets;
static SpinLock s_bound_socket_lock;
static BAN::HashMap<BAN::String, BAN::WeakPtr<UnixDomainSocket>> s_bound_sockets;
static SpinLock s_bound_socket_lock;
static constexpr size_t s_packet_buffer_size = 10 * PAGE_SIZE;
@ -65,7 +57,9 @@ namespace Kernel
if (is_bound() && !is_bound_to_unused())
{
SpinLockGuard _(s_bound_socket_lock);
s_bound_sockets.remove(m_bound_file.inode);
auto it = s_bound_sockets.find(m_bound_path);
if (it != s_bound_sockets.end())
s_bound_sockets.remove(it);
}
if (m_info.has<ConnectionInfo>())
{
@ -123,22 +117,17 @@ namespace Kernel
return_inode = reinterpret_cast<UnixDomainSocket*>(return_inode_tmp.ptr());
}
TRY(return_inode->m_bound_file.canonical_path.push_back('X'));
TRY(return_inode->m_bound_path.push_back('X'));
return_inode->m_info.get<ConnectionInfo>().connection = TRY(pending->get_weak_ptr());
pending->m_info.get<ConnectionInfo>().connection = TRY(return_inode->get_weak_ptr());
pending->m_info.get<ConnectionInfo>().connection_done = true;
if (address && address_len && !is_bound_to_unused())
{
sockaddr_un sa_un {
.sun_family = AF_UNIX,
.sun_path {},
};
strcpy(sa_un.sun_path, pending->m_bound_file.canonical_path.data());
const size_t to_copy = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr_un));
memcpy(address, &sa_un, to_copy);
*address_len = to_copy;
size_t copy_len = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr) + m_bound_path.size() + 1);
auto& sockaddr_un = *reinterpret_cast<struct sockaddr_un*>(address);
sockaddr_un.sun_family = AF_UNIX;
strncpy(sockaddr_un.sun_path, pending->m_bound_path.data(), copy_len);
}
return TRY(Process::current().open_inode(VirtualFileSystem::File(return_inode, "<unix socket>"_sv), O_RDWR | flags));
@ -152,11 +141,10 @@ namespace Kernel
if (sockaddr_un.sun_family != AF_UNIX)
return BAN::Error::from_errno(EAFNOSUPPORT);
if (!is_bound())
TRY(m_bound_file.canonical_path.push_back('X'));
TRY(m_bound_path.push_back('X'));
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(
Process::current().root_file().inode,
Process::current().credentials(),
absolute_path,
O_RDWR
@ -166,7 +154,7 @@ namespace Kernel
{
SpinLockGuard _(s_bound_socket_lock);
auto it = s_bound_sockets.find(file.inode);
auto it = s_bound_sockets.find(file.canonical_path);
if (it == s_bound_sockets.end())
return BAN::Error::from_errno(ECONNREFUSED);
target = it->value.lock();
@ -248,7 +236,7 @@ namespace Kernel
// FIXME: This feels sketchy
auto parent_file = bind_path.front() == '/'
? TRY(Process::current().root_file().clone())
? VirtualFileSystem::get().root_file()
: TRY(Process::current().working_directory().clone());
if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, bind_path.data(), 0755 | S_IFSOCK); ret.is_error())
{
@ -257,7 +245,6 @@ namespace Kernel
return ret.release_error();
}
auto file = TRY(VirtualFileSystem::get().file_from_relative_path(
Process::current().root_file().inode,
parent_file,
Process::current().credentials(),
bind_path,
@ -265,10 +252,10 @@ namespace Kernel
));
SpinLockGuard _(s_bound_socket_lock);
if (s_bound_sockets.contains(file.inode))
if (s_bound_sockets.contains(file.canonical_path))
return BAN::Error::from_errno(EADDRINUSE);
TRY(s_bound_sockets.emplace(file.inode, TRY(get_weak_ptr())));
m_bound_file = BAN::move(file);
TRY(s_bound_sockets.emplace(file.canonical_path, TRY(get_weak_ptr())));
m_bound_path = BAN::move(file.canonical_path);
return {};
}
@ -367,21 +354,14 @@ namespace Kernel
}
else
{
BAN::RefPtr<Inode> target_inode;
BAN::String canonical_path;
if (!address)
{
auto& connectionless_info = m_info.get<ConnectionlessInfo>();
if (connectionless_info.peer_address.empty())
return BAN::Error::from_errno(EDESTADDRREQ);
auto absolute_path = TRY(Process::current().absolute_path_of(connectionless_info.peer_address));
target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(
Process::current().root_file().inode,
Process::current().credentials(),
absolute_path,
O_RDWR
)).inode;
TRY(canonical_path.append(connectionless_info.peer_address));
}
else
{
@ -392,16 +372,17 @@ namespace Kernel
return BAN::Error::from_errno(EAFNOSUPPORT);
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(
Process::current().root_file().inode,
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(
Process::current().credentials(),
absolute_path,
O_WRONLY
)).inode;
));
canonical_path = BAN::move(file.canonical_path);
}
SpinLockGuard _(s_bound_socket_lock);
auto it = s_bound_sockets.find(target_inode);
auto it = s_bound_sockets.find(canonical_path);
if (it == s_bound_sockets.end())
return BAN::Error::from_errno(EDESTADDRREQ);
auto target = it->value.lock();
@ -468,11 +449,20 @@ namespace Kernel
if (!connection)
return BAN::Error::from_errno(ENOTCONN);
sockaddr_un sa_un {
.sun_family = AF_UNIX,
.sun_path = {},
};
strcpy(sa_un.sun_path, connection->m_bound_file.canonical_path.data());
sockaddr_un sa_un;
sa_un.sun_family = AF_UNIX;
sa_un.sun_path[0] = 0;
{
SpinLockGuard _(s_bound_socket_lock);
for (auto& [path, socket] : s_bound_sockets)
{
if (socket.lock() != connection)
continue;
strcpy(sa_un.sun_path, path.data());
break;
}
}
const size_t to_copy = BAN::Math::min<socklen_t>(sizeof(sockaddr_un), *address_len);
memcpy(address, &sa_un, to_copy);

View File

@ -77,7 +77,7 @@ namespace Kernel
BAN::ErrorOr<int> OpenFileDescriptorSet::open(BAN::StringView absolute_path, int flags)
{
return open(TRY(VirtualFileSystem::get().file_from_absolute_path(Process::current().root_file().inode, m_credentials, absolute_path, flags)), flags);
return open(TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)), flags);
}
struct SocketInfo

View File

@ -101,10 +101,9 @@ namespace Kernel
BAN::ErrorOr<Process*> Process::create_userspace(const Credentials& credentials, BAN::StringView path, BAN::Span<BAN::StringView> arguments)
{
auto* process = create_process(credentials, 0);
TRY(process->m_credentials.initialize_supplementary_groups());
process->m_working_directory = VirtualFileSystem::get().root_file();
process->m_root_file = VirtualFileSystem::get().root_file();
process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));
TRY(process->m_cmdline.emplace_back());
@ -120,7 +119,7 @@ namespace Kernel
auto executable_file = TRY(process->find_file(AT_FDCWD, path.data(), O_EXEC));
auto executable_inode = executable_file.inode;
auto executable = TRY(ELF::load_from_inode(process->m_root_file.inode, executable_inode, process->m_credentials, process->page_table()));
auto executable = TRY(ELF::load_from_inode(executable_inode, process->m_credentials, process->page_table()));
process->m_mapped_regions = BAN::move(executable.regions);
if (executable_inode->mode().mode & +Inode::Mode::ISUID)
@ -258,16 +257,6 @@ namespace Kernel
void Process::exit(int status, int signal)
{
bool expected = false;
if (!m_is_exiting.compare_exchange(expected, true))
{
Thread::current().on_exit();
ASSERT_NOT_REACHED();
}
const auto state = Processor::get_interrupt_state();
Processor::set_interrupt_state(InterruptState::Enabled);
if (m_parent)
{
Process* parent_process = nullptr;
@ -305,18 +294,13 @@ namespace Kernel
}
}
for (size_t i = 0; i < m_threads.size(); i++)
{
LockGuard _(m_process_lock);
for (auto* thread : m_threads)
if (thread != &Thread::current())
ASSERT(thread->add_signal(SIGKILL));
if (m_threads[i] == &Thread::current())
continue;
m_threads[i]->add_signal(SIGKILL);
}
while (m_threads.size() > 1)
Processor::yield();
Processor::set_interrupt_state(state);
Thread::current().on_exit();
ASSERT_NOT_REACHED();
@ -458,7 +442,7 @@ namespace Kernel
auto parent_file = TRY(find_relative_parent(fd, path));
auto file = path
? TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent_file, m_credentials, path, flags))
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags))
: BAN::move(parent_file);
return file;
@ -482,7 +466,7 @@ namespace Kernel
if (auto index = path_sv.rfind('/'); index.has_value())
{
parent = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, m_credentials, path_sv.substring(0, index.value()), flags));
parent = TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, m_credentials, path_sv.substring(0, index.value()), flags));
file_name = path_sv.substring(index.value() + 1);
}
else
@ -512,7 +496,7 @@ namespace Kernel
ASSERT(m_process_lock.is_locked());
if (path && path[0] == '/')
return TRY(m_root_file.clone());
return VirtualFileSystem::get().root_file();
if (fd == AT_FDCWD)
return TRY(m_working_directory.clone());
@ -523,6 +507,7 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_exit(int status)
{
ASSERT(this == &Process::current());
LockGuard _(m_process_lock);
exit(status, 0);
ASSERT_NOT_REACHED();
}
@ -584,7 +569,6 @@ namespace Kernel
}
auto working_directory = TRY(m_working_directory.clone());
auto root_file = TRY(m_root_file.clone());
BAN::Vector<BAN::String> cmdline;
TRY(cmdline.resize(m_cmdline.size()));
@ -607,7 +591,6 @@ namespace Kernel
Process* forked = create_process(m_credentials, m_pid, m_sid, m_pgrp);
forked->m_controlling_terminal = m_controlling_terminal;
forked->m_working_directory = BAN::move(working_directory);
forked->m_root_file = BAN::move(root_file);
forked->m_cmdline = BAN::move(cmdline);
forked->m_environ = BAN::move(environ);
forked->m_page_table = BAN::move(page_table);
@ -660,7 +643,7 @@ namespace Kernel
auto executable_file = TRY(find_file(AT_FDCWD, path, O_EXEC));
auto executable_inode = executable_file.inode;
auto executable = TRY(ELF::load_from_inode(m_root_file.inode, executable_inode, m_credentials, *new_page_table));
auto executable = TRY(ELF::load_from_inode(executable_inode, m_credentials, *new_page_table));
auto new_mapped_regions = BAN::move(executable.regions);
BAN::Vector<LibELF::AuxiliaryVector> auxiliary_vector;
@ -1048,7 +1031,7 @@ namespace Kernel
TRY(validate_string_access(path));
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_RDONLY));
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags);
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags);
VirtualFileSystem::File file;
if (file_or_error.is_error())
@ -1058,7 +1041,7 @@ namespace Kernel
// FIXME: There is a race condition between next two lines
TRY(parent.inode->create_file(file_name, (mode & 0777) | Inode::Mode::IFREG, m_credentials.euid(), m_credentials.egid()));
file = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags & ~O_RDWR));
file = TRY(VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags & ~O_RDWR));
}
else
{
@ -1139,7 +1122,7 @@ namespace Kernel
credentials.set_egid(credentials.rgid());
auto relative_parent = TRY(find_relative_parent(AT_FDCWD, path));
TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, credentials, path, flags));
TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, credentials, path, flags));
return 0;
}
@ -1262,7 +1245,6 @@ namespace Kernel
flag = O_NOFOLLOW;
LockGuard _(m_process_lock);
TRY(validate_string_access(path));
auto inode = TRY(find_file(fd, path, flag)).inode;
@ -1285,7 +1267,6 @@ namespace Kernel
flag = O_NOFOLLOW;
LockGuard _(m_process_lock);
TRY(validate_string_access(path));
auto inode = TRY(find_file(fd, path, flag)).inode;
@ -2101,25 +2082,22 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_chdir(const char* path)
{
LockGuard _(m_process_lock);
TRY(validate_string_access(path));
m_working_directory = TRY(find_file(AT_FDCWD, path, O_SEARCH));
auto file = TRY(find_file(AT_FDCWD, path, O_SEARCH));
m_working_directory = BAN::move(file);
return 0;
}
BAN::ErrorOr<long> Process::sys_fchdir(int fildes)
{
LockGuard _(m_process_lock);
m_working_directory = TRY(m_open_file_descriptors.file_of(fildes));
return 0;
}
BAN::ErrorOr<long> Process::sys_chroot(const char* path)
{
LockGuard _(m_process_lock);
TRY(validate_string_access(path));
if (!m_credentials.is_superuser())
return BAN::Error::from_errno(EACCES);
m_root_file = TRY(find_file(AT_FDCWD, path, O_SEARCH));
auto file = TRY(m_open_file_descriptors.file_of(fildes));
m_working_directory = BAN::move(file);
return 0;
}
@ -2927,6 +2905,7 @@ namespace Kernel
m_credentials.set_euid(uid);
m_credentials.set_ruid(uid);
m_credentials.set_suid(uid);
TRY(m_credentials.initialize_supplementary_groups());
return 0;
}
@ -2935,6 +2914,7 @@ namespace Kernel
if (uid == m_credentials.ruid() || uid == m_credentials.suid())
{
m_credentials.set_euid(uid);
TRY(m_credentials.initialize_supplementary_groups());
return 0;
}
@ -2995,6 +2975,7 @@ namespace Kernel
if (uid == m_credentials.ruid() || uid == m_credentials.suid() || m_credentials.is_superuser())
{
m_credentials.set_euid(uid);
TRY(m_credentials.initialize_supplementary_groups());
return 0;
}
@ -3061,6 +3042,8 @@ namespace Kernel
if (euid != -1)
m_credentials.set_euid(euid);
TRY(m_credentials.initialize_supplementary_groups());
return 0;
}
@ -3208,28 +3191,6 @@ namespace Kernel
return BAN::Error::from_errno(error);
}
BAN::ErrorOr<long> Process::sys_getgroups(gid_t groups[], size_t count)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(groups, count * sizeof(gid_t), true));
auto current = m_credentials.groups();
if (current.size() > count)
return BAN::Error::from_errno(EINVAL);
for (size_t i = 0; i < current.size(); i++)
groups[i] = current[i];
return current.size();
}
BAN::ErrorOr<long> Process::sys_setgroups(const gid_t groups[], size_t count)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(groups, count * sizeof(gid_t), true));
if (!m_credentials.is_superuser())
return BAN::Error::from_errno(EPERM);
TRY(m_credentials.set_groups({ groups, count }));
return 0;
}
BAN::ErrorOr<BAN::String> Process::absolute_path_of(BAN::StringView path) const
{
LockGuard _(m_process_lock);

View File

@ -121,8 +121,8 @@ namespace Kernel
void TTY::keyboard_task(void*)
{
BAN::RefPtr<Inode> keyboard_inode;
if (auto ret = DevFileSystem::get().root_inode()->find_inode("keyboard"_sv); !ret.is_error())
keyboard_inode = ret.release_value();
if (auto ret = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY); !ret.is_error())
keyboard_inode = ret.value().inode;
else
{
dprintln("could not open keyboard device: {}", ret.error());

View File

@ -40,9 +40,10 @@ namespace Kernel
switch (m_speed_class)
{
case USB::SpeedClass::LowSpeed:
m_endpoints[0].max_packet_size = 8;
break;
case USB::SpeedClass::FullSpeed:
m_endpoints[0].max_packet_size = 8;
is_ls_or_fs_device_on_hs_hub = m_info.parent_hub && (m_info.parent_hub->speed_class() == USB::SpeedClass::HighSpeed);
break;
case USB::SpeedClass::HighSpeed:
m_endpoints[0].max_packet_size = 64;
break;
@ -52,16 +53,6 @@ namespace Kernel
default: ASSERT_NOT_REACHED();
}
switch (m_speed_class)
{
case USB::SpeedClass::LowSpeed:
case USB::SpeedClass::FullSpeed:
is_ls_or_fs_device_on_hs_hub = m_info.parent_hub && (m_info.parent_hub->speed_class() == USB::SpeedClass::HighSpeed);
break;
default:
break;
}
m_input_context = TRY(DMARegion::create(33 * context_size));
memset(reinterpret_cast<void*>(m_input_context->vaddr()), 0, m_input_context->size());

View File

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

View File

@ -3,7 +3,7 @@
NAME='binutils'
VERSION='2.44'
DOWNLOAD_URL="https://ftp.gnu.org/gnu/binutils/binutils-$VERSION.tar.gz#0cdd76777a0dfd3dd3a63f215f030208ddb91c2361d2bcc02acec0f1c16b6a2e"
DEPENDENCIES=('zlib' 'zstd')
DEPENDENCIES=('zlib')
MAKE_INSTALL_TARGETS=('install-strip')
CONFIGURE_OPTIONS=(
"--target=$BANAN_TOOLCHAIN_TRIPLE"
@ -16,13 +16,6 @@ CONFIGURE_OPTIONS=(
'--disable-werror'
)
pre_configure() {
unset PKG_CONFIG_DIR
unset PKG_CONFIG_SYSROOT_DIR
unset PKG_CONFIG_LIBDIR
unset PKG_CONFIG_PATH
}
post_install() {
# remove libtool files
rm -f $BANAN_SYSROOT/usr/lib/libbfd.la

View File

@ -2,22 +2,20 @@
NAME='doom'
VERSION='git'
DOWNLOAD_URL="https://github.com/ozkl/doomgeneric.git#5041246e859052e2e258ca6edb4e1e9bbd98fcf5"
DEPENDENCIES=('SDL2' 'SDL2_mixer' 'timidity')
DOWNLOAD_URL="https://github.com/ozkl/doomgeneric.git#613f870b6fa83ede448a247de5a2571092fa729d"
configure() {
rm -rf doomgeneric/build
make --directory doomgeneric clean
}
build() {
if [ ! -f ../doom1.wad ]; then
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad -O ../doom1.wad || exit 1
fi
CFLAGS='-std=c11' make --directory doomgeneric --file Makefile.sdl CC="$CC" SDL_PATH="$BANAN_SYSROOT/usr/bin/" || exit 1
make --directory doomgeneric --file Makefile.banan_os -j$(nproc) || exit 1
}
install() {
cp doomgeneric/doomgeneric "${BANAN_SYSROOT}/bin/doom" || exit 1
cp doomgeneric/build/doom "${BANAN_SYSROOT}/bin/" || exit 1
cp ../doom1.wad "$BANAN_SYSROOT/home/user/" || exit 1
}

View File

@ -0,0 +1,224 @@
From 0f37d9f2df042eb8ba021dd91b898c1f07d86b58 Mon Sep 17 00:00:00 2001
From: Bananymous <bananymousosq@gmail.com>
Date: Fri, 18 Oct 2024 03:44:10 +0300
Subject: [PATCH] Add support for banan-os
---
doomgeneric/Makefile.banan_os | 57 +++++++++++
doomgeneric/doomgeneric_banan_os.cpp | 138 +++++++++++++++++++++++++++
2 files changed, 200 insertions(+)
create mode 100644 doomgeneric/Makefile.banan_os
create mode 100644 doomgeneric/doomgeneric_banan_os.cpp
diff --git a/doomgeneric/Makefile.banan_os b/doomgeneric/Makefile.banan_os
new file mode 100644
index 0000000..0878148
--- /dev/null
+++ b/doomgeneric/Makefile.banan_os
@@ -0,0 +1,57 @@
+################################################################
+#
+# $Id:$
+#
+# $Log:$
+#
+
+ifeq ($(V),1)
+ VB=''
+else
+ VB=@
+endif
+
+CC=$(BANAN_ARCH)-pc-banan_os-gcc
+CXX=$(BANAN_ARCH)-pc-banan_os-g++
+CFLAGS+=-O3 -std=c11 -Wall -DNORMALUNIX -DLINUX -DSNDSERV -D_DEFAULT_SOURCE
+CXXFLAGS+=$(CFLAGS) --std=c++20
+LDFLAGS+=
+LIBS+=-lgui -linput -lstdc++
+
+# subdirectory for objects
+OBJDIR=build
+OUTPUT=$(OBJDIR)/doom
+
+SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_banan_os.o
+OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM))
+
+all: $(OUTPUT)
+
+clean:
+ rm -rf $(OBJDIR)
+ rm -f $(OUTPUT)
+ rm -f $(OUTPUT).gdb
+ rm -f $(OUTPUT).map
+
+$(OUTPUT): $(OBJS)
+ @echo [Linking $@]
+ $(VB)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) \
+ -o $(OUTPUT) $(LIBS) -Wl,-Map,$(OUTPUT).map
+ @echo [Size]
+ -$(CROSS_COMPILE)size $(OUTPUT)
+
+$(OBJS): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+$(OBJDIR)/%.o: %.c
+ @echo [Compiling $<]
+ $(VB)$(CC) $(CFLAGS) -c $< -o $@
+
+$(OBJDIR)/%.o: %.cpp
+ @echo [Compiling $<]
+ $(VB)$(CXX) $(CXXFLAGS) -c $< -o $@
+
+print:
+ @echo OBJS: $(OBJS)
\ No newline at end of file
diff --git a/doomgeneric/doomgeneric_banan_os.cpp b/doomgeneric/doomgeneric_banan_os.cpp
new file mode 100644
index 0000000..9161771
--- /dev/null
+++ b/doomgeneric/doomgeneric_banan_os.cpp
@@ -0,0 +1,139 @@
+extern "C"
+{
+#include "doomgeneric.h"
+#include "doomkeys.h"
+}
+
+#include <assert.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/banan-os.h>
+#include <sys/framebuffer.h>
+#include <sys/mman.h>
+#include <time.h>
+
+#include <LibGUI/Window.h>
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+static BAN::UniqPtr<LibGUI::Window> s_window;
+
+static constexpr size_t s_key_queue_size = 16;
+static unsigned short s_key_queue[s_key_queue_size];
+static size_t s_key_read_index = 0;
+static size_t s_key_write_index = 0;
+
+extern "C"
+{
+
+void DG_Init()
+{
+ s_window = MUST(LibGUI::Window::create(DOOMGENERIC_RESX, DOOMGENERIC_RESY, "DOOM"_sv));
+ s_window->set_key_event_callback(
+ [](LibGUI::EventPacket::KeyEvent::event_t event)
+ {
+ unsigned short doom_key = 0;
+ switch (event.key)
+ {
+ case LibInput::Key::Enter:
+ doom_key = KEY_ENTER;
+ break;
+ case LibInput::Key::Escape:
+ doom_key = KEY_ESCAPE;
+ break;
+ case LibInput::Key::ArrowLeft:
+ doom_key = KEY_LEFTARROW;
+ break;
+ case LibInput::Key::ArrowUp:
+ doom_key = KEY_UPARROW;
+ break;
+ case LibInput::Key::ArrowRight:
+ doom_key = KEY_RIGHTARROW;
+ break;
+ case LibInput::Key::ArrowDown:
+ doom_key = KEY_DOWNARROW;
+ break;
+ case LibInput::Key::LeftCtrl:
+ case LibInput::Key::RightCtrl:
+ doom_key = KEY_FIRE;
+ break;
+ case LibInput::Key::Space:
+ doom_key = KEY_USE;
+ break;
+ case LibInput::Key::RightShift:
+ doom_key = KEY_RSHIFT;
+ break;
+ default:
+ {
+ const char* utf8 = LibInput::key_to_utf8(event.key, event.modifier);
+ if (utf8 && strlen(utf8) == 1 && isalpha(*utf8))
+ doom_key = tolower(*utf8);
+ }
+ }
+
+ if (doom_key == 0)
+ return;
+
+ s_key_queue[s_key_write_index] = doom_key | (int)event.pressed() << 8;
+ s_key_write_index = (s_key_write_index + 1) % s_key_queue_size;
+ }
+ );
+}
+
+void DG_DrawFrame()
+{
+ auto& texture = s_window->texture();
+ for (size_t y = 0; y < DOOMGENERIC_RESY; y++)
+ for (size_t x = 0; x < DOOMGENERIC_RESX; x++)
+ texture.set_pixel(x, y, 0xFF000000 | DG_ScreenBuffer[y * DOOMGENERIC_RESX + x]);
+ s_window->invalidate();
+ s_window->poll_events();
+}
+
+void DG_SleepMs(uint32_t ms)
+{
+ struct timespec ts;
+ ts.tv_sec = ms / 1000;
+ ts.tv_nsec = (ms % 1000) * 1000000;
+ nanosleep(&ts, NULL);
+}
+
+uint32_t DG_GetTicksMs()
+{
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
+}
+
+int DG_GetKey(int* pressed, unsigned char* doomKey)
+{
+ if (s_key_read_index == s_key_write_index)
+ return 0;
+
+ unsigned short key_data = s_key_queue[s_key_read_index];
+ s_key_read_index = (s_key_read_index + 1) % s_key_queue_size;
+
+ *pressed = key_data >> 8;
+ *doomKey = key_data & 0xFF;
+
+ return 1;
+}
+
+void DG_SetWindowTitle(const char* title)
+{
+ (void)title;
+}
+
+int main(int argc, char** argv)
+{
+ doomgeneric_Create(argc, argv);
+
+ for (;;)
+ doomgeneric_Tick();
+
+ return 0;
+}
+
+}
--
2.45.2

View File

@ -1,27 +0,0 @@
From a4e6b807885a7cb4a507b4e114743aa0004376ad Mon Sep 17 00:00:00 2001
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
Date: Sun, 10 Aug 2025 01:57:38 +0300
Subject: [PATCH] add support for custom SDL path
---
doomgeneric/Makefile.sdl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doomgeneric/Makefile.sdl b/doomgeneric/Makefile.sdl
index 38402da..8c2f84e 100644
--- a/doomgeneric/Makefile.sdl
+++ b/doomgeneric/Makefile.sdl
@@ -12,8 +12,8 @@ else
endif
-SDL_CFLAGS = `sdl2-config --cflags`
-SDL_LIBS = `sdl2-config --cflags --libs` -lSDL2_mixer
+SDL_CFLAGS = `$(SDL_PATH)sdl2-config --cflags`
+SDL_LIBS = `$(SDL_PATH)sdl2-config --cflags --libs` -lSDL2_mixer
CC=clang # gcc or g++
--
2.50.1

View File

@ -0,0 +1,34 @@
From c28fd460c15a3d4cc5aac35d1ea5744f1722cab4 Mon Sep 17 00:00:00 2001
From: Bananymous <bananymousosq@gmail.com>
Date: Wed, 3 Apr 2024 21:39:22 +0300
Subject: [PATCH] Call exit() on I_Quit() and I_Error()
---
doomgeneric/i_system.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/doomgeneric/i_system.c b/doomgeneric/i_system.c
index 5d00091..bfb204f 100644
--- a/doomgeneric/i_system.c
+++ b/doomgeneric/i_system.c
@@ -257,6 +257,8 @@ void I_Quit (void)
entry = entry->next;
}
+ exit(0);
+
#if ORIGCODE
SDL_Quit();
@@ -403,6 +405,8 @@ void I_Error (char *error, ...)
entry = entry->next;
}
+ exit(1);
+
exit_gui_popup = !M_ParmExists("-nogui");
// Pop up a GUI dialog box to show the error message, if the
--
2.47.1

View File

@ -1,25 +0,0 @@
From fd5308b45021ca18e7703d810e2e2ba86c174669 Mon Sep 17 00:00:00 2001
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
Date: Sun, 10 Aug 2025 01:56:26 +0300
Subject: [PATCH] set timidity config path
---
doomgeneric/i_sdlmusic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doomgeneric/i_sdlmusic.c b/doomgeneric/i_sdlmusic.c
index f56392f..80b9021 100644
--- a/doomgeneric/i_sdlmusic.c
+++ b/doomgeneric/i_sdlmusic.c
@@ -110,7 +110,7 @@ static boolean sdl_was_initialized = false;
static boolean musicpaused = false;
static int current_music_volume;
-char *timidity_cfg_path = "";
+char *timidity_cfg_path = "/etc/timidity.cfg";
static char *temp_timidity_cfg = NULL;
--
2.50.1

View File

@ -0,0 +1,48 @@
From 70c235938f0b64c4f08a478d3107e5254ad904c6 Mon Sep 17 00:00:00 2001
From: Bananymous <bananymousosq@gmail.com>
Date: Wed, 27 Nov 2024 13:28:42 +0200
Subject: [PATCH] Remove unnecessary copy from framebuffer
---
doomgeneric/doomgeneric.c | 2 --
doomgeneric/doomgeneric_banan_os.cpp | 6 +++---
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/doomgeneric/doomgeneric.c b/doomgeneric/doomgeneric.c
index 782a7e7..f4eb63e 100644
--- a/doomgeneric/doomgeneric.c
+++ b/doomgeneric/doomgeneric.c
@@ -18,8 +18,6 @@ void doomgeneric_Create(int argc, char **argv)
M_FindResponseFile();
- DG_ScreenBuffer = malloc(DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4);
-
DG_Init();
D_DoomMain ();
diff --git a/doomgeneric/doomgeneric_banan_os.cpp b/doomgeneric/doomgeneric_banan_os.cpp
index d00c30d..9d13b43 100644
--- a/doomgeneric/doomgeneric_banan_os.cpp
+++ b/doomgeneric/doomgeneric_banan_os.cpp
@@ -80,14 +80,13 @@ void DG_Init()
s_key_write_index = (s_key_write_index + 1) % s_key_queue_size;
}
);
+
+ ASSERT(DG_ScreenBuffer == nullptr);
+ DG_ScreenBuffer = s_window->texture().pixels().data();
}
void DG_DrawFrame()
{
- auto& texture = s_window->texture();
- for (size_t y = 0; y < DOOMGENERIC_RESY; y++)
- for (size_t x = 0; x < DOOMGENERIC_RESX; x++)
- texture.set_pixel(x, y, 0xFF000000 | DG_ScreenBuffer[y * DOOMGENERIC_RESX + x]);
s_window->invalidate();
s_window->poll_events();
}
--
2.47.1

View File

@ -2,11 +2,10 @@
NAME='quake2'
VERSION='git'
DOWNLOAD_URL="https://github.com/ozkl/quake2generic.git#50190797664fd42fc1b0266150c54f76f92bfa15"
DEPENDENCIES=('SDL2' 'SDL2_mixer')
DOWNLOAD_URL="https://github.com/ozkl/quake2generic.git#a967e4f567a98941326fc7fe76eee5e52a04a633"
configure() {
make clean
:
}
build() {
@ -25,13 +24,11 @@ build() {
echo "File hash does not match" >&2
exit 1
fi
cflags='-Dstricmp=strcasecmp -Wno-incompatible-pointer-types'
make CC="$CC" BASE_CFLAGS="$cflags" SDL_PATH="$BANAN_SYSROOT/usr/bin/" -j$(nproc) || exit 1
make -j$(nproc) || exit 1
}
install() {
cp -v build/quake2-soft "${BANAN_SYSROOT}/bin/quake2" || exit 1
cp build/quake2 "${BANAN_SYSROOT}/bin/" || exit 1
baseq2_tar=$(realpath ../baseq2.tar.gz || exit 1)
cd "$BANAN_SYSROOT/home/user/"

View File

@ -0,0 +1,482 @@
From f900c2967edc684334b663e522aeec79e8fee10d Mon Sep 17 00:00:00 2001
From: Bananymous <bananymousosq@gmail.com>
Date: Thu, 14 Nov 2024 12:33:39 +0200
Subject: [PATCH] Add support for banan-os
---
Makefile | 106 +++-------------
port_soft_banan_os.cpp | 277 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 295 insertions(+), 88 deletions(-)
create mode 100644 port_soft_banan_os.cpp
diff --git a/Makefile b/Makefile
index 46142df..4437418 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,3 @@
-
-SDL_CFLAGS = `sdl2-config --cflags`
-SDL_LIBS = `sdl2-config --cflags --libs` -lSDL2_mixer
-
MOUNT_DIR=.
BUILDDIR=build
@@ -18,21 +14,19 @@ GAME_DIR=$(MOUNT_DIR)/game
CTF_DIR=$(MOUNT_DIR)/ctf
XATRIX_DIR=$(MOUNT_DIR)/xatrix
-CC=clang #emcc
+CC=$(BANAN_ARCH)-banan_os-gcc
BASE_CFLAGS=-Dstricmp=strcasecmp
+CXX=$(BANAN_ARCH)-banan_os-g++
+CXXFLAGS=--std=c++20
RELEASE_CFLAGS=$(BASE_CFLAGS) -O6 -ffast-math -funroll-loops \
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
-malign-jumps=2 -malign-functions=2
DEBUG_CFLAGS=$(BASE_CFLAGS) -g
-LDFLAGS=-ldl -lm
-XCFLAGS=-I/opt/X11/include
-
-GLLDFLAGS=-L/usr/X11/lib -L/usr/local/lib \
- $(SDL_LIBS) -lGL
-GLCFLAGS=$(SDL_CFLAGS)
+LDFLAGS=-lgui -linput
+XCFLAGS=
SHLIBEXT=so
@@ -43,6 +37,10 @@ DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
DO_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
DO_GL_SHLIB_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) $(GLCFLAGS) $(XCFLAGS) -o $@ -c $<
+DO_CXX=$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $<
+DO_SHLIB_CXX=$(CXX) $(CFLAGS) $(CXXFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
+DO_GL_SHLIB_CXX=$(CXX) $(CFLAGS) $(CXXFLAGS) $(SHLIBCFLAGS) $(GLCFLAGS) $(XCFLAGS) -o $@ -c $<
+
#############################################################################
# SETUP AND BUILD
#############################################################################
@@ -61,14 +59,12 @@ createdirs:
@-mkdir -p $(BUILDDIR) \
$(BUILDDIR)/client \
$(BUILDDIR)/ref_soft \
- $(BUILDDIR)/ref_softsdl \
- $(BUILDDIR)/ref_gl \
$(BUILDDIR)/net \
$(BUILDDIR)/sound \
$(BUILDDIR)/game
-TARGETS: $(BUILDDIR)/quake2-soft $(BUILDDIR)/quake2-gl
+TARGETS: $(BUILDDIR)/quake2
#############################################################################
# CLIENT/SERVER
@@ -122,7 +118,7 @@ QUAKE2_OBJS = \
\
$(BUILDDIR)/client/pmove.o \
\
- $(BUILDDIR)/net/net_unix.o \
+ $(BUILDDIR)/net/net_loopback.o \
\
$(BUILDDIR)/sound/snddma_null.o \
\
@@ -200,38 +196,11 @@ REF_SOFT_OBJS = \
$(BUILDDIR)/ref_soft/r_rast.o \
$(BUILDDIR)/ref_soft/r_scan.o \
$(BUILDDIR)/ref_soft/r_sprite.o \
- $(BUILDDIR)/ref_soft/r_surf.o
-
-
-REF_SOFT_SDL_OBJS = \
- $(BUILDDIR)/ref_soft/port_soft_sdl.o
-
-
-#############################################################################
-# REF_GL
-#############################################################################
-
-REF_GL_OBJS = \
- $(BUILDDIR)/ref_gl/gl_draw.o \
- $(BUILDDIR)/ref_gl/gl_image.o \
- $(BUILDDIR)/ref_gl/gl_light.o \
- $(BUILDDIR)/ref_gl/gl_mesh.o \
- $(BUILDDIR)/ref_gl/gl_model.o \
- $(BUILDDIR)/ref_gl/gl_rmain.o \
- $(BUILDDIR)/ref_gl/gl_rmisc.o \
- $(BUILDDIR)/ref_gl/gl_rsurf.o \
- $(BUILDDIR)/ref_gl/gl_warp.o \
- \
- $(BUILDDIR)/ref_gl/qgl_system.o \
- $(BUILDDIR)/ref_gl/port_gl_sdl.o
-
-
-$(BUILDDIR)/quake2-soft : $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS) $(REF_SOFT_SDL_OBJS)
- $(CC) $(CFLAGS) -o $@ $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS) $(REF_SOFT_SDL_OBJS) $(LDFLAGS) $(GLLDFLAGS)
-
-$(BUILDDIR)/quake2-gl : $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_GL_OBJS)
- $(CC) $(CFLAGS) -o $@ $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_GL_OBJS) $(LDFLAGS) $(GLLDFLAGS)
+ $(BUILDDIR)/ref_soft/r_surf.o \
+ $(BUILDDIR)/ref_soft/port_soft_banan_os.o
+$(BUILDDIR)/quake2 : $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS)
+ $(CC) $(CFLAGS) -o $@ $(QUAKE2_OBJS) $(GAME_OBJS) $(REF_SOFT_OBJS) $(LDFLAGS)
$(BUILDDIR)/client/cl_cin.o : $(CLIENT_DIR)/cl_cin.c
$(DO_CC)
@@ -362,7 +331,7 @@ $(BUILDDIR)/client/q_system.o : $(OTHER_DIR)/q_system.c
$(BUILDDIR)/client/glob.o : $(OTHER_DIR)/glob.c
$(DO_CC)
-$(BUILDDIR)/net/net_unix.o : $(NET_DIR)/net_unix.c
+$(BUILDDIR)/net/net_loopback.o : $(NET_DIR)/net_loopback.c
$(DO_CC)
$(BUILDDIR)/port_platform_unix.o : $(MOUNT_DIR)/port_platform_unix.c
@@ -689,45 +658,8 @@ $(BUILDDIR)/ref_soft/r_sprite.o : $(REF_SOFT_DIR)/r_sprite.c
$(BUILDDIR)/ref_soft/r_surf.o : $(REF_SOFT_DIR)/r_surf.c
$(DO_GL_SHLIB_CC)
-$(BUILDDIR)/ref_soft/port_soft_sdl.o : $(MOUNT_DIR)/port_soft_sdl.c
- $(DO_GL_SHLIB_CC)
-
-#############################################################################
-# REF_GL
-#############################################################################
-
-$(BUILDDIR)/ref_gl/gl_draw.o : $(REF_GL_DIR)/gl_draw.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_image.o : $(REF_GL_DIR)/gl_image.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_light.o : $(REF_GL_DIR)/gl_light.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_mesh.o : $(REF_GL_DIR)/gl_mesh.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_model.o : $(REF_GL_DIR)/gl_model.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_rmain.o : $(REF_GL_DIR)/gl_rmain.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_rmisc.o : $(REF_GL_DIR)/gl_rmisc.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_rsurf.o : $(REF_GL_DIR)/gl_rsurf.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/gl_warp.o : $(REF_GL_DIR)/gl_warp.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/qgl_system.o : $(REF_GL_DIR)/qgl_system.c
- $(DO_GL_SHLIB_CC)
-
-$(BUILDDIR)/ref_gl/port_gl_sdl.o : $(MOUNT_DIR)/port_gl_sdl.c
- $(DO_GL_SHLIB_CC)
+$(BUILDDIR)/ref_soft/port_soft_banan_os.o : $(MOUNT_DIR)/port_soft_banan_os.cpp
+ $(DO_GL_SHLIB_CXX)
#############################################################################
@@ -738,8 +670,6 @@ clean:
-rm -rf \
$(BUILDDIR)/client \
$(BUILDDIR)/ref_soft \
- $(BUILDDIR)/ref_softsdl \
- $(BUILDDIR)/ref_gl \
$(BUILDDIR)/game \
$(BUILDDIR)/net \
$(BUILDDIR)/sound \
diff --git a/port_soft_banan_os.cpp b/port_soft_banan_os.cpp
new file mode 100644
index 0000000..c7d7e16
--- /dev/null
+++ b/port_soft_banan_os.cpp
@@ -0,0 +1,278 @@
+#include <LibGUI/Window.h>
+#include <LibInput/KeyEvent.h>
+#include <LibInput/MouseEvent.h>
+#include <LibImage/Image.h>
+
+#include <BAN/Debug.h>
+
+extern "C" {
+
+#include "ref_soft/r_local.h"
+#include "client/keys.h"
+
+#include "quake2.h"
+
+static LibImage::Image::Color s_palette[256];
+
+static int s_mouse_dx { 0 };
+static int s_mouse_dy { 0 };
+static bool s_relative_mouse { false };
+
+static BAN::Vector<uint8_t> s_buffer;
+static BAN::UniqPtr<LibGUI::Window> s_window;
+static bool s_is_fullscreen { false };
+
+static int key_to_quake_key(LibInput::Key key)
+{
+ using namespace LibInput;
+
+ switch (key)
+ {
+ case Key::PageUp: return K_PGUP;
+ case Key::PageDown: return K_PGDN;
+ case Key::Home: return K_HOME;
+ case Key::End: return K_END;
+ case Key::ArrowLeft: return K_LEFTARROW;
+ case Key::ArrowRight: return K_RIGHTARROW;
+ case Key::ArrowDown: return K_DOWNARROW;
+ case Key::ArrowUp: return K_UPARROW;
+ case Key::Escape: return K_ESCAPE;
+ case Key::Enter: return K_ENTER;
+ case Key::Tab: return K_TAB;
+ case Key::F1: return K_F1;
+ case Key::F2: return K_F2;
+ case Key::F3: return K_F3;
+ case Key::F4: return K_F4;
+ case Key::F5: return K_F5;
+ case Key::F6: return K_F6;
+ case Key::F7: return K_F7;
+ case Key::F8: return K_F8;
+ case Key::F9: return K_F9;
+ case Key::F10: return K_F10;
+ case Key::F11: return K_F11;
+ case Key::F12: return K_F12;
+ case Key::Backspace: return K_BACKSPACE;
+ case Key::Delete: return K_DEL;
+ case Key::LeftShift:
+ case Key::RightShift: return K_SHIFT;
+ case Key::LeftCtrl:
+ case Key::RightCtrl: return K_CTRL;
+ case Key::LeftAlt:
+ case Key::RightAlt: return K_ALT;
+ case Key::Insert: return K_INS;
+ default:
+ if (const char* ascii = key_to_utf8(key, 0); ascii && strlen(ascii) == 1)
+ return *ascii;
+ break;
+ }
+
+ return 0;
+}
+
+static int button_to_quake_button(LibInput::MouseButton button)
+{
+ using namespace LibInput;
+
+ switch (button)
+ {
+ case LibInput::MouseButton::Left: return K_MOUSE1;
+ case LibInput::MouseButton::Right: return K_MOUSE2;
+ case LibInput::MouseButton::Middle: return K_MOUSE3;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void create_window(uint32_t width, uint32_t height)
+{
+ ASSERT(!s_window);
+ s_window = MUST(LibGUI::Window::create(width, height, "Quake2"_sv));
+
+ s_window->set_mouse_move_event_callback(
+ [](auto event)
+ {
+ if (!s_relative_mouse)
+ return;
+ s_mouse_dx += event.x;
+ s_mouse_dy += event.y;
+ }
+ );
+
+ s_window->set_mouse_button_event_callback(
+ [](auto event)
+ {
+ if (int button = button_to_quake_button(event.button))
+ Quake2_SendKey(button, event.pressed);
+ }
+ );
+
+ s_window->set_key_event_callback(
+ [](auto event)
+ {
+ if (int key = key_to_quake_key(event.key))
+ Quake2_SendKey(key, event.pressed());
+ }
+ );
+
+ s_window->set_close_window_event_callback(
+ []()
+ {
+ char command[] = "quit";
+ ri.Cmd_ExecuteText(EXEC_NOW, command);
+ }
+ );
+}
+
+rserr_t SWimp_SetMode(int* pwidth, int* pheight, int mode, qboolean fullscreen)
+{
+ int width, height;
+
+ if (!ri.Vid_GetModeInfo(&width, &height, mode))
+ return rserr_invalid_mode;
+
+ if (!s_window)
+ create_window(width, height);
+ else if (s_window->width() != width || s_window->height() != height)
+ {
+ s_window->request_resize(width, height);
+
+ bool resized { false };
+ s_window->set_resize_window_event_callback([&]() { resized = true; });
+ while (!resized)
+ s_window->poll_events();
+ s_window->set_resize_window_event_callback({});
+
+ ASSERT(s_window->width() == width && s_window->height() == height);
+ }
+
+ if (s_is_fullscreen != fullscreen)
+ {
+ s_is_fullscreen = fullscreen;
+ s_window->set_fullscreen(fullscreen);
+ }
+
+ MUST(s_buffer.resize(s_window->width() * s_window->height()));
+ vid.rowbytes = s_window->width();
+ vid.buffer = s_buffer.data();
+
+ *pwidth = s_window->width();
+ *pheight = s_window->height();
+
+ ri.Vid_NewWindow(s_window->width(), s_window->height());
+
+ return rserr_ok;
+}
+
+void SWimp_Shutdown(void)
+{
+}
+
+int SWimp_Init(void* hInstance, void* wndProc)
+{
+ return true;
+}
+
+static qboolean SWimp_InitGraphics(qboolean fullscreen)
+{
+ return rserr_ok;
+}
+
+void SWimp_SetPalette(const unsigned char* palette)
+{
+ for (int i = 0; i < 256; i++)
+ {
+ s_palette[i].r = *palette++;
+ s_palette[i].g = *palette++;
+ s_palette[i].b = *palette++;
+ s_palette[i].a = *palette++;
+ }
+}
+
+void SWimp_BeginFrame(float camera_seperation)
+{
+}
+
+void SWimp_EndFrame(void)
+{
+ auto& texture = s_window->texture();
+ const uint32_t width = s_window->width();
+ const uint32_t height = s_window->height();
+ for (int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
+ texture.set_pixel(x, y, s_palette[s_buffer[y * width + x]].as_argb());
+ s_window->invalidate();
+}
+
+void SWimp_AppActivate(qboolean active)
+{
+}
+
+int QG_Milliseconds(void)
+{
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (ts.tv_sec * 1'000) + (ts.tv_nsec / 1'000'000);
+}
+
+void QG_GetMouseDiff(int* dx, int* dy)
+{
+ *dx = s_mouse_dx;
+ s_mouse_dx = 0;
+
+ *dy = s_mouse_dy;
+ s_mouse_dy = 0;
+}
+
+void QG_CaptureMouse(void)
+{
+ s_relative_mouse = true;
+ s_window->set_mouse_capture(true);
+}
+
+void QG_ReleaseMouse(void)
+{
+ s_relative_mouse = false;
+ s_window->set_mouse_capture(false);
+}
+
+static uint64_t get_current_ns()
+{
+ timespec last_ts;
+ clock_gettime(CLOCK_MONOTONIC, &last_ts);
+ return (uint64_t)last_ts.tv_sec * 1'000'000'000 + last_ts.tv_nsec;
+}
+
+int main(int argc, char** argv)
+{
+ Quake2_Init(argc, argv);
+
+ uint64_t last_ns = get_current_ns();
+ for (;;)
+ {
+ s_window->poll_events();
+
+ const uint64_t current_ns = get_current_ns();
+ uint64_t duration_ns = current_ns - last_ns;
+
+ if (duration_ns < 1'000'000)
+ {
+ timespec sleep_ts {
+ .tv_sec = 0,
+ .tv_nsec = (long)(1'000'000 - duration_ns)
+ };
+ while (nanosleep(&sleep_ts, &sleep_ts))
+ continue;
+ duration_ns = get_current_ns() - last_ns;
+ }
+
+ Quake2_Frame(duration_ns / 1'000'000);
+
+ last_ns = current_ns;
+ }
+
+ return 0;
+}
+
+}
--
2.47.0

View File

@ -1,52 +0,0 @@
From fd08d90bb7ee8388a9e005bae23edcccbfc73dbb Mon Sep 17 00:00:00 2001
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
Date: Sun, 10 Aug 2025 19:52:20 +0300
Subject: [PATCH] add support for custom SDL path and add sound support
---
Makefile | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index 8edbffa..de2f605 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-SDL_CFLAGS = `sdl2-config --cflags`
-SDL_LIBS = `sdl2-config --cflags --libs` -lSDL2_mixer
+SDL_CFLAGS = `$(SDL_PATH)sdl2-config --cflags`
+SDL_LIBS = `$(SDL_PATH)sdl2-config --cflags --libs` -lSDL2_mixer
MOUNT_DIR=.
@@ -124,7 +124,7 @@ QUAKE2_OBJS = \
\
$(BUILDDIR)/net/net_unix.o \
\
- $(BUILDDIR)/sound/snddma_null.o \
+ $(BUILDDIR)/sound/snd_sdl.o \
\
$(BUILDDIR)/port_platform_unix.o
@@ -353,7 +353,7 @@ $(BUILDDIR)/client/vid_menu.o : $(OTHER_DIR)/vid_menu.c
$(BUILDDIR)/client/vid_lib.o : $(OTHER_DIR)/vid_lib.c
$(DO_CC)
-$(BUILDDIR)/client/snddma_null.o : $(NULL_DIR)/snddma_null.c
+$(BUILDDIR)/client/snd_sdl.o : $(NULL_DIR)/snd_sdl.c
$(DO_CC)
$(BUILDDIR)/client/q_system.o : $(OTHER_DIR)/q_system.c
@@ -368,7 +368,7 @@ $(BUILDDIR)/net/net_unix.o : $(NET_DIR)/net_unix.c
$(BUILDDIR)/port_platform_unix.o : $(MOUNT_DIR)/port_platform_unix.c
$(DO_CC)
-$(BUILDDIR)/sound/snddma_null.o : $(SOUND_DIR)/snddma_null.c
+$(BUILDDIR)/sound/snd_sdl.o : $(SOUND_DIR)/snd_sdl.c
$(DO_GL_SHLIB_CC)
--
2.50.1

View File

@ -1,42 +0,0 @@
From fbdf3e7c40c1de83a2361bb904d8dbd3464ccebd Mon Sep 17 00:00:00 2001
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
Date: Sun, 10 Aug 2025 19:54:38 +0300
Subject: [PATCH 2/2] fix socket creation
---
net/net_unix.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/net/net_unix.c b/net/net_unix.c
index a92e57c..f297dff 100644
--- a/net/net_unix.c
+++ b/net/net_unix.c
@@ -451,24 +451,16 @@ int NET_Socket (char *net_interface, int port)
qboolean _true = true;
int i = 1;
- if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ if ((newsocket = socket (PF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) == -1)
{
Com_Printf ("ERROR: UDP_OpenSocket: socket:", NET_ErrorString());
return 0;
}
- // make it non-blocking
- if (ioctl (newsocket, FIONBIO, &_true) == -1)
- {
- Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
- return 0;
- }
-
// make it broadcast capable
if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
{
Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
- return 0;
}
if (!net_interface || !net_interface[0] || !stricmp(net_interface, "localhost"))
--
2.50.1

View File

@ -1,31 +0,0 @@
#!/bin/bash ../install.sh
NAME='timidity'
VERSION='2.15.0'
DOWNLOAD_URL="https://sourceforge.net/projects/timidity/files/TiMidity++/TiMidity++-$VERSION/TiMidity++-$VERSION.tar.gz#0b6109a3c64604c8851cd9bb4cbafc014a4e13b0025f597e586d9742388f6fb7"
TAR_CONTENT="TiMidity++-$VERSION"
CONFIG_SUB=('autoconf/config.sub')
CONFIGURE_OPTIONS=(
'--without-x'
'lib_cv_va_copy=y'
'lib_cv___va_copy=n'
'lib_cv_va_val_copy=n'
'CFLAGS=-std=c11'
)
pre_configure() {
unset CC CXX LD
}
post_install() {
if [ ! -f ../eawpats.zip ]; then
wget https://www.quaddicted.com/files/idgames/sounds/eawpats.zip -O ../eawpats.zip || exit 1
fi
eawpats_dir="/usr/share/eawpats"
mkdir -p "$BANAN_SYSROOT/$eawpats_dir"
unzip -qod "$BANAN_SYSROOT/$eawpats_dir" ../eawpats.zip
cp "$BANAN_SYSROOT/$eawpats_dir/timidity.cfg" "$BANAN_SYSROOT/etc/"
sed -i "s|^dir .*$|dir $eawpats_dir|g" "$BANAN_SYSROOT/etc/timidity.cfg"
}

View File

@ -3,15 +3,13 @@
NAME='tinygb'
VERSION='git'
DOWNLOAD_URL="https://github.com/jewelcodes/tinygb.git#57fdaff675a6b5b963b2b6624868d9698eabe375"
DEPENDENCIES=('SDL2')
configure() {
sed -i "s|shell sdl2-config|shell $BANAN_SYSROOT/usr/bin/sdl2-config|g" Makefile
make clean
make -f Makefile.banan_os clean
}
build() {
make CC="$CC" LD="$CC" || exit 1
make -f Makefile.banan_os -j$(nproc) || exit 1
}
install() {

View File

@ -0,0 +1,420 @@
From 7f7c6402e384591bca63021aa97d60a8107de88d Mon Sep 17 00:00:00 2001
From: Bananymous <bananymousosq@gmail.com>
Date: Mon, 5 May 2025 00:59:03 +0300
Subject: [PATCH] Add support for banan-os
---
Makefile.banan_os | 28 +++
src/platform/banan-os/main.cpp | 362 +++++++++++++++++++++++++++++++++
2 files changed, 390 insertions(+)
create mode 100644 Makefile.banan_os
create mode 100644 src/platform/banan-os/main.cpp
diff --git a/Makefile.banan_os b/Makefile.banan_os
new file mode 100644
index 0000000..22e191e
--- /dev/null
+++ b/Makefile.banan_os
@@ -0,0 +1,28 @@
+CC = $(BANAN_ARCH)-banan_os-gcc
+CXX = $(BANAN_ARCH)-banan_os-g++
+LD = $(BANAN_ARCH)-banan_os-gcc
+
+CFLAGS = -c -O2 -Isrc/include -Wall
+CXXFLAGS = --std=c++20
+LDFLAGS = -O2 -lgui -linput
+
+SRC := $(shell find src -name "*.c" -not -path 'src/platform/*') $(shell find src/platform/banan-os -name "*.c" -or -name "*.cpp")
+OBJ := $(addsuffix .o,$(SRC))
+
+all: tinygb
+
+clean:
+ @rm -f $(OBJ)
+ @rm -f tinygb
+
+%.c.o: %.c
+ @echo -e "\x1B[0;1;35m [ CC ]\x1B[0m $@"
+ $(CC) -o $@ $(CFLAGS) $<
+
+%.cpp.o: %.cpp
+ @echo -e "\x1B[0;1;35m [ CC ]\x1B[0m $@"
+ $(CXX) -o $@ $(CFLAGS) $(CXXFLAGS) $<
+
+tinygb: $(OBJ)
+ @echo -e "\x1B[0;1;36m [ LD ]\x1B[0m tinygb"
+ $(LD) $(OBJ) -o tinygb $(LDFLAGS)
diff --git a/src/platform/banan-os/main.cpp b/src/platform/banan-os/main.cpp
new file mode 100644
index 0000000..94f249e
--- /dev/null
+++ b/src/platform/banan-os/main.cpp
@@ -0,0 +1,364 @@
+
+/* tinygb - a tiny gameboy emulator
+ (c) 2022 by jewel */
+
+extern "C" {
+#include <tinygb.h>
+}
+
+#include <LibGUI/Window.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+long rom_size;
+int scaling = 4;
+int frameskip = 0; // no skip
+
+timing_t timing;
+char *rom_filename;
+
+BAN::UniqPtr<LibGUI::Window> s_window;
+
+// Key Config
+LibInput::Key key_a;
+LibInput::Key key_b;
+LibInput::Key key_start;
+LibInput::Key key_select;
+LibInput::Key key_up;
+LibInput::Key key_down;
+LibInput::Key key_left;
+LibInput::Key key_right;
+LibInput::Key key_throttle;
+
+LibInput::Key get_key(const char* keyname)
+{
+ if (keyname == nullptr);
+ else if (!strcmp("a", keyname)) return LibInput::Key::A;
+ else if (!strcmp("b", keyname)) return LibInput::Key::B;
+ else if (!strcmp("c", keyname)) return LibInput::Key::C;
+ else if (!strcmp("d", keyname)) return LibInput::Key::D;
+ else if (!strcmp("e", keyname)) return LibInput::Key::E;
+ else if (!strcmp("f", keyname)) return LibInput::Key::F;
+ else if (!strcmp("g", keyname)) return LibInput::Key::G;
+ else if (!strcmp("h", keyname)) return LibInput::Key::H;
+ else if (!strcmp("i", keyname)) return LibInput::Key::I;
+ else if (!strcmp("j", keyname)) return LibInput::Key::J;
+ else if (!strcmp("k", keyname)) return LibInput::Key::K;
+ else if (!strcmp("l", keyname)) return LibInput::Key::L;
+ else if (!strcmp("m", keyname)) return LibInput::Key::M;
+ else if (!strcmp("n", keyname)) return LibInput::Key::N;
+ else if (!strcmp("o", keyname)) return LibInput::Key::O;
+ else if (!strcmp("p", keyname)) return LibInput::Key::P;
+ else if (!strcmp("q", keyname)) return LibInput::Key::Q;
+ else if (!strcmp("r", keyname)) return LibInput::Key::R;
+ else if (!strcmp("s", keyname)) return LibInput::Key::S;
+ else if (!strcmp("t", keyname)) return LibInput::Key::T;
+ else if (!strcmp("u", keyname)) return LibInput::Key::U;
+ else if (!strcmp("v", keyname)) return LibInput::Key::V;
+ else if (!strcmp("w", keyname)) return LibInput::Key::W;
+ else if (!strcmp("x", keyname)) return LibInput::Key::X;
+ else if (!strcmp("y", keyname)) return LibInput::Key::Y;
+ else if (!strcmp("z", keyname)) return LibInput::Key::Z;
+ else if (!strcmp("0", keyname)) return LibInput::Key::_0;
+ else if (!strcmp("1", keyname)) return LibInput::Key::_1;
+ else if (!strcmp("2", keyname)) return LibInput::Key::_2;
+ else if (!strcmp("3", keyname)) return LibInput::Key::_3;
+ else if (!strcmp("4", keyname)) return LibInput::Key::_4;
+ else if (!strcmp("5", keyname)) return LibInput::Key::_5;
+ else if (!strcmp("6", keyname)) return LibInput::Key::_6;
+ else if (!strcmp("7", keyname)) return LibInput::Key::_7;
+ else if (!strcmp("8", keyname)) return LibInput::Key::_8;
+ else if (!strcmp("9", keyname)) return LibInput::Key::_9;
+ else if (!strcmp("up", keyname)) return LibInput::Key::ArrowUp;
+ else if (!strcmp("down", keyname)) return LibInput::Key::ArrowDown;
+ else if (!strcmp("left", keyname)) return LibInput::Key::ArrowLeft;
+ else if (!strcmp("right", keyname)) return LibInput::Key::ArrowRight;
+ else if (!strcmp("space", keyname)) return LibInput::Key::Space;
+ else if (!strcmp("rshift", keyname)) return LibInput::Key::RightShift;
+ else if (!strcmp("lshift", keyname)) return LibInput::Key::LeftShift;
+ else if (!strcmp("backspace", keyname)) return LibInput::Key::Backspace;
+ else if (!strcmp("delete", keyname)) return LibInput::Key::Delete;
+ else if (!strcmp("tab", keyname)) return LibInput::Key::Tab;
+ else if (!strcmp("escape", keyname)) return LibInput::Key::Escape;
+ else if (!strcmp("exclamation", keyname)) return LibInput::Key::ExclamationMark;
+ else if (!strcmp("at", keyname)) return LibInput::Key::AtSign;
+ else if (!strcmp("hash", keyname)) return LibInput::Key::Hashtag;
+ else if (!strcmp("dollar", keyname)) return LibInput::Key::Dollar;
+ else if (!strcmp("percent", keyname)) return LibInput::Key::Percent;
+ else if (!strcmp("caret", keyname)) return LibInput::Key::Caret;
+ else if (!strcmp("ampersand", keyname)) return LibInput::Key::Ampersand;
+ else if (!strcmp("asterisk", keyname)) return LibInput::Key::Asterix;
+ else if (!strcmp("leftparenthesis", keyname)) return LibInput::Key::OpenParenthesis;
+ else if (!strcmp("rightparenthesis", keyname)) return LibInput::Key::CloseParenthesis;
+
+ return LibInput::Key::None;
+}
+
+static void load_keys()
+{
+ key_a = get_key(config_file.a);
+ if (key_a == LibInput::Key::None)
+ key_a = LibInput::Key::Z;
+
+ key_b = get_key(config_file.b);
+ if (key_b == LibInput::Key::None)
+ key_b = LibInput::Key::X;
+
+ key_start = get_key(config_file.start);
+ if (key_start == LibInput::Key::None)
+ key_start = LibInput::Key::Enter;
+
+ key_select = get_key(config_file.select);
+ if (key_select == LibInput::Key::None)
+ key_select = LibInput::Key::RightShift;
+
+ key_up = get_key(config_file.up);
+ if (key_up == LibInput::Key::None)
+ key_up = LibInput::Key::ArrowUp;
+
+ key_down = get_key(config_file.down);
+ if (key_down == LibInput::Key::None)
+ key_down = LibInput::Key::ArrowDown;
+
+ key_left = get_key(config_file.left);
+ if (key_left == LibInput::Key::None)
+ key_left = LibInput::Key::ArrowLeft;
+
+ key_right = get_key(config_file.right);
+ if (key_right == LibInput::Key::None)
+ key_right = LibInput::Key::ArrowRight;
+
+ key_throttle = get_key(config_file.throttle);
+ if (key_throttle == LibInput::Key::None)
+ key_throttle = LibInput::Key::Space;
+}
+
+void delay(int ms)
+{
+ const timespec ts {
+ .tv_sec = static_cast<time_t>(ms / 1000),
+ .tv_nsec = (ms % 1000) * 1000000
+ };
+ nanosleep(&ts, nullptr);
+}
+
+void destroy_window()
+{
+ s_window.clear();
+}
+
+void update_window(uint32_t *framebuffer)
+{
+ auto pixels = s_window->texture().pixels();
+ for (int i = 0; i < scaled_h; i++)
+ {
+ uint32_t* src = &framebuffer[i * scaled_w];
+ uint32_t* dst = using_sgb_border
+ ? &pixels[(i + gb_y) * s_window->width() + gb_x]
+ : &pixels[i * s_window->width()];
+ memcpy(dst, src, scaled_w * 4);
+ }
+
+ if (framecount > frameskip)
+ {
+ s_window->invalidate();
+ framecount = 0;
+ drawn_frames++;
+ }
+}
+
+void update_border(uint32_t *framebuffer)
+{
+ auto pixels = s_window->texture().pixels();
+ for (int i = 0; i < sgb_scaled_h; i++)
+ {
+ uint32_t* src = &framebuffer[i * sgb_scaled_w];
+ uint32_t* dst = &pixels[i * s_window->width()];
+ memcpy(dst, src, sgb_scaled_w*4);
+ }
+}
+
+void resize_sgb_window()
+{
+ s_window->request_resize(SGB_WIDTH * scaling, SGB_HEIGHT * scaling);
+
+ bool resized { false };
+ s_window->set_resize_window_event_callback([&]() { resized = true; });
+ while (!resized)
+ s_window->poll_events();
+ s_window->set_resize_window_event_callback({});
+
+ ASSERT(s_window->width() == static_cast<uint32_t>(SGB_WIDTH * scaling));
+ ASSERT(s_window->height() == static_cast<uint32_t>(SGB_HEIGHT * scaling));
+}
+
+int main(int argc, char **argv) {
+ if(argc != 2) {
+ fprintf(stdout, "usage: %s rom_name\n", argv[0]);
+ return 1;
+ }
+
+ rom_filename = argv[1];
+
+ open_log();
+ open_config();
+ load_keys();
+
+ // open the rom
+ FILE *rom_file = fopen(rom_filename, "r");
+ if(!rom_file) {
+ write_log("unable to open %s for reading: %s\n", rom_filename, strerror(errno));
+ return 1;
+ }
+
+ fseek(rom_file, 0L, SEEK_END);
+ rom_size = ftell(rom_file);
+ fseek(rom_file, 0L, SEEK_SET);
+
+ write_log("loading rom from file %s, %d KiB\n", rom_filename, rom_size / 1024);
+
+ rom = malloc(rom_size);
+ if(!rom) {
+ write_log("unable to allocate memory\n");
+ fclose(rom_file);
+ return 1;
+ }
+
+ if (fread(rom, 1, rom_size, rom_file) <= 0)
+ {
+ write_log("an error occured while reading from rom file: %s\n", strerror(errno));
+ fclose(rom_file);
+ free(rom);
+ return 1;
+ }
+
+ fclose(rom_file);
+
+ if (auto ret = LibGUI::Window::create(GB_WIDTH * scaling, GB_HEIGHT * scaling, "tinygb"_sv); !ret.is_error())
+ s_window = ret.release_value();
+ else
+ {
+ write_log("couldn't create SDL window: %s\n", ret.error().get_message());
+ free(rom);
+ return 1;
+ }
+
+ s_window->set_key_event_callback([](LibGUI::EventPacket::KeyEvent::event_t event) {
+ int key = 0;
+ if (event.key == key_left)
+ key = JOYPAD_LEFT;
+ else if (event.key == key_right)
+ key = JOYPAD_RIGHT;
+ else if (event.key == key_up)
+ key = JOYPAD_UP;
+ else if (event.key == key_down)
+ key = JOYPAD_DOWN;
+ else if (event.key == key_a)
+ key = JOYPAD_A;
+ else if (event.key == key_b)
+ key = JOYPAD_B;
+ else if (event.key == key_start)
+ key = JOYPAD_START;
+ else if (event.key == key_select)
+ key = JOYPAD_SELECT;
+ else if (event.key == key_throttle)
+ throttle_enabled = event.released();
+ else if (event.pressed() && (event.key == LibInput::Key::Plus || event.key == LibInput::Key::Equals))
+ next_palette();
+ else if (event.pressed() && (event.key == LibInput::Key::Hyphen))
+ prev_palette();
+
+ if (key)
+ joypad_handle(event.pressed(), key);
+ });
+
+ // start emulation
+ memory_start();
+ cpu_start();
+ display_start();
+ timer_start();
+ sound_start();
+
+ time_t rawtime;
+ struct tm *timeinfo;
+ int sec = 500; // any invalid number
+ char new_title[256];
+ int percentage;
+ int throttle_underflow = 0;
+ int throttle_target = throttle_lo + SPEED_ALLOWANCE;
+
+ while(1) {
+ s_window->poll_events();
+
+ for(timing.current_cycles = 0; timing.current_cycles < timing.main_cycles; ) {
+ cpu_cycle();
+ display_cycle();
+ timer_cycle();
+ }
+
+
+ time(&rawtime);
+ timeinfo = localtime(&rawtime);
+
+ if(sec != timeinfo->tm_sec) {
+ sec = timeinfo->tm_sec;
+ percentage = (drawn_frames * 1000) / 597;
+ sprintf(new_title, "tinygb (%d fps - %d%%)", drawn_frames, percentage);
+ s_window->set_title(new_title);
+
+ // adjust cpu throttle according to acceptable fps (98%-102%)
+ if(throttle_enabled) {
+ if(percentage < throttle_lo) {
+ // emulation is too slow
+ if(!throttle_time) {
+ // throttle_time--;
+
+ if(!throttle_underflow) {
+ throttle_underflow = 1;
+ write_log("WARNING: CPU throttle interval has underflown, emulation may be too slow\n");
+ }
+ } else {
+ //write_log("too slow; decreasing throttle time: %d\n", throttle_time);
+
+ // this will speed up the speed adjustments for a more natural feel
+ if(percentage < (throttle_target/3)) throttle_time /= 3;
+ else if(percentage < (throttle_target/2)) throttle_time /= 2;
+ else throttle_time--;
+ }
+
+ // prevent this from going too low
+ if(throttle_time <= (THROTTLE_THRESHOLD/3)) {
+ cycles_per_throttle += (cycles_per_throttle/5); // delay 20% less often
+ throttle_time = (THROTTLE_THRESHOLD/3);
+ }
+ } else if(percentage > throttle_hi) {
+ // emulation is too fast
+ //write_log("too fast; increasing throttle time: %d\n", throttle_time);
+
+ if(throttle_time) {
+ // to make sure we're not multiplying zero
+ if(percentage > (throttle_target*3)) throttle_time *= 3;
+ else if(percentage > (throttle_target*2)) throttle_time *= 2;
+ else throttle_time++;
+ }
+ else {
+ throttle_time++;
+ }
+
+ // prevent unnecessary lag
+ if(throttle_time > THROTTLE_THRESHOLD) {
+ cycles_per_throttle -= (cycles_per_throttle/5); // delay 20% more often
+ throttle_time = THROTTLE_THRESHOLD;
+ }
+ }
+ }
+
+ drawn_frames = 0;
+ }
+ }
+
+ die(0, "");
+ return 0;
+}
\ No newline at end of file
--
2.49.0

View File

@ -39,8 +39,8 @@ SOUND_ARGS='-device ac97'
qemu-system-$QEMU_ARCH \
-m 1G -smp 4 \
$BIOS_ARGS \
$USB_ARGS \
$DISK_ARGS \
$USB_ARGS \
$NET_ARGS \
$SOUND_ARGS \
$@ \

View File

@ -10,7 +10,6 @@ set(LIBC_SOURCES
errno.cpp
fcntl.cpp
fenv.cpp
fnmatch.cpp
ftw.cpp
grp.cpp
ifaddrs.cpp

View File

@ -1,80 +0,0 @@
#include <fnmatch.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
static int fnmatch_impl(const char* pattern, const char* string, int flags, bool leading)
{
while (*pattern)
{
if ((flags & FNM_PERIOD) && leading && *string == '.' && *pattern != '.')
return FNM_NOMATCH;
leading = false;
switch (*pattern)
{
case '*':
{
const char* ptr = strchrnul(string, (flags & FNM_PATHNAME) ? '/' : '0');
while (ptr >= string)
if (fnmatch_impl(pattern + 1, ptr--, flags, false) == 0)
return 0;
return FNM_NOMATCH;
}
case '[':
{
if (strchr(pattern, ']') == nullptr)
break;
pattern++;
const bool negate = (*pattern == '!');
if (negate)
pattern++;
uint8_t ch;
uint32_t bitmap[0x100 / 8] {};
while ((ch = *pattern++) != ']')
bitmap[ch / 32] |= 1 << (ch % 32);
ch = *string++;
if (!!(bitmap[ch / 32] & (1 << (ch % 32))) == negate)
return FNM_NOMATCH;
continue;
}
case '?':
{
if (*string == '\0')
return FNM_NOMATCH;
if ((flags & FNM_PATHNAME) && *string == '/')
return FNM_NOMATCH;
pattern++;
string++;
continue;
}
case '\\':
{
if (!(flags & FNM_NOESCAPE))
pattern++;
break;
}
}
if (*pattern == '\0')
break;
if (*pattern != *string)
return FNM_NOMATCH;
if ((flags & FNM_PATHNAME) && *string == '/')
leading = true;
pattern++;
string++;
}
return *string ? FNM_NOMATCH : 0;
}
int fnmatch(const char* pattern, const char* string, int flags)
{
return fnmatch_impl(pattern, string, flags, true);
}

View File

@ -4,7 +4,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
static FILE* s_grent_fp = nullptr;
static group s_grent_struct;
@ -212,106 +211,3 @@ int getgrnam_r(const char* name, struct group* grp, char* buffer, size_t bufsize
fclose(fp);
return ret;
}
static gid_t* get_user_groups(const char* user)
{
FILE* fp = fopen("/etc/group", "r");
if (fp == nullptr)
return nullptr;
const long initial_len = sysconf(_SC_GETGR_R_SIZE_MAX);
size_t buffer_len = (initial_len == -1) ? 512 : initial_len;
char* buffer = static_cast<char*>(malloc(buffer_len));
if (buffer == nullptr)
{
fclose(fp);
return nullptr;
}
size_t group_count = 0;
gid_t* groups = static_cast<gid_t*>(malloc(sizeof(gid_t)));
if (groups == nullptr)
{
free(buffer);
fclose(fp);
return nullptr;
}
for (;;)
{
struct group result;
struct group* resultp;
int error = getgrent_impl(fp, &result, buffer, buffer_len, &resultp);
if (error == ERANGE)
{
const size_t new_buffer_len = buffer_len * 2;
char* new_buffer = static_cast<char*>(realloc(buffer, new_buffer_len));
if (new_buffer == nullptr)
{
error = ENOMEM;
break;
}
buffer = new_buffer;
buffer_len = new_buffer_len;
continue;
}
if (error != 0)
{
free(buffer);
free(groups);
fclose(fp);
return nullptr;
}
if (resultp == nullptr)
break;
bool contains = false;
for (size_t i = 0; result.gr_mem[i] && !contains; i++)
contains = (strcmp(result.gr_mem[i], user) == 0);
if (!contains)
continue;
gid_t* new_groups = static_cast<gid_t*>(realloc(groups, group_count * sizeof(gid_t)));
if (new_groups == nullptr)
{
free(buffer);
free(groups);
fclose(fp);
return nullptr;
}
groups = new_groups;
groups[group_count++] = result.gr_gid;
}
groups[group_count] = -1;
free(buffer);
fclose(fp);
return groups;
}
int initgroups(const char* user, gid_t group)
{
gid_t* groups = get_user_groups(user);
if (groups == nullptr)
return -1;
size_t group_count = 0;
while (groups[group_count] != -1)
group_count++;
groups[group_count] = group;
int result = setgroups(group_count + 1, groups);
free(groups);
return result;
}
int setgroups(size_t size, const gid_t list[])
{
return syscall(SYS_SETGROUPS, list, size);
}

View File

@ -14,7 +14,7 @@ __BEGIN_DECLS
struct group
{
char* gr_name; /* The name of the group. */
char* gr_passwd; /* The password of the group */
char* gr_passwd;/* The password of the group */
gid_t gr_gid; /* Numerical group ID. */
char** gr_mem; /* Pointer to a null-terminated array of character pointers to member names. */
};
@ -27,9 +27,6 @@ struct group* getgrnam(const char* name);
int getgrnam_r(const char* name, struct group* grp, char* buffer, size_t bufsize, struct group** result);
void setgrent(void);
int initgroups(const char* user, gid_t group);
int setgroups(size_t size, const gid_t list[]);
__END_DECLS
#endif

View File

@ -59,8 +59,6 @@ enum
#define IPV6_V6ONLY IPV6_V6ONLY
};
#define IN_MULTICAST(a) (((in_addr_t)(a) & 0xF0000000) == 0xE0000000)
#define INADDR_ANY 0
#define INADDR_NONE 0xFFFFFFFF
#define INADDR_BROADCAST 0xFFFFFFFF
@ -69,63 +67,31 @@ enum
#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
#define IN6_IS_ADDR_UNSPECIFIED(a) \
((a)->s6_addr32[0] == 0 && \
(a)->s6_addr32[1] == 0 && \
(a)->s6_addr32[2] == 0 && \
(a)->s6_addr32[3] == 0)
#define IN6_IS_ADDR_LOOPBACK(a) \
((a)->s6_addr32[0] == 0 && \
(a)->s6_addr32[1] == 0 && \
(a)->s6_addr32[2] == 0 && \
(a)->s6_addr32[3] == htonl(1))
#define IN6_IS_ADDR_MULTICAST(a) \
((a)->s6_addr[0] == 0xFF)
#define IN6_IS_ADDR_LINKLOCAL(a) \
((a)->s6_addr[0] == 0xFE && \
((a)->s6_addr[1] & 0xC0) == 0x80)
#define IN6_IS_ADDR_SITELOCAL(a) \
((a)->s6_addr[0] == 0xFE && \
((a)->s6_addr[1] & 0xC0) == 0xC0)
#define IN6_IS_ADDR_V4MAPPED(a) \
((a)->s6_addr32[0] == 0 && \
(a)->s6_addr32[1] == 0 && \
(a)->s6_addr32[2] == htonl(0x0000FFFF))
#define IN6_IS_ADDR_V4COMPAT(a) \
((a)->s6_addr32[0] == 0 && \
(a)->s6_addr32[1] == 0 && \
(a)->s6_addr32[2] == 0 && \
ntohl((a)->s6_addr32[3]) > 1)
#define IN6_IS_ADDR_MC_NODELOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) && \
((a)->s6_addr[1] & 0x0F) == 0x01)
#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) && \
((a)->s6_addr[1] & 0x0F) == 0x02)
#define IN6_IS_ADDR_MC_SITELOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) && \
((a)->s6_addr[1] & 0x0F) == 0x05)
#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) && \
((a)->s6_addr[1] & 0x0F) == 0x08)
#define IN6_IS_ADDR_MC_GLOBAL(a) \
(IN6_IS_ADDR_MULTICAST(a) && \
((a)->s6_addr[1] & 0x0F) == 0x0E)
#if 0
#define IN6_IS_ADDR_UNSPECIFIED(addr)
#define IN6_IS_ADDR_LOOPBACK(addr)
#define IN6_IS_ADDR_MULTICAST(addr)
#define IN6_IS_ADDR_LINKLOCAL(addr)
#define IN6_IS_ADDR_SITELOCAL(addr)
#define IN6_IS_ADDR_V4MAPPED(addr)
#define IN6_IS_ADDR_V4COMPAT(addr)
#define IN6_IS_ADDR_MC_NODELOCAL(addr)
#define IN6_IS_ADDR_MC_LINKLOCAL(addr)
#define IN6_IS_ADDR_MC_SITELOCAL(addr)
#define IN6_IS_ADDR_MC_ORGLOCAL(addr)
#define IN6_IS_ADDR_MC_GLOBAL(addr)
#endif
struct sockaddr_in
{
sa_family_t sin_family; /* AF_INET. */
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* IP address. */
unsigned char sin_zero[8];
};
struct in6_addr
{
union {
uint8_t s6_addr[16];
uint32_t s6_addr32[4];
};
uint8_t s6_addr[16];
};
struct sockaddr_in6

View File

@ -37,8 +37,6 @@ __BEGIN_DECLS
#define KDLOADFONT 30
#define FIONREAD 40 /* get number of input bytes available */
struct winsize
{
unsigned short ws_row;

View File

@ -24,8 +24,8 @@ __BEGIN_DECLS
struct sockaddr
{
sa_family_t sa_family; /* Address family. */
char sa_data[14]; /* Socket address (variable-length data). */
sa_family_t sa_family; /* Address family. */
char sa_data[0]; /* Socket address (variable-length data). */
};
struct sockaddr_storage

View File

@ -111,9 +111,6 @@ __BEGIN_DECLS
O(SYS_FLOCK, flock) \
O(SYS_GET_NPROCESSOR, get_nprocessor) \
O(SYS_FUTEX, futex) \
O(SYS_GETGROUPS, getgroups) \
O(SYS_SETGROUPS, setgroups) \
O(SYS_CHROOT, chroot) \
enum Syscall
{

View File

@ -596,7 +596,6 @@ int unlinkat(int fd, const char* path, int flag);
int usleep(useconds_t usec);
ssize_t write(int fildes, const void* buf, size_t nbyte);
int chroot(const char* path);
int getpagesize(void);
char* getpass(const char* prompt);

View File

@ -626,10 +626,6 @@ int getopt(int argc, char* const argv[], const char* optstring)
return '?';
}
int chroot(const char* path)
return syscall(SYS_CHROOT, path);
}
int getpagesize(void)
{
return PAGE_SIZE;
@ -677,7 +673,8 @@ error:
int getgroups(int gidsetsize, gid_t grouplist[])
{
return syscall(SYS_GETGROUPS, grouplist, gidsetsize);
dwarnln("FIXME: getgroups({}, {})", gidsetsize, grouplist);
return 0;
}
pid_t getppid(void)

View File

@ -31,8 +31,7 @@ namespace LibFont
#if __is_kernel
{
// FIXME: This does not account for chroot
auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, O_RDONLY)).inode;
auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, O_RDONLY)).inode;
TRY(file_data.resize(inode->size()));
TRY(inode->read(0, BAN::ByteSpan(file_data.span())));
}

View File

@ -128,8 +128,7 @@ namespace LibInput
#if __is_kernel
{
// FIXME: This does not account for chroot
auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, 0));
auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, 0));
TRY(file_data.resize(file.inode->size()));
TRY(file.inode->read(0, BAN::ByteSpan { reinterpret_cast<uint8_t*>(file_data.data()), file_data.size() }));
canonical_path = file.canonical_path;

View File

@ -3,7 +3,6 @@
#include <BAN/Vector.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
@ -42,12 +41,6 @@ int main(int argc, char** argv)
exit(1);
}
if (fork() == 0)
{
execl("/bin/AudioServer", "AudioServer", NULL);
exit(1);
}
bool first = true;
termios termios;
@ -101,8 +94,6 @@ int main(int argc, char** argv)
printf("Welcome back %s!\n", pwd->pw_name);
if (initgroups(name_buffer, pwd->pw_gid) == -1)
perror("initgroups");
if (setgid(pwd->pw_gid) == -1)
perror("setgid");
if (setuid(pwd->pw_uid) == -1)

View File

@ -442,7 +442,6 @@ int main(int, char**)
.sin_family = AF_INET,
.sin_port = 0,
.sin_addr = { .s_addr = resolved->raw },
.sin_zero = {},
};
if (send(client.socket, &addr, sizeof(addr), 0) == -1)
@ -490,7 +489,6 @@ int main(int, char**)
.sin_family = AF_INET,
.sin_port = 0,
.sin_addr = { .s_addr = result->raw },
.sin_zero = {},
};
if (send(client.socket, &addr, sizeof(addr), 0) == -1)