Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ CXX_SOURCES += $(shell find smp -name '*.cpp' 2>/dev/null | sort)
CXX_SOURCES += $(shell find rc -name '*.cpp' 2>/dev/null | sort)
CXX_SOURCES += $(shell find fs -name '*.cpp' 2>/dev/null | sort)
CXX_SOURCES += $(shell find resource -name '*.cpp' 2>/dev/null | sort)
CXX_SOURCES += $(shell find socket -name '*.cpp' 2>/dev/null | sort)
CXX_SOURCES += $(shell find arch/$(ARCH) -name '*.cpp' 2>/dev/null | sort)

# Unit test sources (only when STLX_UNIT_TESTS_ENABLED=1)
Expand Down
7 changes: 7 additions & 0 deletions kernel/arch/aarch64/syscall/linux_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ constexpr uint64_t MPROTECT = 226;
constexpr uint64_t EXIT = 93;
constexpr uint64_t EXIT_GROUP = 94;
constexpr uint64_t SET_TID_ADDRESS = 96;
constexpr uint64_t SOCKET = 198;
constexpr uint64_t SOCKETPAIR = 199;
constexpr uint64_t BIND = 200;
constexpr uint64_t LISTEN = 201;
constexpr uint64_t ACCEPT = 202;
constexpr uint64_t CONNECT = 203;
constexpr uint64_t FCNTL = 25;

} // namespace syscall::linux_nr

Expand Down
7 changes: 7 additions & 0 deletions kernel/arch/x86_64/syscall/linux_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ constexpr uint64_t EXIT = 60;
constexpr uint64_t ARCH_PRCTL = 158;
constexpr uint64_t SET_TID_ADDRESS = 218;
constexpr uint64_t EXIT_GROUP = 231;
constexpr uint64_t SOCKET = 41;
constexpr uint64_t CONNECT = 42;
constexpr uint64_t ACCEPT = 43;
constexpr uint64_t BIND = 49;
constexpr uint64_t LISTEN = 50;
constexpr uint64_t SOCKETPAIR = 53;
constexpr uint64_t FCNTL = 72;

} // namespace syscall::linux_nr

Expand Down
14 changes: 9 additions & 5 deletions kernel/common/string.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
#include "string.h"

extern "C" void* memset(void* dest, int c, size_t n) {
auto* d = static_cast<uint8_t*>(dest);
for (size_t i = 0; i < n; ++i) {
d[i] = static_cast<uint8_t>(c);
}
return dest;
}

