--- /dev/null
+#include "overlayfs.h"
+
+#include "heap.h"
+#include "utils.h"
+#include "tmpfs.h"
+
+#include <stdint.h>
+
+struct overlayfs {
+ fs_node_t* lower;
+ fs_node_t* upper;
+};
+
+struct overlay_node {
+ fs_node_t vfs;
+ struct overlayfs* ofs;
+
+ fs_node_t* lower;
+ fs_node_t* upper;
+
+ char path[256];
+};
+
+static struct fs_node* overlay_finddir_impl(struct fs_node* node, char* name);
+
+static void overlay_str_copy_n(char* dst, size_t dst_sz, const char* src, size_t src_n) {
+ if (!dst || dst_sz == 0) return;
+ size_t i = 0;
+ for (; i + 1 < dst_sz && i < src_n; i++) {
+ char c = src[i];
+ if (c == 0) break;
+ dst[i] = c;
+ }
+ dst[i] = 0;
+}
+
+static uint32_t overlay_read_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
+ if (!node) return 0;
+ struct overlay_node* on = (struct overlay_node*)node;
+
+ fs_node_t* src = on->upper ? on->upper : on->lower;
+ if (!src) return 0;
+ return vfs_read(src, offset, size, buffer);
+}
+
+static fs_node_t* overlay_copy_up_file(struct overlay_node* on) {
+ if (!on || on->upper) return on ? on->upper : NULL;
+ if (!on->ofs || !on->ofs->upper) return NULL;
+ if (!on->lower) return NULL;
+ if (on->vfs.flags != FS_FILE) return NULL;
+
+ uint32_t len = on->lower->length;
+ uint8_t* buf = NULL;
+ if (len) {
+ buf = (uint8_t*)kmalloc(len);
+ if (!buf) return NULL;
+ uint32_t rd = vfs_read(on->lower, 0, len, buf);
+ if (rd != len) {
+ if (buf) kfree(buf);
+ return NULL;
+ }
+ }
+
+ fs_node_t* created = tmpfs_create_file(on->ofs->upper, on->path, buf, len);
+ if (buf) kfree(buf);
+ if (!created) return NULL;
+
+ on->upper = created;
+ on->vfs.length = created->length;
+ on->vfs.inode = created->inode;
+ return created;
+}
+
+static uint32_t overlay_write_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
+ if (!node) return 0;
+ struct overlay_node* on = (struct overlay_node*)node;
+
+ fs_node_t* dst = on->upper;
+ if (!dst) {
+ dst = overlay_copy_up_file(on);
+ }
+ if (!dst) return 0;
+
+ uint32_t wr = vfs_write(dst, offset, size, buffer);
+ if (dst->length > on->vfs.length) on->vfs.length = dst->length;
+ return wr;
+}
+
+static fs_node_t* overlay_wrap_child(struct overlay_node* parent, const char* name, fs_node_t* lower_child, fs_node_t* upper_child) {
+ if (!parent || !parent->ofs || !name) return NULL;
+ if (!lower_child && !upper_child) return NULL;
+
+ struct overlay_node* c = (struct overlay_node*)kmalloc(sizeof(*c));
+ if (!c) return NULL;
+ memset(c, 0, sizeof(*c));
+
+ strcpy(c->vfs.name, name);
+ c->ofs = parent->ofs;
+ c->lower = lower_child;
+ c->upper = upper_child;
+
+ if (upper_child) {
+ c->vfs.flags = upper_child->flags;
+ c->vfs.inode = upper_child->inode;
+ c->vfs.length = upper_child->length;
+ } else {
+ c->vfs.flags = lower_child->flags;
+ c->vfs.inode = lower_child->inode;
+ c->vfs.length = lower_child->length;
+ }
+
+ c->vfs.read = &overlay_read_impl;
+ c->vfs.write = (c->vfs.flags == FS_FILE) ? &overlay_write_impl : 0;
+ c->vfs.open = 0;
+ c->vfs.close = 0;
+ c->vfs.finddir = (c->vfs.flags == FS_DIRECTORY) ? &overlay_finddir_impl : 0;
+
+ if (parent->path[0] == 0) {
+ c->path[0] = '/';
+ c->path[1] = 0;
+ } else {
+ strcpy(c->path, parent->path);
+ }
+
+ size_t l = strlen(c->path);
+ if (l == 0) {
+ c->path[0] = '/';
+ c->path[1] = 0;
+ l = 1;
+ }
+ if (l + 1 < sizeof(c->path) && c->path[l - 1] != '/') {
+ c->path[l++] = '/';
+ c->path[l] = 0;
+ }
+
+ size_t cur = strlen(c->path);
+ if (cur + 1 < sizeof(c->path)) {
+ size_t rem = sizeof(c->path) - cur - 1;
+ overlay_str_copy_n(c->path + cur, rem + 1, name, strlen(name));
+ }
+
+ return &c->vfs;
+}
+
+static struct fs_node* overlay_finddir_impl(struct fs_node* node, char* name) {
+ if (!node || !name) return 0;
+ if (node->flags != FS_DIRECTORY) return 0;
+
+ struct overlay_node* dir = (struct overlay_node*)node;
+
+ fs_node_t* upper_child = NULL;
+ fs_node_t* lower_child = NULL;
+
+ if (dir->upper && dir->upper->finddir) {
+ upper_child = dir->upper->finddir(dir->upper, name);
+ }
+ if (dir->lower && dir->lower->finddir) {
+ lower_child = dir->lower->finddir(dir->lower, name);
+ }
+
+ if (!upper_child && !lower_child) return 0;
+ return overlay_wrap_child(dir, name, lower_child, upper_child);
+}
+
+fs_node_t* overlayfs_create_root(fs_node_t* lower_root, fs_node_t* upper_root) {
+ if (!lower_root || !upper_root) return NULL;
+
+ struct overlayfs* ofs = (struct overlayfs*)kmalloc(sizeof(*ofs));
+ if (!ofs) return NULL;
+ ofs->lower = lower_root;
+ ofs->upper = upper_root;
+
+ struct overlay_node* root = (struct overlay_node*)kmalloc(sizeof(*root));
+ if (!root) {
+ kfree(ofs);
+ return NULL;
+ }
+ memset(root, 0, sizeof(*root));
+
+ root->ofs = ofs;
+ root->lower = lower_root;
+ root->upper = upper_root;
+
+ root->vfs.name[0] = 0;
+ root->vfs.flags = FS_DIRECTORY;
+ root->vfs.inode = upper_root->inode;
+ root->vfs.length = 0;
+ root->vfs.read = 0;
+ root->vfs.write = 0;
+ root->vfs.open = 0;
+ root->vfs.close = 0;
+ root->vfs.finddir = &overlay_finddir_impl;
+
+ root->path[0] = 0;
+
+ return &root->vfs;
+}
static uint32_t g_tmpfs_next_inode = 1;
+static struct fs_node* tmpfs_finddir_impl(struct fs_node* node, char* name);
+static uint32_t tmpfs_write_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer);
+
static struct tmpfs_node* tmpfs_node_alloc(const char* name, uint32_t flags) {
struct tmpfs_node* n = (struct tmpfs_node*)kmalloc(sizeof(*n));
if (!n) return NULL;
dir->first_child = child;
}
+static struct tmpfs_node* tmpfs_child_ensure_dir(struct tmpfs_node* dir, const char* name) {
+ if (!dir || !name || name[0] == 0) return NULL;
+ struct tmpfs_node* existing = tmpfs_child_find(dir, name);
+ if (existing) {
+ if (existing->vfs.flags != FS_DIRECTORY) return NULL;
+ return existing;
+ }
+
+ struct tmpfs_node* nd = tmpfs_node_alloc(name, FS_DIRECTORY);
+ if (!nd) return NULL;
+ nd->vfs.read = 0;
+ nd->vfs.write = 0;
+ nd->vfs.open = 0;
+ nd->vfs.close = 0;
+ nd->vfs.finddir = &tmpfs_finddir_impl;
+ tmpfs_child_add(dir, nd);
+ return nd;
+}
+
+static int tmpfs_split_next(const char** p_inout, char* out, size_t out_sz) {
+ if (!p_inout || !*p_inout || !out || out_sz == 0) return 0;
+ const char* p = *p_inout;
+ while (*p == '/') p++;
+ if (*p == 0) {
+ *p_inout = p;
+ out[0] = 0;
+ return 0;
+ }
+
+ size_t i = 0;
+ while (*p != 0 && *p != '/') {
+ if (i + 1 < out_sz) {
+ out[i++] = *p;
+ }
+ p++;
+ }
+ out[i] = 0;
+ while (*p == '/') p++;
+ *p_inout = p;
+ return out[0] != 0;
+}
+
static uint32_t tmpfs_read_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
if (!node || !buffer) return 0;
if (node->flags != FS_FILE) return 0;
tmpfs_child_add(dir, f);
return 0;
}
+
+int tmpfs_mkdir_p(fs_node_t* root_dir, const char* path) {
+ if (!root_dir || root_dir->flags != FS_DIRECTORY) return -1;
+ if (!path) return -1;
+
+ struct tmpfs_node* cur = (struct tmpfs_node*)root_dir;
+ const char* p = path;
+ char part[128];
+
+ while (tmpfs_split_next(&p, part, sizeof(part))) {
+ struct tmpfs_node* next = tmpfs_child_ensure_dir(cur, part);
+ if (!next) return -1;
+ cur = next;
+ }
+
+ return 0;
+}
+
+fs_node_t* tmpfs_create_file(fs_node_t* root_dir, const char* path, const uint8_t* data, uint32_t len) {
+ if (!root_dir || root_dir->flags != FS_DIRECTORY) return NULL;
+ if (!path) return NULL;
+
+ struct tmpfs_node* cur = (struct tmpfs_node*)root_dir;
+ const char* p = path;
+ char part[128];
+ char leaf[128];
+ leaf[0] = 0;
+
+ while (tmpfs_split_next(&p, part, sizeof(part))) {
+ if (*p == 0) {
+ strcpy(leaf, part);
+ break;
+ }
+ struct tmpfs_node* next = tmpfs_child_ensure_dir(cur, part);
+ if (!next) return NULL;
+ cur = next;
+ }
+
+ if (leaf[0] == 0) return NULL;
+
+ struct tmpfs_node* existing = tmpfs_child_find(cur, leaf);
+ if (existing) {
+ if (existing->vfs.flags != FS_FILE) return NULL;
+ if (len && data) {
+ uint8_t* buf = (uint8_t*)kmalloc(len);
+ if (!buf) return NULL;
+ memcpy(buf, data, len);
+ (void)tmpfs_write_impl(&existing->vfs, 0, len, buf);
+ kfree(buf);
+ }
+ return &existing->vfs;
+ }
+
+ struct tmpfs_node* f = tmpfs_node_alloc(leaf, FS_FILE);
+ if (!f) return NULL;
+
+ f->vfs.read = &tmpfs_read_impl;
+ f->vfs.write = &tmpfs_write_impl;
+ f->vfs.open = 0;
+ f->vfs.close = 0;
+ f->vfs.finddir = 0;
+
+ if (len && data) {
+ f->data = (uint8_t*)kmalloc(len);
+ if (!f->data) {
+ kfree(f);
+ return NULL;
+ }
+ memcpy(f->data, data, len);
+ f->cap = len;
+ f->vfs.length = len;
+ }
+
+ tmpfs_child_add(cur, f);
+ return &f->vfs;
+}
static const char path[] = "/bin/init.elf";
int fd = sys_open(path, 0);
if (fd < 0) {
- sys_write(1, "[init] open failed\n", 18);
+ sys_write(1, "[init] open failed\n", (uint32_t)(sizeof("[init] open failed\n") - 1));
sys_exit(1);
}
uint8_t hdr[4];
int rd = sys_read(fd, hdr, (uint32_t)sizeof(hdr));
if (sys_close(fd) < 0) {
- sys_write(1, "[init] close failed\n", 19);
+ sys_write(1, "[init] close failed\n", (uint32_t)(sizeof("[init] close failed\n") - 1));
sys_exit(1);
}
sys_write(1, "[init] open/read/close OK (ELF magic)\n",
(uint32_t)(sizeof("[init] open/read/close OK (ELF magic)\n") - 1));
} else {
- sys_write(1, "[init] read failed or bad header\n", 30);
+ sys_write(1, "[init] read failed or bad header\n",
+ (uint32_t)(sizeof("[init] read failed or bad header\n") - 1));
sys_exit(1);
}
fd = sys_open("/bin/init.elf", 0);
if (fd < 0) {
- sys_write(1, "[init] open2 failed\n", 19);
+ sys_write(1, "[init] overlay open failed\n",
+ (uint32_t)(sizeof("[init] overlay open failed\n") - 1));
+ sys_exit(1);
+ }
+
+ uint8_t orig0 = 0;
+ if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_read(fd, &orig0, 1) != 1) {
+ sys_write(1, "[init] overlay read failed\n",
+ (uint32_t)(sizeof("[init] overlay read failed\n") - 1));
+ sys_exit(1);
+ }
+
+ uint8_t x = (uint8_t)(orig0 ^ 0xFF);
+ if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_write(fd, &x, 1) != 1) {
+ sys_write(1, "[init] overlay write failed\n",
+ (uint32_t)(sizeof("[init] overlay write failed\n") - 1));
+ sys_exit(1);
+ }
+
+ if (sys_close(fd) < 0) {
+ sys_write(1, "[init] overlay close failed\n",
+ (uint32_t)(sizeof("[init] overlay close failed\n") - 1));
+ sys_exit(1);
+ }
+
+ fd = sys_open("/bin/init.elf", 0);
+ if (fd < 0) {
+ sys_write(1, "[init] overlay open2 failed\n",
+ (uint32_t)(sizeof("[init] overlay open2 failed\n") - 1));
+ sys_exit(1);
+ }
+
+ uint8_t chk = 0;
+ if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_read(fd, &chk, 1) != 1 || chk != x) {
+ sys_write(1, "[init] overlay verify failed\n",
+ (uint32_t)(sizeof("[init] overlay verify failed\n") - 1));
+ sys_exit(1);
+ }
+
+ if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_write(fd, &orig0, 1) != 1) {
+ sys_write(1, "[init] overlay restore failed\n",
+ (uint32_t)(sizeof("[init] overlay restore failed\n") - 1));
+ sys_exit(1);
+ }
+
+ if (sys_close(fd) < 0) {
+ sys_write(1, "[init] overlay close2 failed\n",
+ (uint32_t)(sizeof("[init] overlay close2 failed\n") - 1));
+ sys_exit(1);
+ }
+
+ sys_write(1, "[init] overlay copy-up OK\n",
+ (uint32_t)(sizeof("[init] overlay copy-up OK\n") - 1));
+
+ fd = sys_open("/bin/init.elf", 0);
+ if (fd < 0) {
+ sys_write(1, "[init] open2 failed\n", (uint32_t)(sizeof("[init] open2 failed\n") - 1));
sys_exit(1);
}
struct stat st;
if (sys_fstat(fd, &st) < 0) {
- sys_write(1, "[init] fstat failed\n", 19);
+ sys_write(1, "[init] fstat failed\n", (uint32_t)(sizeof("[init] fstat failed\n") - 1));
sys_exit(1);
}
if ((st.st_mode & S_IFMT) != S_IFREG || st.st_size == 0) {
- sys_write(1, "[init] fstat bad\n", 16);
+ sys_write(1, "[init] fstat bad\n", (uint32_t)(sizeof("[init] fstat bad\n") - 1));
sys_exit(1);
}
if (sys_lseek(fd, 0, SEEK_SET) < 0) {
- sys_write(1, "[init] lseek set failed\n", 24);
+ sys_write(1, "[init] lseek set failed\n",
+ (uint32_t)(sizeof("[init] lseek set failed\n") - 1));
sys_exit(1);
}
uint8_t m2[4];
if (sys_read(fd, m2, 4) != 4) {
- sys_write(1, "[init] read2 failed\n", 19);
+ sys_write(1, "[init] read2 failed\n", (uint32_t)(sizeof("[init] read2 failed\n") - 1));
sys_exit(1);
}
if (m2[0] != 0x7F || m2[1] != 'E' || m2[2] != 'L' || m2[3] != 'F') {
- sys_write(1, "[init] lseek/read mismatch\n", 27);
+ sys_write(1, "[init] lseek/read mismatch\n",
+ (uint32_t)(sizeof("[init] lseek/read mismatch\n") - 1));
sys_exit(1);
}
if (sys_close(fd) < 0) {
- sys_write(1, "[init] close2 failed\n", 20);
+ sys_write(1, "[init] close2 failed\n", (uint32_t)(sizeof("[init] close2 failed\n") - 1));
sys_exit(1);
}
if (sys_stat("/bin/init.elf", &st) < 0) {
- sys_write(1, "[init] stat failed\n", 18);
+ sys_write(1, "[init] stat failed\n", (uint32_t)(sizeof("[init] stat failed\n") - 1));
sys_exit(1);
}
if ((st.st_mode & S_IFMT) != S_IFREG || st.st_size == 0) {
- sys_write(1, "[init] stat bad\n", 15);
+ sys_write(1, "[init] stat bad\n", (uint32_t)(sizeof("[init] stat bad\n") - 1));
sys_exit(1);
}
- sys_write(1, "[init] lseek/stat/fstat OK\n", 27);
+ sys_write(1, "[init] lseek/stat/fstat OK\n",
+ (uint32_t)(sizeof("[init] lseek/stat/fstat OK\n") - 1));
fd = sys_open("/tmp/hello.txt", 0);
if (fd < 0) {
- sys_write(1, "[init] tmpfs open failed\n", 24);
+ sys_write(1, "[init] tmpfs open failed\n",
+ (uint32_t)(sizeof("[init] tmpfs open failed\n") - 1));
sys_exit(1);
}
if (sys_stat("/tmp/hello.txt", &st) < 0) {
- sys_write(1, "[init] tmpfs stat failed\n", 24);
+ sys_write(1, "[init] tmpfs stat failed\n",
+ (uint32_t)(sizeof("[init] tmpfs stat failed\n") - 1));
sys_exit(1);
}
if ((st.st_mode & S_IFMT) != S_IFREG) {
- sys_write(1, "[init] tmpfs stat not reg\n", 26);
+ sys_write(1, "[init] tmpfs stat not reg\n",
+ (uint32_t)(sizeof("[init] tmpfs stat not reg\n") - 1));
sys_exit(1);
}
if (st.st_size == 0) {
- sys_write(1, "[init] tmpfs stat size 0\n", 25);
+ sys_write(1, "[init] tmpfs stat size 0\n",
+ (uint32_t)(sizeof("[init] tmpfs stat size 0\n") - 1));
sys_exit(1);
}
struct stat fst;
if (sys_fstat(fd, &fst) < 0) {
- sys_write(1, "[init] tmpfs fstat failed\n", 25);
+ sys_write(1, "[init] tmpfs fstat failed\n",
+ (uint32_t)(sizeof("[init] tmpfs fstat failed\n") - 1));
sys_exit(1);
}
if (fst.st_size != st.st_size) {
- sys_write(1, "[init] tmpfs stat size mismatch\n", 31);
+ sys_write(1, "[init] tmpfs stat size mismatch\n",
+ (uint32_t)(sizeof("[init] tmpfs stat size mismatch\n") - 1));
sys_exit(1);
}
int end = sys_lseek(fd, 0, SEEK_END);
if (end < 0 || (uint32_t)end != st.st_size) {
- sys_write(1, "[init] tmpfs lseek end bad\n", 27);
+ sys_write(1, "[init] tmpfs lseek end bad\n",
+ (uint32_t)(sizeof("[init] tmpfs lseek end bad\n") - 1));
sys_exit(1);
}
uint8_t eofb;
if (sys_read(fd, &eofb, 1) != 0) {
- sys_write(1, "[init] tmpfs eof read bad\n", 27);
+ sys_write(1, "[init] tmpfs eof read bad\n",
+ (uint32_t)(sizeof("[init] tmpfs eof read bad\n") - 1));
sys_exit(1);
}
if (sys_lseek(fd, 0, 999) >= 0) {
- sys_write(1, "[init] tmpfs lseek whence bad\n", 30);
+ sys_write(1, "[init] tmpfs lseek whence bad\n",
+ (uint32_t)(sizeof("[init] tmpfs lseek whence bad\n") - 1));
sys_exit(1);
}
if (sys_lseek(fd, 0, SEEK_SET) < 0) {
- sys_write(1, "[init] tmpfs lseek set failed\n", 30);
+ sys_write(1, "[init] tmpfs lseek set failed\n",
+ (uint32_t)(sizeof("[init] tmpfs lseek set failed\n") - 1));
sys_exit(1);
}
uint8_t tbuf[6];
if (sys_read(fd, tbuf, 5) != 5) {
- sys_write(1, "[init] tmpfs read failed\n", 24);
+ sys_write(1, "[init] tmpfs read failed\n",
+ (uint32_t)(sizeof("[init] tmpfs read failed\n") - 1));
sys_exit(1);
}
tbuf[5] = 0;
if (tbuf[0] != 'h' || tbuf[1] != 'e' || tbuf[2] != 'l' || tbuf[3] != 'l' || tbuf[4] != 'o') {
- sys_write(1, "[init] tmpfs bad data\n", 22);
+ sys_write(1, "[init] tmpfs bad data\n", (uint32_t)(sizeof("[init] tmpfs bad data\n") - 1));
sys_exit(1);
}
if (sys_close(fd) < 0) {
- sys_write(1, "[init] tmpfs close failed\n", 25);
+ sys_write(1, "[init] tmpfs close failed\n",
+ (uint32_t)(sizeof("[init] tmpfs close failed\n") - 1));
sys_exit(1);
}
if (sys_open("/tmp/does_not_exist", 0) >= 0) {
- sys_write(1, "[init] tmpfs open nonexist bad\n", 32);
+ sys_write(1, "[init] tmpfs open nonexist bad\n",
+ (uint32_t)(sizeof("[init] tmpfs open nonexist bad\n") - 1));
sys_exit(1);
}
fd = sys_open("/tmp/hello.txt", 0);
if (fd < 0) {
- sys_write(1, "[init] tmpfs open3 failed\n", 25);
+ sys_write(1, "[init] tmpfs open3 failed\n",
+ (uint32_t)(sizeof("[init] tmpfs open3 failed\n") - 1));
sys_exit(1);
}
if (sys_fstat(fd, &fst) < 0) {
- sys_write(1, "[init] tmpfs fstat2 failed\n", 26);
+ sys_write(1, "[init] tmpfs fstat2 failed\n",
+ (uint32_t)(sizeof("[init] tmpfs fstat2 failed\n") - 1));
sys_exit(1);
}
if (sys_lseek(fd, 0, SEEK_END) < 0) {
- sys_write(1, "[init] tmpfs lseek end2 failed\n", 31);
+ sys_write(1, "[init] tmpfs lseek end2 failed\n",
+ (uint32_t)(sizeof("[init] tmpfs lseek end2 failed\n") - 1));
sys_exit(1);
}
- static const char suf[] = "XYZ";
+ char suf[3];
+ suf[0] = 'X';
+ suf[1] = 'Y';
+ suf[2] = 'Z';
if (sys_write(fd, suf, 3) != 3) {
- sys_write(1, "[init] tmpfs write failed\n", 25);
+ sys_write(1, "[init] tmpfs write failed\n",
+ (uint32_t)(sizeof("[init] tmpfs write failed\n") - 1));
sys_exit(1);
}
if (sys_fstat(fd, &fst) < 0) {
- sys_write(1, "[init] tmpfs fstat3 failed\n", 26);
+ sys_write(1, "[init] tmpfs fstat3 failed\n",
+ (uint32_t)(sizeof("[init] tmpfs fstat3 failed\n") - 1));
sys_exit(1);
}
if (fst.st_size != st.st_size + 3) {
- sys_write(1, "[init] tmpfs size not grown\n", 27);
+ sys_write(1, "[init] tmpfs size not grown\n",
+ (uint32_t)(sizeof("[init] tmpfs size not grown\n") - 1));
sys_exit(1);
}
if (sys_lseek(fd, -3, SEEK_END) < 0) {
- sys_write(1, "[init] tmpfs lseek back failed\n", 31);
+ sys_write(1, "[init] tmpfs lseek back failed\n",
+ (uint32_t)(sizeof("[init] tmpfs lseek back failed\n") - 1));
sys_exit(1);
}
uint8_t s2[3];
if (sys_read(fd, s2, 3) != 3 || s2[0] != 'X' || s2[1] != 'Y' || s2[2] != 'Z') {
- sys_write(1, "[init] tmpfs suffix mismatch\n", 27);
+ sys_write(1, "[init] tmpfs suffix mismatch\n",
+ (uint32_t)(sizeof("[init] tmpfs suffix mismatch\n") - 1));
sys_exit(1);
}
if (sys_close(fd) < 0) {
- sys_write(1, "[init] tmpfs close3 failed\n", 26);
+ sys_write(1, "[init] tmpfs close3 failed\n",
+ (uint32_t)(sizeof("[init] tmpfs close3 failed\n") - 1));
sys_exit(1);
}
- sys_write(1, "[init] tmpfs/mount OK\n", 22);
+ sys_write(1, "[init] tmpfs/mount OK\n", (uint32_t)(sizeof("[init] tmpfs/mount OK\n") - 1));
enum { NCHILD = 100 };
int children[NCHILD];