summaryrefslogtreecommitdiff
path: root/src/fs
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2025-07-07 13:22:53 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2025-07-25 14:16:41 +0200
commit14f60e4fd65c42f126eaee7e09cb4251c167c6ed (patch)
tree313b5e16d7d99cf1518c953e2efe5e5fc920dfbf /src/fs
parent48a61c16eaa6dcfc75d00dba302537ce1492db98 (diff)
wiptty
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/CMakeLists.txt24
-rw-r--r--src/fs/devfs/CMakeLists.txt20
-rw-r--r--src/fs/devfs/include/devfs.h24
-rw-r--r--src/fs/devfs/private_include/devfs/ops.h48
-rw-r--r--src/fs/devfs/private_include/devfs/types.h44
-rw-r--r--src/fs/devfs/src/CMakeLists.txt34
-rw-r--r--src/fs/devfs/src/close.c26
-rw-r--r--src/fs/devfs/src/flags.c25
-rw-r--r--src/fs/devfs/src/mkdir.c28
-rw-r--r--src/fs/devfs/src/mknod.c54
-rw-r--r--src/fs/devfs/src/mount.c59
-rw-r--r--src/fs/devfs/src/open.c57
-rw-r--r--src/fs/devfs/src/ops.c32
-rw-r--r--src/fs/devfs/src/read.c95
-rw-r--r--src/fs/devfs/src/register.c44
-rw-r--r--src/fs/devfs/src/search.c29
-rw-r--r--src/fs/devfs/src/seek.c98
-rw-r--r--src/fs/devfs/src/stat.c30
-rw-r--r--src/fs/devfs/src/status.c30
-rw-r--r--src/fs/devfs/src/unlink.c26
-rw-r--r--src/fs/devfs/src/update.c27
-rw-r--r--src/fs/devfs/src/write.c95
-rw-r--r--src/fs/include/fs/fs.h159
-rw-r--r--src/fs/include/fs/inode.h79
-rw-r--r--src/fs/iso9660/CMakeLists.txt20
-rw-r--r--src/fs/iso9660/include/iso9660.h24
-rw-r--r--src/fs/iso9660/private_include/iso9660/ops.h39
-rw-r--r--src/fs/iso9660/private_include/iso9660/types.h34
-rw-r--r--src/fs/iso9660/src/CMakeLists.txt28
-rw-r--r--src/fs/iso9660/src/close.c26
-rw-r--r--src/fs/iso9660/src/mkdir.c28
-rw-r--r--src/fs/iso9660/src/mount.c196
-rw-r--r--src/fs/iso9660/src/open.c27
-rw-r--r--src/fs/iso9660/src/read.c27
-rw-r--r--src/fs/iso9660/src/register.c44
-rw-r--r--src/fs/iso9660/src/search.c27
-rw-r--r--src/fs/iso9660/src/seek.c27
-rw-r--r--src/fs/iso9660/src/stat.c28
-rw-r--r--src/fs/iso9660/src/write.c28
-rw-r--r--src/fs/private_include/fs/private.h63
-rw-r--r--src/fs/private_include/fs/types.h55
-rw-r--r--src/fs/ramfs/CMakeLists.txt20
-rw-r--r--src/fs/ramfs/include/ramfs.h43
-rw-r--r--src/fs/ramfs/private_include/ramfs/types.h31
-rw-r--r--src/fs/ramfs/src/CMakeLists.txt29
-rw-r--r--src/fs/ramfs/src/close.c25
-rw-r--r--src/fs/ramfs/src/flags.c25
-rw-r--r--src/fs/ramfs/src/free.c31
-rw-r--r--src/fs/ramfs/src/mkdir.c79
-rw-r--r--src/fs/ramfs/src/mknod.c87
-rw-r--r--src/fs/ramfs/src/mount.c69
-rw-r--r--src/fs/ramfs/src/open.c26
-rw-r--r--src/fs/ramfs/src/read.c26
-rw-r--r--src/fs/ramfs/src/search.c150
-rw-r--r--src/fs/ramfs/src/stat.c52
-rw-r--r--src/fs/ramfs/src/write.c26
-rw-r--r--src/fs/rootfs/CMakeLists.txt20
-rw-r--r--src/fs/rootfs/include/rootfs.h24
-rw-r--r--src/fs/rootfs/private_include/rootfs/ops.h42
-rw-r--r--src/fs/rootfs/private_include/rootfs/types.h32
-rw-r--r--src/fs/rootfs/src/CMakeLists.txt28
-rw-r--r--src/fs/rootfs/src/close.c25
-rw-r--r--src/fs/rootfs/src/flags.c26
-rw-r--r--src/fs/rootfs/src/mkdir.c30
-rw-r--r--src/fs/rootfs/src/mount.c42
-rw-r--r--src/fs/rootfs/src/open.c27
-rw-r--r--src/fs/rootfs/src/read.c26
-rw-r--r--src/fs/rootfs/src/register.c43
-rw-r--r--src/fs/rootfs/src/search.c29
-rw-r--r--src/fs/rootfs/src/stat.c28
-rw-r--r--src/fs/rootfs/src/write.c26
-rw-r--r--src/fs/src/CMakeLists.txt30
-rw-r--r--src/fs/src/from_type.c36
-rw-r--r--src/fs/src/headtail.c22
-rw-r--r--src/fs/src/inode/CMakeLists.txt20
-rw-r--r--src/fs/src/inode/free.c31
-rw-r--r--src/fs/src/inode/search.c121
-rw-r--r--src/fs/src/mountpoint.c60
-rw-r--r--src/fs/src/mp_from_path.c40
-rw-r--r--src/fs/src/mps_from_path.c89
-rw-r--r--src/fs/src/next.c59
-rw-r--r--src/fs/src/parent.c33
-rw-r--r--src/fs/src/register.c42
-rw-r--r--src/fs/src/relpath.c43
-rw-r--r--src/fs/src/update.c30
85 files changed, 3731 insertions, 0 deletions
diff --git a/src/fs/CMakeLists.txt b/src/fs/CMakeLists.txt
new file mode 100644
index 0000000..d08b64e
--- /dev/null
+++ b/src/fs/CMakeLists.txt
@@ -0,0 +1,24 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+add_library(fs)
+add_subdirectory(src)
+target_include_directories(fs PUBLIC include PRIVATE private_include)
+target_link_libraries(fs PUBLIC state)
+add_subdirectory(devfs)
+add_subdirectory(iso9660)
+add_subdirectory(ramfs)
+add_subdirectory(rootfs)
diff --git a/src/fs/devfs/CMakeLists.txt b/src/fs/devfs/CMakeLists.txt
new file mode 100644
index 0000000..7305bdf
--- /dev/null
+++ b/src/fs/devfs/CMakeLists.txt
@@ -0,0 +1,20 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+add_library(devfs)
+add_subdirectory(src)
+target_include_directories(devfs PUBLIC include PRIVATE private_include)
+target_link_libraries(devfs PUBLIC state c PRIVATE fs drv ramfs)
diff --git a/src/fs/devfs/include/devfs.h b/src/fs/devfs/include/devfs.h
new file mode 100644
index 0000000..d9634fc
--- /dev/null
+++ b/src/fs/devfs/include/devfs.h
@@ -0,0 +1,24 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef DEVFS_H
+#define DEVFS_H
+
+int devfs_register(void);
+
+#endif
diff --git a/src/fs/devfs/private_include/devfs/ops.h b/src/fs/devfs/private_include/devfs/ops.h
new file mode 100644
index 0000000..f7c4e5b
--- /dev/null
+++ b/src/fs/devfs/private_include/devfs/ops.h
@@ -0,0 +1,48 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef DEVFS_OPS_H
+#define DEVFS_OPS_H
+
+#include <fs/fs.h>
+#include <drv/event.h>
+#include <stdbool.h>
+
+int devfs_mount(const struct fs_mount *m, struct fs_ret *r);
+int devfs_mkdir(const struct fs_mkdir *m, const struct fs_mp *mp,
+ const union inode_result *i, struct fs_ret *r);
+int devfs_open(const struct fs_open *o, const struct fs_mp *mp,
+ const union inode_result *i, struct fs_ret *r);
+int devfs_read(const struct fs_read *r, struct fs_ret *ret);
+int devfs_write(const struct fs_write *w, struct fs_ret *r);
+int devfs_stat(const struct fs_stat *s, const struct fs_mp *mp,
+ const union inode_result *i, struct fs_ret *r);
+int devfs_close(const struct fs_close *c, struct fs_ret *r);
+int devfs_seek(const struct fs_seek *s, struct fs_ret *r);
+int devfs_search(const char *path, const struct fs_mp *mp,
+ union inode_result *inode, struct fs_ret *r);
+int devfs_status(const char *node, const struct drv_event_ops *const ops,
+ bool available, void *args);
+int devfs_flags(const union inode_result *i);
+int devfs_update(struct fs_mp_prv *pr);
+int devfs_mknod(const char *path, mode_t mode, dev_t dev,
+ const struct drv_event_ops *const ops, struct fs_mp_prv *mp);
+int devfs_unlink(const char *path, struct fs_mp_prv *mp);
+const struct devfs_ops *devfs_ops(const struct fs_mp_prv *pr, const char *node);
+
+#endif
diff --git a/src/fs/devfs/private_include/devfs/types.h b/src/fs/devfs/private_include/devfs/types.h
new file mode 100644
index 0000000..698ccac
--- /dev/null
+++ b/src/fs/devfs/private_include/devfs/types.h
@@ -0,0 +1,44 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef DEVFS_TYPES_H
+#define DEVFS_TYPES_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <drv/drv.h>
+#include <drv/event.h>
+#include <ramfs.h>
+
+struct devfs_ops
+{
+ char *node;
+ struct drv_event_ops ops;
+ struct devfs_ops *prev, *next;
+};
+
+struct fs_mp_prv
+{
+ struct ramfs *rfs;
+ struct drv *drv;
+ struct devfs_ops *head, *tail;
+};
+
+extern const struct fs devfs;
+
+#endif
diff --git a/src/fs/devfs/src/CMakeLists.txt b/src/fs/devfs/src/CMakeLists.txt
new file mode 100644
index 0000000..7db8c9f
--- /dev/null
+++ b/src/fs/devfs/src/CMakeLists.txt
@@ -0,0 +1,34 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(devfs PRIVATE
+ close.c
+ flags.c
+ mount.c
+ mkdir.c
+ mknod.c
+ open.c
+ ops.c
+ stat.c
+ read.c
+ register.c
+ search.c
+ seek.c
+ status.c
+ unlink.c
+ update.c
+ write.c
+)
diff --git a/src/fs/devfs/src/close.c b/src/fs/devfs/src/close.c
new file mode 100644
index 0000000..0277b96
--- /dev/null
+++ b/src/fs/devfs/src/close.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <fs/fs.h>
+
+int devfs_close(const struct fs_close *const c, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/devfs/src/flags.c b/src/fs/devfs/src/flags.c
new file mode 100644
index 0000000..b99bb8c
--- /dev/null
+++ b/src/fs/devfs/src/flags.c
@@ -0,0 +1,25 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+
+int devfs_flags(const union inode_result *const i)
+{
+ return i->memi->flags;
+}
diff --git a/src/fs/devfs/src/mkdir.c b/src/fs/devfs/src/mkdir.c
new file mode 100644
index 0000000..9aa74b3
--- /dev/null
+++ b/src/fs/devfs/src/mkdir.c
@@ -0,0 +1,28 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <fs/fs.h>
+#include <fs/inode.h>
+
+int devfs_mkdir(const struct fs_mkdir *m, const struct fs_mp *const mp,
+ const union inode_result *const i, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/devfs/src/mknod.c b/src/fs/devfs/src/mknod.c
new file mode 100644
index 0000000..8d13075
--- /dev/null
+++ b/src/fs/devfs/src/mknod.c
@@ -0,0 +1,54 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <fs/inode.h>
+#include <ramfs.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+int devfs_mknod(const char *const node, const mode_t mode, const dev_t dev,
+ const struct drv_event_ops *const ops, struct fs_mp_prv *const pr)
+{
+ struct devfs_ops *dops = NULL;
+ char *const nodedup = strdup(node);
+
+ if (!nodedup
+ || !(dops = malloc(sizeof *dops))
+ || ramfs_mknod(node, mode, dev, pr->rfs))
+ goto failure;
+
+ *dops = (const struct devfs_ops){.node = nodedup, .ops = *ops};
+
+ if (!pr->head)
+ pr->head = dops;
+ else
+ {
+ dops->prev = pr->tail;
+ pr->tail->next = dops;
+ }
+
+ pr->tail = dops;
+ return 0;
+
+failure:
+ free(dops);
+ return -1;
+}
diff --git a/src/fs/devfs/src/mount.c b/src/fs/devfs/src/mount.c
new file mode 100644
index 0000000..cff4779
--- /dev/null
+++ b/src/fs/devfs/src/mount.c
@@ -0,0 +1,59 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <drv/drv.h>
+#include <fs/fs.h>
+#include <ramfs.h>
+#include <stdlib.h>
+
+int devfs_mount(const struct fs_mount *const m, struct fs_ret *const r)
+{
+ struct drv *drv = NULL;
+ struct fs_mp_prv *p = NULL;
+ struct ramfs *const rfs = ramfs_mount(m, r);
+
+ if (!rfs || !(p = malloc(sizeof *p)))
+ goto failure;
+
+ const struct drv_event ev =
+ {
+ .status = devfs_status,
+ .args = p
+ };
+
+ if (!(drv = drv_init(&ev))
+ || fs_mountpoint(m->src, m->tgt, &devfs, devfs_update, p))
+ goto failure;
+
+ *p = (const struct fs_mp_prv)
+ {
+ .drv = drv,
+ .rfs = rfs
+ };
+
+ return 0;
+
+failure:
+ drv_free(drv);
+ free(p);
+ ramfs_free(rfs);
+ return -1;
+}
diff --git a/src/fs/devfs/src/open.c b/src/fs/devfs/src/open.c
new file mode 100644
index 0000000..b9bd3f7
--- /dev/null
+++ b/src/fs/devfs/src/open.c
@@ -0,0 +1,57 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/types.h>
+#include <devfs/ops.h>
+#include <fs/fs.h>
+#include <state.h>
+#include <stdlib.h>
+
+struct open
+{
+ struct fs_ret *pr, r;
+};
+
+static enum state done(void *const args)
+{
+ struct open *const op = args;
+
+ *op->pr = op->r;
+ free(op);
+ return STATE_AGAIN;
+}
+
+int devfs_open(const struct fs_open *const o, const struct fs_mp *const mp,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ struct open *const op = malloc(sizeof *op);
+
+ if (!op)
+ return -1;
+
+ *op = (const struct open){.pr = r, .r = *r};
+ *o->fd = (const struct fs_fd)
+ {
+ .inode = *inode,
+ .mp = mp
+ };
+
+ *r = (const struct fs_ret){.f = done, .args = op};
+ return 0;
+}
diff --git a/src/fs/devfs/src/ops.c b/src/fs/devfs/src/ops.c
new file mode 100644
index 0000000..1cd4a15
--- /dev/null
+++ b/src/fs/devfs/src/ops.c
@@ -0,0 +1,32 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <string.h>
+
+const struct devfs_ops *devfs_ops(const struct fs_mp_prv *const pr,
+ const char *const node)
+{
+ for (struct devfs_ops *o = pr->head; o; o = o->next)
+ if (!strcmp(o->node, node))
+ return o;
+
+ return NULL;
+}
diff --git a/src/fs/devfs/src/read.c b/src/fs/devfs/src/read.c
new file mode 100644
index 0000000..0bc19f0
--- /dev/null
+++ b/src/fs/devfs/src/read.c
@@ -0,0 +1,95 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <fs/fs.h>
+#include <state.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+struct read
+{
+ bool done;
+ struct fs_fd *fd;
+ struct fs_ret *pr, r;
+};
+
+static int done(const int error, void *const args)
+{
+ struct read *const re = args;
+
+ re->done = true;
+ return 0;
+}
+
+static enum state wait(void *const args)
+{
+ struct read *const re = args;
+
+ if (!re->done)
+ return STATE_AGAIN;
+
+ *re->pr = re->r;
+ free(re);
+ return STATE_AGAIN;
+}
+
+int devfs_read(const struct fs_read *const fr, struct fs_ret *const r)
+{
+ struct fs_fd *const fd = fr->fd;
+ const struct fs_mp *const mp = fd->mp;
+ const struct inode *const inode = fd->inode.memi;
+ const struct devfs_ops *const o = devfs_ops(mp->prv, inode->name);
+ struct read *const re = malloc(sizeof *re);
+
+ if (!re)
+ goto failure;
+ else if (!o)
+ {
+ errno = ENOENT;
+ goto failure;
+ }
+
+ *re = (const struct read)
+ {
+ .fd = fd,
+ .pr = r,
+ .r = *r
+ };
+
+ const struct drv_event_done d =
+ {
+ .f = done,
+ .args = re
+ };
+
+ const struct drv_event_ops *const ops = &o->ops;
+
+ if (ops->read(fr->buf, fr->n, &d, ops->args))
+ goto failure;
+
+ *r = (const struct fs_ret){.f = wait, .args = re};
+ return 0;
+
+failure:
+ free(re);
+ return -1;
+}
diff --git a/src/fs/devfs/src/register.c b/src/fs/devfs/src/register.c
new file mode 100644
index 0000000..46dcdb6
--- /dev/null
+++ b/src/fs/devfs/src/register.c
@@ -0,0 +1,44 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <fs/fs.h>
+
+const struct fs devfs =
+{
+ .type = "devfs",
+ .mount = devfs_mount,
+ .stat = devfs_stat,
+ .mkdir = devfs_mkdir,
+ .open = devfs_open,
+ .read = devfs_read,
+ .write = devfs_write,
+ .close = devfs_close,
+ .seek = devfs_seek,
+ .iops =
+ {
+ .search = devfs_search,
+ .flags = devfs_flags
+ }
+};
+
+int devfs_register(void)
+{
+ return fs_register(&devfs);
+}
diff --git a/src/fs/devfs/src/search.c b/src/fs/devfs/src/search.c
new file mode 100644
index 0000000..22a4e92
--- /dev/null
+++ b/src/fs/devfs/src/search.c
@@ -0,0 +1,29 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <fs/fs.h>
+#include <ramfs.h>
+
+int devfs_search(const char *const path, const struct fs_mp *const mp,
+ union inode_result *const inode, struct fs_ret *const r)
+{
+ return ramfs_search(path, mp->prv->rfs, inode, r);
+}
diff --git a/src/fs/devfs/src/seek.c b/src/fs/devfs/src/seek.c
new file mode 100644
index 0000000..d955e70
--- /dev/null
+++ b/src/fs/devfs/src/seek.c
@@ -0,0 +1,98 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <fs/fs.h>
+#include <state.h>
+#include <errno.h>
+#include <stdlib.h>
+
+struct seek
+{
+ bool done;
+ struct fs_fd *fd;
+ struct fs_ret *pr, r;
+};
+
+static int done(int error, void *const args)
+{
+ struct seek *const s = args;
+ struct fs_fd *const fd = s->fd;
+
+ if (error)
+ fd->error = error;
+
+ s->done = true;
+ return 0;
+}
+
+static enum state wait(void *const args)
+{
+ struct seek *const s = args;
+
+ if (!s->done)
+ return STATE_AGAIN;
+
+ *s->pr = s->r;
+ free(s);
+ return STATE_AGAIN;
+}
+
+int devfs_seek(const struct fs_seek *const fs, struct fs_ret *const r)
+{
+ struct fs_fd *const fd = fs->fd;
+ const struct fs_mp *const mp = fd->mp;
+ const struct inode *const inode = fd->inode.memi;
+ const struct devfs_ops *const o = devfs_ops(mp->prv, inode->name);
+ struct seek *const s = malloc(sizeof *s);
+
+ if (!s)
+ goto failure;
+ else if (!o)
+ {
+ errno = ENOENT;
+ goto failure;
+ }
+
+ *s = (const struct seek)
+ {
+ .fd = fd,
+ .pr = r,
+ .r = *r
+ };
+
+ const struct drv_event_done d =
+ {
+ .f = done,
+ .args = s
+ };
+
+ const struct drv_event_ops *const ops = &o->ops;
+
+ if (ops->seek(fs->offset, &d, fd))
+ goto failure;
+
+ *r = (const struct fs_ret){.f = wait, .args = s};
+ return 0;
+
+failure:
+ free(s);
+ return -1;
+}
diff --git a/src/fs/devfs/src/stat.c b/src/fs/devfs/src/stat.c
new file mode 100644
index 0000000..dff4d3c
--- /dev/null
+++ b/src/fs/devfs/src/stat.c
@@ -0,0 +1,30 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <ramfs.h>
+
+int devfs_stat(const struct fs_stat *const s, const struct fs_mp *const mp,
+ const union inode_result *const i, struct fs_ret *const r)
+{
+ return ramfs_stat(s, mp->prv->rfs, i, r);
+}
diff --git a/src/fs/devfs/src/status.c b/src/fs/devfs/src/status.c
new file mode 100644
index 0000000..8a4d1e1
--- /dev/null
+++ b/src/fs/devfs/src/status.c
@@ -0,0 +1,30 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs/ops.h>
+#include <drv/event.h>
+#include <stdbool.h>
+
+int devfs_status(const char *const node, const struct drv_event_ops *const ops,
+ const bool available, void *const args)
+{
+ struct fs_mp_prv *const mp = args;
+
+ return available ? devfs_mknod(node, 0755, 0, ops, mp)
+ : devfs_unlink(node, mp);
+}
diff --git a/src/fs/devfs/src/unlink.c b/src/fs/devfs/src/unlink.c
new file mode 100644
index 0000000..d03fd68
--- /dev/null
+++ b/src/fs/devfs/src/unlink.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs/ops.h>
+#include <sys/types.h>
+#include <errno.h>
+
+int devfs_unlink(const char *const node, struct fs_mp_prv *const mp)
+{
+ return -1;
+}
diff --git a/src/fs/devfs/src/update.c b/src/fs/devfs/src/update.c
new file mode 100644
index 0000000..2a0a879
--- /dev/null
+++ b/src/fs/devfs/src/update.c
@@ -0,0 +1,27 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/types.h>
+#include <devfs/ops.h>
+#include <drv/drv.h>
+
+int devfs_update(struct fs_mp_prv *const pr)
+{
+ return drv_update(pr->drv);
+}
diff --git a/src/fs/devfs/src/write.c b/src/fs/devfs/src/write.c
new file mode 100644
index 0000000..759751e
--- /dev/null
+++ b/src/fs/devfs/src/write.c
@@ -0,0 +1,95 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <devfs.h>
+#include <devfs/ops.h>
+#include <devfs/types.h>
+#include <fs/fs.h>
+#include <state.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+struct write
+{
+ bool done;
+ struct fs_fd *fd;
+ struct fs_ret *pr, r;
+};
+
+static int done(const int error, void *const args)
+{
+ struct write *const w = args;
+
+ w->done = true;
+ return 0;
+}
+
+static enum state wait(void *const args)
+{
+ struct write *const w = args;
+
+ if (!w->done)
+ return STATE_AGAIN;
+
+ *w->pr = w->r;
+ free(w);
+ return STATE_AGAIN;
+}
+
+int devfs_write(const struct fs_write *const fw, struct fs_ret *const r)
+{
+ struct fs_fd *const fd = fw->fd;
+ const struct fs_mp *const mp = fd->mp;
+ const struct inode *const inode = fd->inode.memi;
+ const struct devfs_ops *const o = devfs_ops(mp->prv, inode->name);
+ struct write *const w = malloc(sizeof *w);
+
+ if (!w)
+ goto failure;
+ else if (!o)
+ {
+ errno = ENOENT;
+ goto failure;
+ }
+
+ *w = (const struct write)
+ {
+ .fd = fd,
+ .pr = r,
+ .r = *r
+ };
+
+ const struct drv_event_done d =
+ {
+ .f = done,
+ .args = w
+ };
+
+ const struct drv_event_ops *const ops = &o->ops;
+
+ if (ops->write(fw->buf, fw->n, &d, ops->args))
+ goto failure;
+
+ *r = (const struct fs_ret){.f = wait, .args = w};
+ return 0;
+
+failure:
+ free(w);
+ return -1;
+}
diff --git a/src/fs/include/fs/fs.h b/src/fs/include/fs/fs.h
new file mode 100644
index 0000000..c66ce97
--- /dev/null
+++ b/src/fs/include/fs/fs.h
@@ -0,0 +1,159 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef FS_H
+#define FS_H
+
+#include <fs/inode.h>
+#include <state.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+struct fs_mountpoint;
+struct fs_mp_prv;
+struct fs_fd_prv;
+
+struct fs_stat
+{
+ const char *path;
+ struct stat *sb;
+ uid_t uid;
+ gid_t gid;
+};
+
+struct fs_mkdir
+{
+ const char *path;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+};
+
+struct fs_mount
+{
+ const char *src, *tgt;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+};
+
+struct fs_umount
+{
+ const char *tgt;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+};
+
+struct fs_open
+{
+ const char *path;
+ struct fs_fd *fd;
+ int flags;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+};
+
+struct fs_close
+{
+ struct fs_fd *fd;
+};
+
+struct fs_read
+{
+ struct fs_fd *fd;
+ void *buf;
+ size_t n;
+};
+
+struct fs_write
+{
+ struct fs_fd *fd;
+ const void *buf;
+ size_t n;
+};
+
+struct fs_seek
+{
+ struct fs_fd *fd;
+ long offset;
+};
+
+struct fs_ret
+{
+ enum state (*f)(void *args);
+ void *args;
+};
+
+enum
+{
+ FS_DEV_REQUIRED = 1
+};
+
+struct fs
+{
+ const char *type;
+ int flags;
+ int (*mount)(const struct fs_mount *, struct fs_ret *);
+ int (*umount)(const struct fs_umount *, struct fs_ret *);
+ int (*stat)(const struct fs_stat *, const struct fs_mp *,
+ const union inode_result *, struct fs_ret *);
+ int (*mkdir)(const struct fs_mkdir *, const struct fs_mp *,
+ const union inode_result *, struct fs_ret *);
+ int (*open)(const struct fs_open *, const struct fs_mp *,
+ const union inode_result *, struct fs_ret *);
+ int (*close)(const struct fs_close *, struct fs_ret *);
+ int (*read)(const struct fs_read *, struct fs_ret *);
+ int (*write)(const struct fs_write *, struct fs_ret *);
+ int (*seek)(const struct fs_seek *, struct fs_ret *);
+ struct inode_ops iops;
+};
+
+struct fs_mp
+{
+ const char *src, *tgt;
+ const struct fs *fs;
+ struct fs_mp_prv *prv;
+};
+
+struct fs_fd
+{
+ long offset;
+ int error;
+ const struct fs_mp *mp;
+ union inode_result inode;
+ struct fs_fd_prv *prv;
+};
+
+typedef int (*fs_update_fn)(struct fs_mp_prv *);
+
+int fs_register(const struct fs *fs);
+int fs_update(void);
+int fs_mountpoint(const char *src, const char *tgt, const struct fs *fs,
+ fs_update_fn fn, struct fs_mp_prv *pr);
+const struct fs *fs_from_type(const char *type);
+int fs_mp_from_path(const char *path, struct fs_mp *mp);
+struct fs_mp *fs_mps_from_path(const char *path, size_t *n);
+const char *fs_relpath(const char *path);
+char *fs_parent(const char *path);
+int fs_next(const char *path, char **next, size_t *i);
+
+#endif
diff --git a/src/fs/include/fs/inode.h b/src/fs/include/fs/inode.h
new file mode 100644
index 0000000..914564b
--- /dev/null
+++ b/src/fs/include/fs/inode.h
@@ -0,0 +1,79 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef FS_INODE_H
+#define FS_INODE_H
+
+#include <state.h>
+#include <sys/types.h>
+#include <time.h>
+
+struct fs;
+struct fs_mp;
+struct fs_ret;
+struct inode_prv;
+
+enum
+{
+ INODE_DIR = 1,
+ INODE_REGFILE = 1 << 1,
+ INODE_BLOCKDEV = 1 << 2,
+ INODE_MOUNTPOINT = 1 << 3,
+};
+
+struct inode
+{
+ char *name;
+ int flags;
+ ino_t ino;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+ struct timespec atim, mtim, ctim;
+ struct inode *parent, *child, *left, *right;
+ struct inode_prv *prv;
+};
+
+union inode_result
+{
+ struct inode cachei, *memi;
+};
+
+typedef int (*inode_search_done)(enum state state, const char *relpath,
+ const struct fs_mp *mp, const union inode_result *inode, void *args);
+
+struct inode_search
+{
+ const char *path;
+ inode_search_done done;
+ void *args;
+};
+
+struct inode_ops
+{
+ int (*search)(const char *path, const struct fs_mp *mp,
+ union inode_result *inode, struct fs_ret *r);
+ int (*reserve)(const struct inode *i, void *args, struct fs_ret *r);
+ int (*flags)(const union inode_result *i);
+};
+
+int inode_search(const struct inode_search *s, struct fs_ret *r);
+void inode_search_free(struct inode_search *s);
+void inode_free(struct inode *i);
+
+#endif
diff --git a/src/fs/iso9660/CMakeLists.txt b/src/fs/iso9660/CMakeLists.txt
new file mode 100644
index 0000000..67b56cf
--- /dev/null
+++ b/src/fs/iso9660/CMakeLists.txt
@@ -0,0 +1,20 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+add_library(iso9660)
+add_subdirectory(src)
+target_include_directories(iso9660 PUBLIC include PRIVATE private_include)
+target_link_libraries(iso9660 PUBLIC c PRIVATE fs kprintf state)
diff --git a/src/fs/iso9660/include/iso9660.h b/src/fs/iso9660/include/iso9660.h
new file mode 100644
index 0000000..f5ee681
--- /dev/null
+++ b/src/fs/iso9660/include/iso9660.h
@@ -0,0 +1,24 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef ISO9660_H
+#define ISO9660_H
+
+int iso9660_register(void);
+
+#endif
diff --git a/src/fs/iso9660/private_include/iso9660/ops.h b/src/fs/iso9660/private_include/iso9660/ops.h
new file mode 100644
index 0000000..64cd798
--- /dev/null
+++ b/src/fs/iso9660/private_include/iso9660/ops.h
@@ -0,0 +1,39 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef ISO9660_OPS_H
+#define ISO9660_OPS_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+
+int iso9660_mount(const struct fs_mount *m, struct fs_ret *r);
+int iso9660_mkdir(const struct fs_mkdir *m, const struct fs_mp *mp,
+ const union inode_result *i, struct fs_ret *r);
+int iso9660_open(const struct fs_open *o, const struct fs_mp *mp,
+ const union inode_result *i, struct fs_ret *r);
+int iso9660_read(const struct fs_read *r, struct fs_ret *ret);
+int iso9660_write(const struct fs_write *w, struct fs_ret *r);
+int iso9660_stat(const struct fs_stat *s, const struct fs_mp *mp,
+ const union inode_result *inode, struct fs_ret *r);
+int iso9660_seek(const struct fs_seek *s, struct fs_ret *r);
+int iso9660_close(const struct fs_close *c, struct fs_ret *r);
+int iso9660_search(const char *path, const struct fs_mp *prv,
+ union inode_result *inode, struct fs_ret *r);
+
+#endif
diff --git a/src/fs/iso9660/private_include/iso9660/types.h b/src/fs/iso9660/private_include/iso9660/types.h
new file mode 100644
index 0000000..89cd1d3
--- /dev/null
+++ b/src/fs/iso9660/private_include/iso9660/types.h
@@ -0,0 +1,34 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef ISO9660_TYPES_H
+#define ISO9660_TYPES_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+
+struct fs_mp_prv
+{
+ int dummy;
+};
+
+enum {ISO9660_SECTOR_SZ = 2048};
+
+extern const struct fs iso9660;
+
+#endif
diff --git a/src/fs/iso9660/src/CMakeLists.txt b/src/fs/iso9660/src/CMakeLists.txt
new file mode 100644
index 0000000..97dd80b
--- /dev/null
+++ b/src/fs/iso9660/src/CMakeLists.txt
@@ -0,0 +1,28 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(iso9660 PRIVATE
+ close.c
+ mount.c
+ mkdir.c
+ open.c
+ stat.c
+ read.c
+ register.c
+ search.c
+ seek.c
+ write.c
+)
diff --git a/src/fs/iso9660/src/close.c b/src/fs/iso9660/src/close.c
new file mode 100644
index 0000000..dc80117
--- /dev/null
+++ b/src/fs/iso9660/src/close.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+
+int iso9660_close(const struct fs_close *const c, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/iso9660/src/mkdir.c b/src/fs/iso9660/src/mkdir.c
new file mode 100644
index 0000000..e3d91ce
--- /dev/null
+++ b/src/fs/iso9660/src/mkdir.c
@@ -0,0 +1,28 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+#include <fs/inode.h>
+
+int iso9660_mkdir(const struct fs_mkdir *const m, const struct fs_mp *const mp,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/iso9660/src/mount.c b/src/fs/iso9660/src/mount.c
new file mode 100644
index 0000000..aeddcc5
--- /dev/null
+++ b/src/fs/iso9660/src/mount.c
@@ -0,0 +1,196 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <iso9660/types.h>
+#include <fs/fs.h>
+#include <kprintf.h>
+#include <state.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct mount
+{
+ char *path, header[sizeof "CD001"];
+ struct fs_fd fd;
+ struct fs_ret *r;
+ struct fs_mount mount;
+ const struct fs_mp *mp;
+};
+
+static void free_mount(struct mount *const m)
+{
+ if (!m)
+ return;
+
+ const struct fs_close c = {.fd = &m->fd};
+
+ m->mp->fs->close(&c, m->r);
+ free(m->path);
+ free(m);
+}
+
+static enum state check_header(void *const args)
+{
+ struct mount *const m = args;
+ static const char header[] = {1, 'C', 'D', '0', '0', '1'};
+
+ if (memcmp(m->header, header, sizeof header))
+ {
+ kprintf("invalid header");
+ free_mount(m);
+ return STATE_FATAL;
+ }
+
+ free_mount(m);
+ return STATE_OK;
+}
+
+static enum state read_header(void *const args)
+{
+ struct mount *const m = args;
+ struct fs_fd *const fd = &m->fd;
+ const struct fs_read r =
+ {
+ .buf = m->header,
+ .n = sizeof m->header,
+ .fd = fd
+ };
+
+ if (fd->error)
+ {
+ errno = fd->error;
+ goto failure;
+ }
+
+ *m->r = (const struct fs_ret)
+ {
+ .f = check_header,
+ .args = m
+ };
+
+ if (m->mp->fs->read(&r, m->r))
+ goto failure;
+
+ return STATE_AGAIN;
+
+failure:
+ free_mount(m);
+ return STATE_FATAL;
+}
+
+static enum state seek_header(void *const args)
+{
+ struct mount *const m = args;
+ const struct fs_mp *const mp = m->mp;
+ const struct fs_seek s =
+ {
+ .fd = &m->fd,
+ .offset = 16 * ISO9660_SECTOR_SZ
+ };
+
+ *m->r = (const struct fs_ret)
+ {
+ .args = m,
+ .f = read_header
+ };
+
+ if (mp->fs->seek(&s, m->r))
+ goto failure;
+
+ return STATE_AGAIN;
+
+failure:
+ free_mount(m);
+ return STATE_FATAL;
+}
+
+static int search_done(const enum state state, const char *const relpath,
+ const struct fs_mp *const mp, const union inode_result *const inode,
+ void *const args)
+{
+ struct mount *const m = args;
+ const struct fs_mount *const fm = &m->mount;
+
+ if (!inode)
+ {
+ errno = ENOENT;
+ goto failure;
+ }
+
+ const struct fs_open o =
+ {
+ .fd = &m->fd,
+ .gid = fm->gid,
+ .uid = fm->uid,
+ .mode = fm->mode,
+ .path = relpath
+ };
+
+ *m->r = (const struct fs_ret)
+ {
+ .args = m,
+ .f = seek_header
+ };
+
+ if (mp->fs->open(&o, mp, inode, m->r))
+ goto failure;
+
+ m->mp = mp;
+ return 0;
+
+failure:
+ free_mount(m);
+ return -1;
+}
+
+int iso9660_mount(const struct fs_mount *const fm, struct fs_ret *const r)
+{
+ char *tgtdup = NULL;
+ struct mount *const m = malloc(sizeof *m);
+
+ if (!m || !(tgtdup = strdup(fm->tgt)))
+ goto failure;
+
+ *m = (const struct mount)
+ {
+ .path = tgtdup,
+ .mount = *fm,
+ .r = r
+ };
+
+ const struct inode_search s =
+ {
+ .args = m,
+ .path = fm->src,
+ .done = search_done
+ };
+
+ if (inode_search(&s, r))
+ goto failure;
+
+ return 0;
+
+failure:
+ free(tgtdup);
+ free(m);
+ return -1;
+}
diff --git a/src/fs/iso9660/src/open.c b/src/fs/iso9660/src/open.c
new file mode 100644
index 0000000..b7c78ef
--- /dev/null
+++ b/src/fs/iso9660/src/open.c
@@ -0,0 +1,27 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+
+int iso9660_open(const struct fs_open *const o, const struct fs_mp *const mp,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/iso9660/src/read.c b/src/fs/iso9660/src/read.c
new file mode 100644
index 0000000..7a8569f
--- /dev/null
+++ b/src/fs/iso9660/src/read.c
@@ -0,0 +1,27 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+#include <stddef.h>
+
+int iso9660_read(const struct fs_read *const r, struct fs_ret *const ret)
+{
+ return -1;
+}
diff --git a/src/fs/iso9660/src/register.c b/src/fs/iso9660/src/register.c
new file mode 100644
index 0000000..2b69651
--- /dev/null
+++ b/src/fs/iso9660/src/register.c
@@ -0,0 +1,44 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+
+const struct fs iso9660 =
+{
+ .type = "iso9660",
+ .flags = FS_DEV_REQUIRED,
+ .mount = iso9660_mount,
+ .stat = iso9660_stat,
+ .mkdir = iso9660_mkdir,
+ .open = iso9660_open,
+ .read = iso9660_read,
+ .write = iso9660_write,
+ .close = iso9660_close,
+ .seek = iso9660_seek,
+ .iops =
+ {
+ .search = iso9660_search
+ }
+};
+
+int iso9660_register(void)
+{
+ return fs_register(&iso9660);
+}
diff --git a/src/fs/iso9660/src/search.c b/src/fs/iso9660/src/search.c
new file mode 100644
index 0000000..c6d1208
--- /dev/null
+++ b/src/fs/iso9660/src/search.c
@@ -0,0 +1,27 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+
+int iso9660_search(const char *const path, const struct fs_mp *const mp,
+ union inode_result *const inode, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/iso9660/src/seek.c b/src/fs/iso9660/src/seek.c
new file mode 100644
index 0000000..c78bb52
--- /dev/null
+++ b/src/fs/iso9660/src/seek.c
@@ -0,0 +1,27 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <iso9660/types.h>
+#include <fs/fs.h>
+
+int iso9660_seek(const struct fs_seek *const s, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/iso9660/src/stat.c b/src/fs/iso9660/src/stat.c
new file mode 100644
index 0000000..e5905e4
--- /dev/null
+++ b/src/fs/iso9660/src/stat.c
@@ -0,0 +1,28 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+#include <sys/stat.h>
+
+int iso9660_stat(const struct fs_stat *const s, const struct fs_mp *const mp,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/iso9660/src/write.c b/src/fs/iso9660/src/write.c
new file mode 100644
index 0000000..b7baa93
--- /dev/null
+++ b/src/fs/iso9660/src/write.c
@@ -0,0 +1,28 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <iso9660.h>
+#include <iso9660/ops.h>
+#include <fs/fs.h>
+#include <errno.h>
+
+int iso9660_write(const struct fs_write *const w, struct fs_ret *const r)
+{
+ errno = EROFS;
+ return -1;
+}
diff --git a/src/fs/private_include/fs/private.h b/src/fs/private_include/fs/private.h
new file mode 100644
index 0000000..327ded3
--- /dev/null
+++ b/src/fs/private_include/fs/private.h
@@ -0,0 +1,63 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef FS_TYPES_H
+#define FS_TYPES_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <state.h>
+#include <sys/types.h>
+
+struct fs_fd_prv;
+
+struct fs_register
+{
+ const struct fs *fs;
+ struct fs_register *next;
+};
+
+struct fs_mountpoint
+{
+ char *src, *tgt;
+ const struct fs *fs;
+ struct fs_mp_prv *prv;
+ struct fs_mountpoint *next;
+ fs_update_fn update;
+};
+
+struct fs_add
+{
+ char *src, *tgt;
+ struct inode_search *search;
+ struct inode *inode;
+ mode_t mode;
+ const struct fs *fs;
+ enum state (*next)(struct fs_add *);
+};
+
+struct fs_fd
+{
+ long off;
+ struct fs_fd_prv *prv;
+};
+
+extern struct fs_register *fs_rhead, *fs_rtail;
+extern struct fs_mountpoint *fs_mphead, *fs_mptail;
+
+#endif
diff --git a/src/fs/private_include/fs/types.h b/src/fs/private_include/fs/types.h
new file mode 100644
index 0000000..fe1eb01
--- /dev/null
+++ b/src/fs/private_include/fs/types.h
@@ -0,0 +1,55 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef FS_TYPES_H
+#define FS_TYPES_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <state.h>
+#include <sys/types.h>
+
+struct fs_register
+{
+ const struct fs *fs;
+ struct fs_register *next;
+};
+
+struct fs_mountpoint
+{
+ char *src, *tgt;
+ const struct fs *fs;
+ struct fs_mp_prv *prv;
+ struct fs_mountpoint *next;
+ fs_update_fn update;
+};
+
+struct fs_add
+{
+ char *src, *tgt;
+ struct inode_search *search;
+ struct inode *inode;
+ mode_t mode;
+ const struct fs *fs;
+ enum state (*next)(struct fs_add *);
+};
+
+extern struct fs_register *fs_rhead, *fs_rtail;
+extern struct fs_mountpoint *fs_mphead, *fs_mptail;
+
+#endif
diff --git a/src/fs/ramfs/CMakeLists.txt b/src/fs/ramfs/CMakeLists.txt
new file mode 100644
index 0000000..9581c99
--- /dev/null
+++ b/src/fs/ramfs/CMakeLists.txt
@@ -0,0 +1,20 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+add_library(ramfs)
+add_subdirectory(src)
+target_include_directories(ramfs PUBLIC include PRIVATE private_include)
+target_link_libraries(ramfs PUBLIC state c PRIVATE fs drv)
diff --git a/src/fs/ramfs/include/ramfs.h b/src/fs/ramfs/include/ramfs.h
new file mode 100644
index 0000000..36be39c
--- /dev/null
+++ b/src/fs/ramfs/include/ramfs.h
@@ -0,0 +1,43 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef RAMFS_H
+#define RAMFS_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stddef.h>
+
+struct ramfs *ramfs_mount(const struct fs_mount *m, struct fs_ret *r);
+int ramfs_mkdir(const struct fs_mkdir *m, struct ramfs *rfs,
+ const union inode_result *i, struct fs_ret *r);
+int ramfs_open(const struct fs_open *o, struct inode *i, struct fs_ret *r);
+int ramfs_read(const struct fs_read *r, struct fs_ret *ret);
+int ramfs_write(const struct fs_write *w, struct fs_ret *r);
+int ramfs_stat(const struct fs_stat *s, const struct ramfs *rfs,
+ const union inode_result *inode, struct fs_ret *r);
+int ramfs_close(const struct fs_close *c, struct fs_ret *r);
+int ramfs_search(const char *path, const struct ramfs *rfs,
+ union inode_result *inode, struct fs_ret *r);
+int ramfs_flags(const union inode_result *i);
+int ramfs_mknod(const char *node, mode_t mode, dev_t dev, struct ramfs *rfs);
+void ramfs_free(struct ramfs *rfs);
+
+#endif
diff --git a/src/fs/ramfs/private_include/ramfs/types.h b/src/fs/ramfs/private_include/ramfs/types.h
new file mode 100644
index 0000000..975ff9a
--- /dev/null
+++ b/src/fs/ramfs/private_include/ramfs/types.h
@@ -0,0 +1,31 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef RAMFS_TYPES_H
+#define RAMFS_TYPES_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+
+struct ramfs
+{
+ struct inode *root;
+ ino_t ino;
+};
+
+#endif
diff --git a/src/fs/ramfs/src/CMakeLists.txt b/src/fs/ramfs/src/CMakeLists.txt
new file mode 100644
index 0000000..904e22d
--- /dev/null
+++ b/src/fs/ramfs/src/CMakeLists.txt
@@ -0,0 +1,29 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(ramfs PRIVATE
+ close.c
+ free.c
+ flags.c
+ mount.c
+ mkdir.c
+ mknod.c
+ open.c
+ stat.c
+ read.c
+ search.c
+ write.c
+)
diff --git a/src/fs/ramfs/src/close.c b/src/fs/ramfs/src/close.c
new file mode 100644
index 0000000..9d85319
--- /dev/null
+++ b/src/fs/ramfs/src/close.c
@@ -0,0 +1,25 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <fs/fs.h>
+
+int ramfs_close(const struct fs_close *const c, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/ramfs/src/flags.c b/src/fs/ramfs/src/flags.c
new file mode 100644
index 0000000..1453c5c
--- /dev/null
+++ b/src/fs/ramfs/src/flags.c
@@ -0,0 +1,25 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <fs/inode.h>
+
+int ramfs_flags(const union inode_result *const i)
+{
+ return i->memi->flags;
+}
diff --git a/src/fs/ramfs/src/free.c b/src/fs/ramfs/src/free.c
new file mode 100644
index 0000000..39b9bc4
--- /dev/null
+++ b/src/fs/ramfs/src/free.c
@@ -0,0 +1,31 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <ramfs/types.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+void ramfs_free(struct ramfs *const r)
+{
+ if (!r)
+ return;
+
+ inode_free(r->root);
+ free(r);
+}
diff --git a/src/fs/ramfs/src/mkdir.c b/src/fs/ramfs/src/mkdir.c
new file mode 100644
index 0000000..fef39ef
--- /dev/null
+++ b/src/fs/ramfs/src/mkdir.c
@@ -0,0 +1,79 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <ramfs/types.h>
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <state.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+static enum state done(void *const args)
+{
+ return STATE_OK;
+}
+
+int ramfs_mkdir(const struct fs_mkdir *const m, struct ramfs *const rfs,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ struct timespec ts;
+ struct inode *ni = NULL;
+ struct inode *const parent = inode->memi;
+ char *const name = strdup(m->path);
+
+ if (!name
+ || clock_gettime(CLOCK_REALTIME, &ts)
+ || !(ni = malloc(sizeof *ni)))
+ goto failure;
+
+ *ni = (const struct inode)
+ {
+ .name = name,
+ .mode = m->mode,
+ .uid = m->uid,
+ .gid = m->gid,
+ .flags = INODE_DIR,
+ .atim = ts,
+ .ctim = ts,
+ .mtim = ts,
+ .ino = rfs->ino++,
+ .parent = parent
+ };
+
+ if (!parent->child)
+ parent->child = ni;
+ else
+ for (struct inode *i = parent->child; i; i = i->right)
+ if (!i->right)
+ {
+ i->right = ni;
+ ni->left = i;
+ break;
+ }
+
+ parent->atim = parent->mtim = ts;
+ *r = (const struct fs_ret){.f = done};
+ return 0;
+
+failure:
+ free(ni);
+ free(name);
+ return -1;
+}
diff --git a/src/fs/ramfs/src/mknod.c b/src/fs/ramfs/src/mknod.c
new file mode 100644
index 0000000..2ad9fd7
--- /dev/null
+++ b/src/fs/ramfs/src/mknod.c
@@ -0,0 +1,87 @@
+
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <ramfs/types.h>
+#include <fs/inode.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+static struct inode *find(const char *const node, struct inode *const root)
+{
+ for (struct inode *c = root->child; c; c = c->right)
+ if (!strcmp(c->name, node))
+ return c;
+
+ return NULL;
+}
+
+int ramfs_mknod(const char *const node, const mode_t mode, const dev_t dev,
+ struct ramfs *const rfs)
+{
+ struct inode *const r = rfs->root,
+ *const inode = find(node, r),
+ *newinode = NULL;
+ char *nodedup = NULL;
+ struct timespec ts;
+
+ if (inode)
+ {
+ errno = EEXIST;
+ goto failure;
+ }
+ else if (clock_gettime(CLOCK_REALTIME, &ts)
+ || !(nodedup = strdup(node))
+ || !(newinode = malloc(sizeof *newinode)))
+ goto failure;
+
+ *newinode = (const struct inode)
+ {
+ .atim = ts,
+ .ctim = ts,
+ .mtim = ts,
+ .flags = INODE_BLOCKDEV,
+ .mode = mode,
+ .parent = rfs->root,
+ .name = nodedup
+ };
+
+ if (!r->child)
+ r->child = newinode;
+ else
+ for (struct inode *c = r->child; c; c = c->right)
+ if (!c->right)
+ {
+ c->right = newinode;
+ newinode->left = c;
+ break;
+ }
+
+ r->atim = r->mtim = ts;
+ return 0;
+
+failure:
+ free(nodedup);
+ free(newinode);
+ return -1;
+}
diff --git a/src/fs/ramfs/src/mount.c b/src/fs/ramfs/src/mount.c
new file mode 100644
index 0000000..09c4685
--- /dev/null
+++ b/src/fs/ramfs/src/mount.c
@@ -0,0 +1,69 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <ramfs/types.h>
+#include <fs/fs.h>
+#include <state.h>
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+static enum state mount(void *const args)
+{
+ return STATE_OK;
+}
+
+struct ramfs *ramfs_mount(const struct fs_mount *const m,
+ struct fs_ret *const r)
+{
+ struct ramfs *ret = NULL;
+ struct timespec ts;
+ char *const name = strdup("/");
+ struct inode *root = NULL;
+
+ if (!name
+ || clock_gettime(CLOCK_REALTIME, &ts)
+ || !(root = malloc(sizeof *root))
+ || !(ret = malloc(sizeof *ret)))
+ goto failure;
+
+ *root = (const struct inode)
+ {
+ .name = name,
+ .mode = m->mode,
+ .uid = m->uid,
+ .gid = m->gid,
+ .atim = ts,
+ .mtim = ts,
+ .ctim = ts
+ };
+
+ *ret = (const struct ramfs){.root = root};
+ *r = (const struct fs_ret){.f = mount};
+ ret->ino++;
+ return ret;
+
+failure:
+ free(root);
+ free(ret);
+ free(name);
+ return NULL;
+}
diff --git a/src/fs/ramfs/src/open.c b/src/fs/ramfs/src/open.c
new file mode 100644
index 0000000..1140b58
--- /dev/null
+++ b/src/fs/ramfs/src/open.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <fs/fs.h>
+
+int ramfs_open(const struct fs_open *const o,struct inode *const i,
+ struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/ramfs/src/read.c b/src/fs/ramfs/src/read.c
new file mode 100644
index 0000000..77d6287
--- /dev/null
+++ b/src/fs/ramfs/src/read.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <fs/fs.h>
+#include <stddef.h>
+
+int ramfs_read(const struct fs_read *const r, struct fs_ret *const ret)
+{
+ return -1;
+}
diff --git a/src/fs/ramfs/src/search.c b/src/fs/ramfs/src/search.c
new file mode 100644
index 0000000..2c8f35a
--- /dev/null
+++ b/src/fs/ramfs/src/search.c
@@ -0,0 +1,150 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <ramfs/types.h>
+#include <fs/fs.h>
+#include <state.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct search
+{
+ union inode_result *inode;
+ const struct ramfs *rfs;
+ struct fs_ret r, *pr;
+ const char *path;
+};
+
+static void free_search(struct search *const s)
+{
+ free(s);
+}
+
+static int find_node(const char *const path, struct inode **const out,
+ size_t *const i)
+{
+ int ret = -1;
+ char *node;
+ struct inode *volatile const inode = *out;
+
+ if (fs_next(path, &node, i))
+ return -1;
+ else if (!strcmp(inode->name, node))
+ {
+ if (*i >= strlen(path))
+ {
+ free(node);
+ return 1;
+ }
+
+ *out = inode->child;
+ }
+ else
+ {
+ bool found = false;
+
+ for (struct inode *in = inode->right; in; in = in->right)
+ if (!strcmp(in->name, node))
+ {
+ if (*i >= strlen(path))
+ {
+ *out = in;
+ free(node);
+ return 1;
+ }
+
+ *out = in->child;
+ found = true;
+ break;
+ }
+
+ if (!found)
+ goto end;
+ }
+
+ ret = 0;
+
+end:
+ if (ret == -1)
+ {
+ volatile int a = 0;
+
+ a++;
+ }
+
+ free(node);
+ return ret;
+}
+
+static enum state search(void *const args)
+{
+ enum state ret = STATE_FATAL;
+ struct search *const s = args;
+ struct inode *inode = s->rfs->root;
+ size_t i = 0;
+
+ for (;;)
+ {
+ const int n = find_node(s->path, &inode, &i);
+
+ if (n < 0)
+ goto end;
+ else if (n > 0)
+ break;
+ }
+
+ s->inode->memi = inode;
+ *s->pr = s->r;
+ ret = STATE_AGAIN;
+
+end:
+ free_search(s);
+ return ret;
+}
+
+int ramfs_search(const char *const path, const struct ramfs *const rfs,
+ union inode_result *const inode, struct fs_ret *const r)
+{
+ struct search *s = malloc(sizeof *s);
+
+ if (!s)
+ goto failure;
+
+ *s = (const struct search)
+ {
+ .inode = inode,
+ .path = path,
+ .rfs = rfs,
+ .r = *r,
+ .pr = r
+ };
+
+ *r = (const struct fs_ret)
+ {
+ .f = search,
+ .args = s
+ };
+
+ return 0;
+
+failure:
+ free(s);
+ return -1;
+}
diff --git a/src/fs/ramfs/src/stat.c b/src/fs/ramfs/src/stat.c
new file mode 100644
index 0000000..c5498d9
--- /dev/null
+++ b/src/fs/ramfs/src/stat.c
@@ -0,0 +1,52 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <fs/fs.h>
+#include <state.h>
+#include <sys/stat.h>
+
+static enum state done(void *const args)
+{
+ return STATE_OK;
+}
+
+int ramfs_stat(const struct fs_stat *const s, const struct ramfs *const rfs,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ const struct inode *const i = inode->memi;
+
+ *s->sb = (const struct stat)
+ {
+ .st_atim = i->atim,
+ .st_ctim = i->ctim,
+ .st_mtim = i->mtim,
+ .st_blksize = 1,
+ .st_ino = i->ino,
+ .st_uid = i->uid,
+ .st_gid = i->gid,
+ .st_mode = i->mode
+ };
+
+ *r = (const struct fs_ret)
+ {
+ .f = done
+ };
+
+ return 0;
+}
diff --git a/src/fs/ramfs/src/write.c b/src/fs/ramfs/src/write.c
new file mode 100644
index 0000000..94b18cc
--- /dev/null
+++ b/src/fs/ramfs/src/write.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <ramfs.h>
+#include <fs/fs.h>
+#include <stddef.h>
+
+int ramfs_write(const struct fs_write *const w, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/rootfs/CMakeLists.txt b/src/fs/rootfs/CMakeLists.txt
new file mode 100644
index 0000000..b32fd82
--- /dev/null
+++ b/src/fs/rootfs/CMakeLists.txt
@@ -0,0 +1,20 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+add_library(rootfs)
+add_subdirectory(src)
+target_include_directories(rootfs PUBLIC include PRIVATE private_include)
+target_link_libraries(rootfs PUBLIC state c PRIVATE fs ramfs)
diff --git a/src/fs/rootfs/include/rootfs.h b/src/fs/rootfs/include/rootfs.h
new file mode 100644
index 0000000..c218b1c
--- /dev/null
+++ b/src/fs/rootfs/include/rootfs.h
@@ -0,0 +1,24 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef ROOTFS_H
+#define ROOTFS_H
+
+int rootfs_register(void);
+
+#endif
diff --git a/src/fs/rootfs/private_include/rootfs/ops.h b/src/fs/rootfs/private_include/rootfs/ops.h
new file mode 100644
index 0000000..356e740
--- /dev/null
+++ b/src/fs/rootfs/private_include/rootfs/ops.h
@@ -0,0 +1,42 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef ROOTFS_OPS_H
+#define ROOTFS_OPS_H
+
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stddef.h>
+
+int rootfs_mount(const struct fs_mount *m, struct fs_ret *r);
+int rootfs_mkdir(const struct fs_mkdir *m, const struct fs_mp *mp,
+ const union inode_result *i, struct fs_ret *r);
+int rootfs_open(const struct fs_open *o, const struct fs_mp *mp,
+ const union inode_result *i, struct fs_ret *r);
+int rootfs_read(const struct fs_read *r, struct fs_ret *ret);
+int rootfs_write(const struct fs_write *w, struct fs_ret *r);
+int rootfs_stat(const struct fs_stat *s, const struct fs_mp *mp,
+ const union inode_result *inode, struct fs_ret *r);
+int rootfs_close(const struct fs_close *c, struct fs_ret *r);
+int rootfs_search(const char *path, const struct fs_mp *mp,
+ union inode_result *inode, struct fs_ret *r);
+int rootfs_flags(const union inode_result *i);
+
+#endif
diff --git a/src/fs/rootfs/private_include/rootfs/types.h b/src/fs/rootfs/private_include/rootfs/types.h
new file mode 100644
index 0000000..1ce40aa
--- /dev/null
+++ b/src/fs/rootfs/private_include/rootfs/types.h
@@ -0,0 +1,32 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef ROOTFS_TYPES_H
+#define ROOTFS_TYPES_H
+
+#include <fs/fs.h>
+#include <ramfs.h>
+
+struct fs_mp_prv
+{
+ struct ramfs *rfs;
+};
+
+extern const struct fs rootfs;
+
+#endif
diff --git a/src/fs/rootfs/src/CMakeLists.txt b/src/fs/rootfs/src/CMakeLists.txt
new file mode 100644
index 0000000..b7fdcdb
--- /dev/null
+++ b/src/fs/rootfs/src/CMakeLists.txt
@@ -0,0 +1,28 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(rootfs PRIVATE
+ close.c
+ flags.c
+ mount.c
+ mkdir.c
+ open.c
+ stat.c
+ read.c
+ register.c
+ search.c
+ write.c
+)
diff --git a/src/fs/rootfs/src/close.c b/src/fs/rootfs/src/close.c
new file mode 100644
index 0000000..51a7c45
--- /dev/null
+++ b/src/fs/rootfs/src/close.c
@@ -0,0 +1,25 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <fs/fs.h>
+
+int rootfs_close(const struct fs_close *const c, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/rootfs/src/flags.c b/src/fs/rootfs/src/flags.c
new file mode 100644
index 0000000..06496bb
--- /dev/null
+++ b/src/fs/rootfs/src/flags.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <rootfs/ops.h>
+#include <fs/inode.h>
+
+int rootfs_flags(const union inode_result *const i)
+{
+ return i->memi->flags;
+}
diff --git a/src/fs/rootfs/src/mkdir.c b/src/fs/rootfs/src/mkdir.c
new file mode 100644
index 0000000..7136477
--- /dev/null
+++ b/src/fs/rootfs/src/mkdir.c
@@ -0,0 +1,30 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <rootfs/ops.h>
+#include <rootfs/types.h>
+#include <fs/fs.h>
+#include <fs/inode.h>
+#include <ramfs.h>
+
+int rootfs_mkdir(const struct fs_mkdir *const m, const struct fs_mp *const mp,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ return ramfs_mkdir(m, mp->prv->rfs, inode, r);
+}
diff --git a/src/fs/rootfs/src/mount.c b/src/fs/rootfs/src/mount.c
new file mode 100644
index 0000000..f421918
--- /dev/null
+++ b/src/fs/rootfs/src/mount.c
@@ -0,0 +1,42 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <rootfs/types.h>
+#include <ramfs.h>
+#include <fs/fs.h>
+#include <stdlib.h>
+
+int rootfs_mount(const struct fs_mount *const m, struct fs_ret *const r)
+{
+ struct ramfs *rfs = NULL;
+ struct fs_mp_prv *const p = malloc(sizeof *p);
+
+ if (!p
+ || !(rfs = ramfs_mount(m, r))
+ || fs_mountpoint(m->src, m->tgt, &rootfs, NULL, p))
+ goto failure;
+
+ *p = (const struct fs_mp_prv){.rfs = rfs};
+ return 0;
+
+failure:
+ ramfs_free(rfs);
+ free(p);
+ return -1;
+}
diff --git a/src/fs/rootfs/src/open.c b/src/fs/rootfs/src/open.c
new file mode 100644
index 0000000..6fea301
--- /dev/null
+++ b/src/fs/rootfs/src/open.c
@@ -0,0 +1,27 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <rootfs/ops.h>
+#include <fs/fs.h>
+
+int rootfs_open(const struct fs_open *const o, const struct fs_mp *const mp,
+ const union inode_result *const i, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/rootfs/src/read.c b/src/fs/rootfs/src/read.c
new file mode 100644
index 0000000..d2cb757
--- /dev/null
+++ b/src/fs/rootfs/src/read.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <fs/fs.h>
+#include <stddef.h>
+
+int rootfs_read(const struct fs_read *const r, struct fs_ret *const ret)
+{
+ return -1;
+}
diff --git a/src/fs/rootfs/src/register.c b/src/fs/rootfs/src/register.c
new file mode 100644
index 0000000..e578cf7
--- /dev/null
+++ b/src/fs/rootfs/src/register.c
@@ -0,0 +1,43 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <rootfs/ops.h>
+#include <fs/fs.h>
+
+const struct fs rootfs =
+{
+ .type = "rootfs",
+ .mount = rootfs_mount,
+ .stat = rootfs_stat,
+ .mkdir = rootfs_mkdir,
+ .open = rootfs_open,
+ .read = rootfs_read,
+ .write = rootfs_write,
+ .close = rootfs_close,
+ .iops =
+ {
+ .search = rootfs_search,
+ .flags = rootfs_flags
+ }
+};
+
+int rootfs_register(void)
+{
+ return fs_register(&rootfs);
+}
diff --git a/src/fs/rootfs/src/search.c b/src/fs/rootfs/src/search.c
new file mode 100644
index 0000000..3675f0a
--- /dev/null
+++ b/src/fs/rootfs/src/search.c
@@ -0,0 +1,29 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <rootfs/ops.h>
+#include <rootfs/types.h>
+#include <fs/fs.h>
+#include <ramfs.h>
+
+int rootfs_search(const char *const path, const struct fs_mp *const mp,
+ union inode_result *const inode, struct fs_ret *const r)
+{
+ return ramfs_search(path, mp->prv->rfs, inode, r);
+}
diff --git a/src/fs/rootfs/src/stat.c b/src/fs/rootfs/src/stat.c
new file mode 100644
index 0000000..2eff55c
--- /dev/null
+++ b/src/fs/rootfs/src/stat.c
@@ -0,0 +1,28 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <rootfs/ops.h>
+#include <fs/fs.h>
+#include <sys/stat.h>
+
+int rootfs_stat(const struct fs_stat *const s, const struct fs_mp *const mp,
+ const union inode_result *const inode, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/rootfs/src/write.c b/src/fs/rootfs/src/write.c
new file mode 100644
index 0000000..53b9704
--- /dev/null
+++ b/src/fs/rootfs/src/write.c
@@ -0,0 +1,26 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <rootfs.h>
+#include <fs/fs.h>
+#include <stddef.h>
+
+int rootfs_write(const struct fs_write *const w, struct fs_ret *const r)
+{
+ return -1;
+}
diff --git a/src/fs/src/CMakeLists.txt b/src/fs/src/CMakeLists.txt
new file mode 100644
index 0000000..7f2c7a5
--- /dev/null
+++ b/src/fs/src/CMakeLists.txt
@@ -0,0 +1,30 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(fs PRIVATE
+ from_type.c
+ headtail.c
+ mountpoint.c
+ mp_from_path.c
+ mps_from_path.c
+ parent.c
+ register.c
+ relpath.c
+ update.c
+ next.c
+)
+
+add_subdirectory(inode)
diff --git a/src/fs/src/from_type.c b/src/fs/src/from_type.c
new file mode 100644
index 0000000..b836cdd
--- /dev/null
+++ b/src/fs/src/from_type.c
@@ -0,0 +1,36 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+const struct fs *fs_from_type(const char *const type)
+{
+ for (const struct fs_register *r = fs_rhead; r; r = r->next)
+ {
+ const struct fs *const fs = r->fs;
+
+ if (!strcmp(type, fs->type))
+ return fs;
+ }
+
+ return NULL;
+}
diff --git a/src/fs/src/headtail.c b/src/fs/src/headtail.c
new file mode 100644
index 0000000..f5eaf79
--- /dev/null
+++ b/src/fs/src/headtail.c
@@ -0,0 +1,22 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/types.h>
+
+struct fs_register *fs_rhead, *fs_rtail;
+struct fs_mountpoint *fs_mphead, *fs_mptail;
diff --git a/src/fs/src/inode/CMakeLists.txt b/src/fs/src/inode/CMakeLists.txt
new file mode 100644
index 0000000..1b0e0fd
--- /dev/null
+++ b/src/fs/src/inode/CMakeLists.txt
@@ -0,0 +1,20 @@
+# wanix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(fs PRIVATE
+ free.c
+ search.c
+)
diff --git a/src/fs/src/inode/free.c b/src/fs/src/inode/free.c
new file mode 100644
index 0000000..0ff18f2
--- /dev/null
+++ b/src/fs/src/inode/free.c
@@ -0,0 +1,31 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/inode.h>
+#include <stdlib.h>
+
+void inode_free(struct inode *const i)
+{
+ if (i)
+ {
+ inode_free(i->child);
+ free(i->name);
+ }
+
+ free(i);
+}
diff --git a/src/fs/src/inode/search.c b/src/fs/src/inode/search.c
new file mode 100644
index 0000000..09b38a1
--- /dev/null
+++ b/src/fs/src/inode/search.c
@@ -0,0 +1,121 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/inode.h>
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <state.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct search
+{
+ struct fs_mp *mp;
+ size_t n, mp_i;
+ struct fs_ret *r;
+ union inode_result inode;
+ struct inode_search search;
+};
+
+static void free_search(struct search *const s)
+{
+ free(s);
+}
+
+static enum state search_mp(struct search *const s)
+{
+ const struct inode_search *const is = &s->search;
+ const struct fs_mp *const cur = &s->mp[s->mp_i],
+ *const next = s->mp_i + 1 < s->n ?
+ &s->mp[s->mp_i + 1] : NULL;
+ const struct fs *const fs = cur->fs;
+ const char *relpath = next ? next->tgt : is->path;
+
+ for (size_t i = 0; i < s->mp_i; i++)
+ relpath += strlen(s->mp[s->mp_i].tgt);
+
+ if (fs && fs->iops.search(relpath, cur, &s->inode, s->r))
+ return STATE_FATAL;
+
+ s->mp_i++;
+ return STATE_AGAIN;
+}
+
+static enum state search(void *const args)
+{
+ struct search *const s = args;
+ const struct inode_search *const is = &s->search;
+
+ if (!s->mp)
+ {
+ const int ret = is->done(STATE_FATAL, NULL, NULL, NULL, is->args);
+
+ free_search(s);
+ return ret ? STATE_FATAL : STATE_AGAIN;
+ }
+ else if (s->mp_i < s->n)
+ return search_mp(s);
+ else
+ {
+ const char *relpath = is->path;
+
+ for (size_t i = 0; i < s->n; i++)
+ relpath += strlen(s->mp[i].tgt);
+
+ const int ret = is->done(STATE_OK, relpath, &s->mp[s->n - 1],
+ &s->inode, is->args);
+
+ free_search(s);
+ return ret ? STATE_FATAL : STATE_AGAIN;
+ }
+
+ return STATE_FATAL;
+}
+
+int inode_search(const struct inode_search *const is, struct fs_ret *const r)
+{
+ struct search *s = NULL;
+ size_t n;
+ /* Do not check for errors yet. */
+ struct fs_mp *const mp = fs_mps_from_path(is->path, &n);
+
+ if (!(s = malloc(sizeof *s)))
+ goto failure;
+
+ *s = (const struct search)
+ {
+ .search = *is,
+ .mp = mp,
+ .n = n,
+ .r = r
+ };
+
+ *r = (const struct fs_ret)
+ {
+ .f = search,
+ .args = s
+ };
+
+ return 0;
+
+failure:
+ free(s);
+ free(mp);
+ return -1;
+}
diff --git a/src/fs/src/mountpoint.c b/src/fs/src/mountpoint.c
new file mode 100644
index 0000000..6ae5a0e
--- /dev/null
+++ b/src/fs/src/mountpoint.c
@@ -0,0 +1,60 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+int fs_mountpoint(const char *const src, const char *const tgt,
+ const struct fs *const fs, const fs_update_fn fn,
+ struct fs_mp_prv *const pr)
+{
+ struct fs_mountpoint *m = NULL;
+ char *srcdup = NULL, *const tgtdup = strdup(tgt);
+
+ if (!tgtdup)
+ goto failure;
+ else if (src && !(srcdup = strdup(src)))
+ goto failure;
+ else if (!(m = malloc(sizeof *m)))
+ goto failure;
+
+ *m = (const struct fs_mountpoint)
+ {
+ .src = srcdup,
+ .tgt = tgtdup,
+ .update = fn,
+ .fs = fs,
+ .prv = pr
+ };
+
+ if (!fs_mphead)
+ fs_mphead = m;
+ else if (fs_mptail)
+ fs_mptail->next = m;
+
+ fs_mptail = m;
+ return 0;
+
+failure:
+ free(srcdup);
+ free(tgtdup);
+ free(m);
+ return -1;
+}
diff --git a/src/fs/src/mp_from_path.c b/src/fs/src/mp_from_path.c
new file mode 100644
index 0000000..5e69ea6
--- /dev/null
+++ b/src/fs/src/mp_from_path.c
@@ -0,0 +1,40 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <string.h>
+
+int fs_mp_from_path(const char *const path, struct fs_mp *const mp)
+{
+ for (const struct fs_mountpoint *p = fs_mphead; p; p = p->next)
+ if (!strcmp(path, p->tgt))
+ {
+ *mp = (const struct fs_mp)
+ {
+ .fs = p->fs,
+ .prv = p->prv,
+ .src = p->src,
+ .tgt= p->tgt
+ };
+
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/src/fs/src/mps_from_path.c b/src/fs/src/mps_from_path.c
new file mode 100644
index 0000000..a3d5510
--- /dev/null
+++ b/src/fs/src/mps_from_path.c
@@ -0,0 +1,89 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+static struct fs_mp *find(const char *const path, size_t *const out)
+{
+ struct fs_mp *ret = NULL;
+ size_t n = 0;
+
+ for (const struct fs_mountpoint *p = fs_mphead; p; p = p->next)
+ {
+ const size_t len = strlen(p->tgt);
+
+ if (!strncmp(p->tgt, path, len))
+ {
+ const size_t sz = n + 1;
+ struct fs_mp *const m = realloc(ret, sz * sizeof *m);
+
+ if (!m)
+ goto failure;
+
+ m[n++] = (const struct fs_mp)
+ {
+ .fs = p->fs,
+ .prv = p->prv,
+ .src = p->src,
+ .tgt = p->tgt
+ };
+
+ ret = m;
+ }
+ }
+
+ *out = n;
+ return ret;
+
+failure:
+ free(ret);
+ return NULL;
+}
+
+static void sort(struct fs_mp *const m, const size_t n)
+{
+ for (size_t i = 1; i < n; i++)
+ {
+ struct fs_mp am = m[i];
+ const size_t len = strlen(am.tgt);
+ size_t j = i;
+
+ while (j && len < strlen(m[j - 1].tgt))
+ {
+ m[j] = m [j - 1];
+ j--;
+ }
+
+ m[j] = am;
+ }
+}
+
+struct fs_mp *fs_mps_from_path(const char *const path, size_t *const n)
+{
+ struct fs_mp *const ret = find(path, n);
+
+ if (!ret)
+ return NULL;
+
+ sort(ret, *n);
+ return ret;
+}
diff --git a/src/fs/src/next.c b/src/fs/src/next.c
new file mode 100644
index 0000000..dac2352
--- /dev/null
+++ b/src/fs/src/next.c
@@ -0,0 +1,59 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+int fs_next(const char *const path, char **const out, size_t *const i)
+{
+ char *next = NULL;
+
+ if (*i >= strlen(path))
+ goto failure;
+
+ const char *const s = &path[*i];
+
+ if (*s == '/')
+ {
+ if (!(next = strdup("/")))
+ goto failure;
+
+ (*i)++;
+ *out = next;
+ return 0;
+ }
+
+ const char *sep = strchr(s, '/');
+ next = sep ? strndup(s, sep - s) : strdup(s);
+
+ if (!next)
+ goto failure;
+ else if (sep)
+ while (*sep && *sep == '/')
+ sep++;
+
+ *i += sep ? sep - s : strlen(s);
+ *out = next;
+ return 0;
+
+failure:
+ free(next);
+ return -1;
+}
diff --git a/src/fs/src/parent.c b/src/fs/src/parent.c
new file mode 100644
index 0000000..34ed0ab
--- /dev/null
+++ b/src/fs/src/parent.c
@@ -0,0 +1,33 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *fs_parent(const char *const path)
+{
+ char *ret = NULL;
+ const char *const sep = strrchr(path, '/');
+
+ if (!sep || !(ret = strndup(path, sep - path + 1)))
+ return NULL;
+
+ return ret;
+}
diff --git a/src/fs/src/register.c b/src/fs/src/register.c
new file mode 100644
index 0000000..a503d2a
--- /dev/null
+++ b/src/fs/src/register.c
@@ -0,0 +1,42 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <stdlib.h>
+
+int fs_register(const struct fs *const fs)
+{
+ struct fs_register *const r = malloc(sizeof *r);
+
+ if (!r)
+ return -1;
+ else if (!fs_rhead)
+ fs_rhead = r;
+ else if (fs_rtail)
+ fs_rtail->next = r;
+
+ fs_rtail = r;
+
+ *r = (const struct fs_register)
+ {
+ .fs = fs
+ };
+
+ return 0;
+}
diff --git a/src/fs/src/relpath.c b/src/fs/src/relpath.c
new file mode 100644
index 0000000..e7414c2
--- /dev/null
+++ b/src/fs/src/relpath.c
@@ -0,0 +1,43 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <string.h>
+
+const char *fs_relpath(const char *const path)
+{
+ size_t lastn = 0;
+ const struct fs_mountpoint *mp = NULL;
+
+ for (const struct fs_mountpoint *m = fs_mphead; m; m = m->next)
+ {
+ const size_t n = strlen(m->tgt);
+
+ if (!strncmp(m->tgt, path, n) && lastn < n)
+ {
+ lastn = n;
+ mp = m;
+ }
+ }
+
+ if (!mp)
+ return NULL;
+
+ return path + strlen(mp->tgt);
+}
diff --git a/src/fs/src/update.c b/src/fs/src/update.c
new file mode 100644
index 0000000..5f47eb3
--- /dev/null
+++ b/src/fs/src/update.c
@@ -0,0 +1,30 @@
+/*
+ * wanix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <fs/fs.h>
+#include <fs/types.h>
+#include <stddef.h>
+
+int fs_update(void)
+{
+ for (const struct fs_mountpoint *m = fs_mphead; m; m = m->next)
+ if (m->update && m->update(m->prv))
+ return -1;
+
+ return 0;
+}