namespace string {

size_t strlen(const char* s) {
Expand All @@ -20,11 +28,7 @@ void* memcpy(void* dest, const void* src, size_t n) {
}

void* memset(void* dest, int c, size_t n) {
auto* d = static_cast<uint8_t*>(dest);
for (size_t i = 0; i < n; ++i) {
d[i] = static_cast<uint8_t>(c);
}
return dest;
return ::memset(dest, c, n);
}

int memcmp(const void* s1, const void* s2, size_t n) {
Expand Down
9 changes: 9 additions & 0 deletions kernel/fs/fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ int32_t node::ioctl(file*, uint32_t, uint64_t) { return ERR_NOSYS; }
int32_t node::open(file*, uint32_t) { return OK; }
int32_t node::on_close(file*) { return OK; }
int32_t node::readlink(char*, size_t, size_t*) { return ERR_NOSYS; }
int32_t node::create_socket(const char*, size_t, void*, node**) { return ERR_NOSYS; }

int32_t node::getattr(vattr* attr) {
if (!attr) return ERR_INVAL;
Expand Down Expand Up @@ -245,6 +246,14 @@ __PRIVILEGED_CODE int32_t lookup(const char* path, node** out) {
return resolve_path(path, out);
}

__PRIVILEGED_CODE int32_t resolve_parent_path(
const char* path, node** out_parent,
const char** out_name, size_t* out_name_len
) {
if (!path || !out_parent || !out_name || !out_name_len) return ERR_INVAL;
return resolve_parent(path, out_parent, out_name, out_name_len);
}


__PRIVILEGED_CODE int32_t mount(const char* source, const char* target,
const char* fs_name, uint32_t flags) {
Expand Down
10 changes: 10 additions & 0 deletions kernel/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ ssize_t readdir(file* f, dirent* entries, size_t count);
*/
__PRIVILEGED_CODE int32_t lookup(const char* path, node** out);

/**
* @brief Resolve the parent directory of a path and extract the final component.
* On success, *out_parent has add_ref() called; caller must release.
* @note Privilege: **required**
*/
__PRIVILEGED_CODE int32_t resolve_parent_path(
const char* path, node** out_parent,
const char** out_name, size_t* out_name_len
);

} // namespace fs

#endif // STELLUX_FS_FS_H
6 changes: 4 additions & 2 deletions kernel/fs/fstypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ enum class node_type : uint32_t {
directory,
symlink,
char_device,
block_device
block_device,
socket
};

constexpr size_t NAME_MAX = 255;
Expand All @@ -22,7 +23,8 @@ constexpr uint32_t O_WRONLY = 1;
constexpr uint32_t O_RDWR = 2;
constexpr uint32_t O_CREAT = 0x40;
constexpr uint32_t O_TRUNC = 0x200;
constexpr uint32_t O_APPEND = 0x400;
constexpr uint32_t O_APPEND = 0x400;
constexpr uint32_t O_NONBLOCK = 0x800;

constexpr uint32_t ACCESS_MODE_MASK = 0x3;

Expand Down
3 changes: 3 additions & 0 deletions kernel/fs/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class node : public rc::ref_counted<node> {
// --- Symlink ---
virtual int32_t readlink(char* buf, size_t size, size_t* out_len);

// --- Socket node creation (directory nodes may override) ---
virtual int32_t create_socket(const char* name, size_t len, void* impl, node** out);

/**
* ref_counted contract. Destroys the node and frees privileged memory.
* @note Privilege: **required**
Expand Down
31 changes: 31 additions & 0 deletions kernel/fs/ramfs/ramfs.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "fs/ramfs/ramfs.h"
#include "fs/socket_node.h"
#include "fs/fs.h"
#include "common/string.h"
#include "mm/heap.h"
Expand Down Expand Up @@ -145,6 +146,36 @@ int32_t dir_node::create(const char* name, size_t len, uint32_t mode, fs::node**
return fs::OK;
}

int32_t dir_node::create_socket(const char* name, size_t len, void* impl, fs::node** out) {
(void)impl;
if (!name || !out || len == 0) return fs::ERR_INVAL;
if (len > fs::NAME_MAX) return fs::ERR_NAMETOOLONG;

sync::irq_lock_guard guard(m_lock);

if (find_child(name, len)) {
return fs::ERR_EXIST;
}

char name_buf[fs::NAME_MAX + 1];
string::memcpy(name_buf, name, len);
name_buf[len] = '\0';

void* mem = heap::kzalloc(sizeof(fs::socket_node));
if (!mem) {
return fs::ERR_NOMEM;
}
auto* child = new (mem) fs::socket_node(m_fs, name_buf);

child->set_parent(this);
m_children.push_back(child);
m_child_count++;

child->add_ref();
*out = child;
return fs::OK;
}

int32_t dir_node::mkdir(const char* name, size_t len, uint32_t mode, fs::node** out) {
if (!name || !out || len == 0) return fs::ERR_INVAL;
if (len > fs::NAME_MAX) return fs::ERR_NAMETOOLONG;
Expand Down
1 change: 1 addition & 0 deletions kernel/fs/ramfs/ramfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class dir_node : public fs::node {
int32_t rmdir(const char* name, size_t len) override;
ssize_t readdir(fs::file* f, fs::dirent* entries, size_t count) override;
int32_t getattr(fs::vattr* attr) override;
int32_t create_socket(const char* name, size_t len, void* impl, fs::node** out) override;

private:
fs::node* find_child(const char* name, size_t len);
Expand Down
23 changes: 23 additions & 0 deletions kernel/fs/socket_node.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "fs/socket_node.h"
#include "fs/fs.h"
#include "socket/listener.h"

namespace fs {

socket_node::socket_node(instance* fs, const char* name)
: node(node_type::socket, fs, name) {}

int32_t socket_node::getattr(vattr* attr) {
if (!attr) {
return fs::ERR_INVAL;
}
attr->type = node_type::socket;
attr->size = 0;
return fs::OK;
}

void socket_node::set_listener(rc::strong_ref<socket::listener_state> ls) {
m_listener = static_cast<rc::strong_ref<socket::listener_state>&&>(ls);
}

} // namespace fs
26 changes: 26 additions & 0 deletions kernel/fs/socket_node.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef STELLUX_FS_SOCKET_NODE_H
#define STELLUX_FS_SOCKET_NODE_H

#include "fs/node.h"
#include "rc/strong_ref.h"

namespace socket { struct listener_state; }

namespace fs {

class socket_node : public node {
public:
socket_node(instance* fs, const char* name);

int32_t getattr(vattr* attr) override;

socket::listener_state* get_listener() const { return m_listener.ptr(); }
void set_listener(rc::strong_ref<socket::listener_state> ls);

private:
rc::strong_ref<socket::listener_state> m_listener;
};

} // namespace fs

#endif // STELLUX_FS_SOCKET_NODE_H
61 changes: 58 additions & 3 deletions kernel/resource/handle_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ __PRIVILEGED_CODE void init_handle_table(handle_table* table) {
for (uint32_t i = 0; i < MAX_TASK_HANDLES; i++) {
table->entries[i].used = false;
table->entries[i].generation = 0;
table->entries[i].reserved = 0;
table->entries[i].flags = 0;
table->entries[i].rights = 0;
table->entries[i].type = resource_type::UNKNOWN;
table->entries[i].obj = nullptr;
Expand Down Expand Up @@ -52,6 +52,7 @@ __PRIVILEGED_CODE int32_t alloc_handle(
resource_add_ref(obj);
entry.used = true;
entry.generation++;
entry.flags = 0;
entry.rights = rights;
entry.type = type;
entry.obj = obj;
Expand All @@ -70,7 +71,8 @@ __PRIVILEGED_CODE int32_t get_handle_object(
handle_table* table,
handle_t handle,
uint32_t required_rights,
resource_object** out_obj
resource_object** out_obj,
uint32_t* out_flags
) {
if (!table || !out_obj) {
return HANDLE_ERR_INVAL;
Expand All @@ -93,6 +95,59 @@ __PRIVILEGED_CODE int32_t get_handle_object(

resource_add_ref(entry.obj);
*out_obj = entry.obj;
if (out_flags) {
*out_flags = entry.flags;
}
return HANDLE_OK;
}

/**
* @note Privilege: **required**
*/
__PRIVILEGED_CODE int32_t get_handle_flags(
handle_table* table,
handle_t handle,
uint32_t* out_flags
) {
if (!table || !out_flags) {
return HANDLE_ERR_INVAL;
}
if (handle < 0 || static_cast<uint32_t>(handle) >= MAX_TASK_HANDLES) {
return HANDLE_ERR_NOENT;
}

sync::irq_lock_guard guard(table->lock);
handle_entry& entry = table->entries[static_cast<uint32_t>(handle)];
if (!entry.used) {
return HANDLE_ERR_NOENT;
}

*out_flags = entry.flags;
return HANDLE_OK;
}

/**
* @note Privilege: **required**
*/
__PRIVILEGED_CODE int32_t set_handle_flags(
handle_table* table,
handle_t handle,
uint32_t flags
) {
if (!table) {
return HANDLE_ERR_INVAL;
}
if (handle < 0 || static_cast<uint32_t>(handle) >= MAX_TASK_HANDLES) {
return HANDLE_ERR_NOENT;
}

sync::irq_lock_guard guard(table->lock);
handle_entry& entry = table->entries[static_cast<uint32_t>(handle)];
if (!entry.used) {
return HANDLE_ERR_NOENT;
}

entry.flags = flags;
return HANDLE_OK;
}

Expand Down Expand Up @@ -122,7 +177,7 @@ __PRIVILEGED_CODE int32_t remove_handle(
entry.rights = 0;
entry.type = resource_type::UNKNOWN;
entry.obj = nullptr;
entry.reserved = 0;
entry.flags = 0;

*out_obj = obj;
return HANDLE_OK;
Expand Down
25 changes: 23 additions & 2 deletions kernel/resource/handle_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ constexpr uint32_t MAX_TASK_HANDLES = 128;
struct handle_entry {
bool used;
uint16_t generation;
uint16_t reserved;
uint32_t flags;
uint32_t rights;
resource_type type;
resource_object* obj;
Expand Down Expand Up @@ -58,7 +58,28 @@ __PRIVILEGED_CODE int32_t get_handle_object(
handle_table* table,
handle_t handle,
uint32_t required_rights,
resource_object** out_obj
resource_object** out_obj,
uint32_t* out_flags = nullptr
);

/**
* @brief Get per-handle flags (O_NONBLOCK, etc.).
* @note Privilege: **required**
*/
__PRIVILEGED_CODE int32_t get_handle_flags(
handle_table* table,
handle_t handle,
uint32_t* out_flags
);

/**
* @brief Set per-handle flags (O_NONBLOCK, etc.).
* @note Privilege: **required**
*/
__PRIVILEGED_CODE int32_t set_handle_flags(
handle_table* table,
handle_t handle,
uint32_t flags
);

/**
Expand Down
6 changes: 4 additions & 2 deletions kernel/resource/providers/file_provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ __PRIVILEGED_CODE static int32_t map_fs_error_to_resource(int32_t fs_err) {
}
}

__PRIVILEGED_CODE static ssize_t file_read(resource_object* obj, void* kdst, size_t count) {
__PRIVILEGED_CODE static ssize_t file_read(resource_object* obj, void* kdst, size_t count, uint32_t flags) {
(void)flags;
if (!obj || !obj->impl || !kdst) {
return ERR_INVAL;
}
Expand All @@ -42,7 +43,8 @@ __PRIVILEGED_CODE static ssize_t file_read(resource_object* obj, void* kdst, siz
return rc;
}

__PRIVILEGED_CODE static ssize_t file_write(resource_object* obj, const void* ksrc, size_t count) {
__PRIVILEGED_CODE static ssize_t file_write(resource_object* obj, const void* ksrc, size_t count, uint32_t flags) {
(void)flags;
if (!obj || !obj->impl || !ksrc) {
return ERR_INVAL;
}
Expand Down
Loading