diff options
Diffstat (limited to 'src/aio')
| -rw-r--r-- | src/aio/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | src/aio/include/aio.h | 39 | ||||
| -rw-r--r-- | src/aio/private_include/aio/types.h | 34 | ||||
| -rw-r--r-- | src/aio/src/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/aio/src/free.c (renamed from src/aio/src/close.c) | 13 | ||||
| -rw-r--r-- | src/aio/src/mkdir.c | 137 | ||||
| -rw-r--r-- | src/aio/src/mount.c | 175 | ||||
| -rw-r--r-- | src/aio/src/open.c | 102 | ||||
| -rw-r--r-- | src/aio/src/poll.c | 74 | ||||
| -rw-r--r-- | src/aio/src/stat.c | 118 | ||||
| -rw-r--r-- | src/aio/src/write.c | 79 |
11 files changed, 755 insertions, 36 deletions
diff --git a/src/aio/CMakeLists.txt b/src/aio/CMakeLists.txt index 3f4561a..a335457 100644 --- a/src/aio/CMakeLists.txt +++ b/src/aio/CMakeLists.txt @@ -1,6 +1,11 @@ set(src - "src/close.c" - "src/open.c" + src/free.c + src/mkdir.c + src/mount.c + src/open.c + src/poll.c ) add_library(aio ${src}) -target_include_directories(aio PUBLIC "include" PRIVATE "private_include") +add_subdirectory(src) +target_include_directories(aio PUBLIC include PRIVATE private_include) +target_link_libraries(aio PUBLIC fs INTERFACE state) diff --git a/src/aio/include/aio.h b/src/aio/include/aio.h index f9f76cb..cea6ee1 100644 --- a/src/aio/include/aio.h +++ b/src/aio/include/aio.h @@ -1,5 +1,5 @@ /* - * wanix, a Unix-like operating system for WebAssembly + * 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 @@ -19,17 +19,40 @@ #ifndef AIO_H #define AIO_H +#include <fs/fs.h> +#include <sys/types.h> +#include <state.h> +#include <stdbool.h> #include <stddef.h> -enum +struct aio_poll { - AIO_POLLIN = 1, - AIO_POLLOUT = 1 << 1 + const struct aio *aio; + bool done; + int error; + struct aio_poll *prev, *next; }; -struct aio *aio_open(const char *path, const char *mode); -int aio_poll(struct aio **io, size_t n); -int aio_event(const struct aio *io, int ev); -int aio_close(struct aio *io); +struct aio_done +{ + int (*f)(enum state state, void *args); + void *args; +}; + +struct aio_mount +{ + struct fs_mount mount; + const char *type; +}; + +struct aio *aio_mount(const struct aio_mount *m, const struct aio_done *d); +struct aio *aio_mkdir(const struct fs_mkdir *m, const struct aio_done *d); +struct aio *aio_open(const struct fs_open *o, const struct aio_done *d); +struct aio *aio_read(const struct fs_read *r, const struct aio_done *d); +struct aio *aio_write(const struct fs_write *w, const struct aio_done *d); +struct aio *aio_close(const struct fs_close *c, const struct aio_done *d); +struct aio *aio_stat(const struct fs_stat *s, const struct aio_done *d); +int aio_poll(struct aio_poll *p, int ms); +void aio_free(struct aio *io); #endif diff --git a/src/aio/private_include/aio/types.h b/src/aio/private_include/aio/types.h index 31ee414..32a7545 100644 --- a/src/aio/private_include/aio/types.h +++ b/src/aio/private_include/aio/types.h @@ -1,16 +1,32 @@ -#ifndef AIO_PRV_OPEN_H -#define AIO_PRV_OPEN_H +/* + * 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/>. + */ -enum aio_state -{ - AIO_OK, - AIO_AGAIN, - AIO_FATAL -}; +#ifndef AIO_TYPES_H +#define AIO_TYPES_H + +#include <aio.h> +#include <fs/fs.h> struct aio { - enum aio_state (*next)(struct aio *); + int error; + struct fs_ret r; + struct aio_done done; }; #endif diff --git a/src/aio/src/CMakeLists.txt b/src/aio/src/CMakeLists.txt new file mode 100644 index 0000000..8848842 --- /dev/null +++ b/src/aio/src/CMakeLists.txt @@ -0,0 +1,9 @@ +target_sources(aio PRIVATE + free.c + mkdir.c + mount.c + open.c + poll.c + stat.c + write.c +) diff --git a/src/aio/src/close.c b/src/aio/src/free.c index a6067a8..3a84f1b 100644 --- a/src/aio/src/close.c +++ b/src/aio/src/free.c @@ -1,5 +1,5 @@ /* - * wanix, a Unix-like operating system for WebAssembly + * 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 @@ -17,18 +17,9 @@ */ #include <aio.h> -#include <errno.h> -#include <stdio.h> #include <stdlib.h> -int aio_close(struct aio *const aio) +void aio_free(struct aio *const aio) { - if (!aio) - { - errno = EINVAL; - return EOF; - } - free(aio); - return 0; } diff --git a/src/aio/src/mkdir.c b/src/aio/src/mkdir.c new file mode 100644 index 0000000..3a7fae6 --- /dev/null +++ b/src/aio/src/mkdir.c @@ -0,0 +1,137 @@ +/* + * 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 <aio.h> +#include <aio/types.h> +#include <fs/fs.h> +#include <fs/inode.h> +#include <sys/stat.h> +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +struct mkdir +{ + struct fs_mkdir mkdir; + struct aio_done done; + char *path, *parent; + struct aio *aio; +}; + +static void free_mkdir(struct mkdir *const mk) +{ + if (mk) + { + free(mk->path); + free(mk->parent); + } + + free(mk); +} + +static int done(const enum state state, void *const args) +{ + int ret = 0; + struct mkdir *const mk = args; + const struct aio_done *const d = &mk->done; + + if (d->f) + ret = d->f(state, d->args); + + free_mkdir(mk); + return ret; +} + +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 mkdir *const mk = args; + struct aio *const aio = mk->aio; + const struct fs *const fs = mp->fs; + const char *path = mk->path; + struct fs_ret r; + + path += strlen(mp->tgt) + strlen(relpath); + mk->mkdir.path = path; + + if (fs->mkdir(&mk->mkdir, mp, inode, &r)) + goto failure; + + aio->r = r; + return 0; + +failure: + aio->error = errno; + aio->done = mk->done; + free_mkdir(mk); + return -1; +} + +struct aio *aio_mkdir(const struct fs_mkdir *const m, + const struct aio_done *const d) +{ + struct aio *aio = NULL; + struct mkdir *mk = NULL; + char *const pathdup = strdup(m->path), *parent = NULL; + + if (!pathdup + || !(parent = fs_parent(m->path)) + || !(mk = malloc(sizeof *mk)) + || !(aio = malloc(sizeof *aio))) + goto failure; + + *mk = (const struct mkdir) + { + .path = pathdup, + .parent = parent, + .aio = aio, + .mkdir = *m + }; + + *aio = (const struct aio) + { + .done = + { + .args = mk, + .f = done + } + }; + + const struct inode_search s = + { + .path = parent, + .done = search_done, + .args = mk + }; + + if (d) + mk->done = *d; + else if (inode_search(&s, &aio->r)) + goto failure; + + return aio; + +failure: + free(mk); + free(aio); + free(parent); + free(pathdup); + return NULL; +} diff --git a/src/aio/src/mount.c b/src/aio/src/mount.c new file mode 100644 index 0000000..e90d8de --- /dev/null +++ b/src/aio/src/mount.c @@ -0,0 +1,175 @@ +/* + * 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 <aio.h> +#include <aio/types.h> +#include <fs/fs.h> +#include <fs/inode.h> +#include <sys/types.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +struct mount +{ + char *src, *tgt; + struct aio *aio; + const struct fs *fs; + struct fs_mount mount; + struct aio_done done; +}; + +static void free_mount(struct mount *const m) +{ + if (m) + { + free(m->src); + free(m->tgt); + } + + free(m); +} + +static int done(const enum state state, void *const args) +{ + int ret = 0; + struct mount *const m = args; + const struct aio_done *const d = &m->done; + + if (d->f) + ret = d->f(state, d->args); + + free_mount(m); + return ret; +} + +static int search_done(const enum state s, const char *const relpath, + const struct fs_mp *const mp, const union inode_result *const inode, + void *const args) +{ + struct mount *const m = args; + struct aio *const aio = m->aio; + const struct fs *const fs = m->fs; + + if (strcmp(m->tgt, "/")) + { + if (!inode) + { + aio->error = ENOENT; + goto failure; + } + else if (mp->fs->iops.flags(inode) & INODE_MOUNTPOINT) + { + aio->error = EBUSY; + goto failure; + } + } + + if (fs->mount(&m->mount, &aio->r)) + { + aio->error = errno; + goto failure; + } + + return 0; + +failure: + aio->done = m->done; + free_mount(m); + return -1; +} + +struct aio *aio_mount(const struct aio_mount *const am, + const struct aio_done *const d) +{ + struct aio *aio = NULL; + const struct fs_mount *const m = &am->mount; + const struct fs *const fs = fs_from_type(am->type); + char *srcdup = NULL, *tgtdup = NULL; + struct mount *pm = NULL; + struct fs_mp mp; + + if (!fs) + { + errno = ENODEV; + goto failure; + } + else if (!m->src && fs->flags & FS_DEV_REQUIRED) + { + errno = ENOTBLK; + goto failure; + } + else if (!fs_mp_from_path(m->tgt, &mp) + && m->src && !strcmp(mp.src, m->src)) + { + errno = EBUSY; + goto failure; + } + else if ((m->src && !(srcdup = strdup(m->src))) + || !(tgtdup = strdup(m->tgt)) + || !(pm = malloc(sizeof *pm)) + || !(aio = malloc(sizeof *aio))) + goto failure; + + const struct inode_search s = + { + .path = m->tgt, + .done = search_done, + .args = pm + }; + + *pm = (const struct mount) + { + .aio = aio, + .src = srcdup, + .tgt = tgtdup, + .fs = fs, + .mount = + { + .src = srcdup, + .tgt = tgtdup, + .mode = m->mode, + .gid = m->gid, + .uid = m->uid + } + }; + + *aio = (const struct aio) + { + .done = + { + .f = done, + .args = pm + } + }; + + if (inode_search(&s, &aio->r)) + goto failure; + + if (d) + pm->done = *d; + + return aio; + +failure: + free(tgtdup); + free(srcdup); + free(pm); + free(aio); + return NULL; +} diff --git a/src/aio/src/open.c b/src/aio/src/open.c index 89fbbba..f3a84da 100644 --- a/src/aio/src/open.c +++ b/src/aio/src/open.c @@ -1,5 +1,5 @@ /* - * wanix, a Unix-like operating system for WebAssembly + * 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 @@ -16,18 +16,110 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include <aio.h> +#include <fs/fs.h> #include <aio/types.h> +#include <state.h> +#include <errno.h> #include <stddef.h> #include <stdlib.h> -struct aio *aio_open(const char *const path, const char *const mode) +struct open { - struct aio *const ret = malloc(sizeof *ret); + struct aio *aio; + struct fs_open open; + struct aio_done done; +}; - if (!ret) +static int done(const enum state s, void *const args) +{ + struct open *const o = args; + + if (o->done.f) + o->done.f(s, o->done.args); + + free(o); + return 0; +} + +static enum state open_done(void *const args) +{ + return STATE_OK; +} + +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 open *const o = args; + struct aio *const aio = o->aio; + const struct fs *const fs = mp->fs; + + if (!inode) + { + aio->error = ENOENT; + goto failure; + } + + aio->r = (const struct fs_ret) + { + .f = open_done, + .args = o + }; + + if (fs->open(&o->open, mp, inode, &aio->r)) + { + aio->error = errno; + goto failure; + } + + return 0; + +failure: + aio->done = o->done; + return -1; +} + +struct aio *aio_open(const struct fs_open *const op, + const struct aio_done *const d) +{ + struct aio *aio = NULL; + struct open *const o = malloc(sizeof *o); + + if (!o || !(aio = malloc(sizeof *aio))) goto failure; + *o = (const struct open) + { + .aio = aio, + .open = *op + }; + + *aio = (const struct aio) + { + .done = + { + .f = done, + .args = o + } + }; + + const struct inode_search s = + { + .path = op->path, + .done = search_done, + .args = o + }; + + if (inode_search(&s, &aio->r)) + goto failure; + + if (d) + o->done = *d; + + return aio; + failure: - free(ret); + free(aio); return NULL; } diff --git a/src/aio/src/poll.c b/src/aio/src/poll.c new file mode 100644 index 0000000..615f2de --- /dev/null +++ b/src/aio/src/poll.c @@ -0,0 +1,74 @@ +/* + * 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 <aio.h> +#include <aio/types.h> +#include <state.h> +#include <stdbool.h> +#include <stddef.h> +#include <time.h> + +int aio_poll(struct aio_poll *const poll, int ms) +{ + struct timespec init; + + if (ms > 0 && clock_gettime(CLOCK_REALTIME, &init)) + return -1; + + do + { + for (struct aio_poll *p = poll; p; p = p->next) + { + const struct aio *const aio = p->aio; + const struct fs_ret *const r = &aio->r; + const enum state s = r->f(r->args); + + switch (s) + { + case STATE_AGAIN: + break; + + case STATE_FATAL: + p->error = aio->error; + /* Fall through */ + case STATE_OK: + { + const struct aio_done *const d = &aio->done; + + if (d->f) + return d->f(s, d->args) ? -1 : 1; + + p->done = true; + return 1; + } + } + } + + if (ms > 0) + { + struct timespec after; + + if (clock_gettime(CLOCK_REALTIME, &after)) + return -1; + + /* TODO */ + } + } while (ms); + + return 0; +} diff --git a/src/aio/src/stat.c b/src/aio/src/stat.c new file mode 100644 index 0000000..9a7df76 --- /dev/null +++ b/src/aio/src/stat.c @@ -0,0 +1,118 @@ +/* + * 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 <aio.h> +#include <aio/types.h> +#include <fs/fs.h> +#include <fs/inode.h> +#include <sys/types.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +struct stat_prv +{ + struct fs_stat stat; + struct aio_done done; + struct aio *aio; +}; + +static int done(const enum state state, void *const args) +{ + int ret = 0; + struct stat_prv *const p = args; + const struct aio_done *const d = &p->done; + + if (d->f) + ret = d->f(state, d->args); + + free(p); + return ret; +} + +static int search_done(const enum state s, const char *const relpath, + const struct fs_mp *const mp, const union inode_result *const inode, + void *const args) +{ + struct stat_prv *const p = args; + struct aio *const aio = p->aio; + const struct fs *const fs = mp->fs; + + if (!inode) + { + aio->error = ENOENT; + goto failure; + } + else if (fs->stat(&p->stat, mp, inode, &aio->r)) + { + aio->error = errno; + goto failure; + } + + return 0; + +failure: + aio->done = p->done; + free(p); + return -1; +} + +struct aio *aio_stat(const struct fs_stat *const as, + const struct aio_done *const d) +{ + struct aio *const aio = malloc(sizeof *aio); + struct stat_prv *const p = malloc(sizeof *p); + + if (!p || !aio) + goto failure; + + const struct inode_search s = + { + .path = as->path, + .done = search_done, + .args = p + }; + + *p = (const struct stat_prv) + { + .aio = aio, + .stat = *as + }; + + *aio = (const struct aio) + { + .done = + { + .f = done, + .args = p + } + }; + + if (inode_search(&s, &aio->r)) + goto failure; + + if (d) + p->done = *d; + + return aio; + +failure: + free(p); + free(aio); + return NULL; +} diff --git a/src/aio/src/write.c b/src/aio/src/write.c new file mode 100644 index 0000000..116629f --- /dev/null +++ b/src/aio/src/write.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 <aio.h> +#include <fs/fs.h> +#include <aio/types.h> +#include <state.h> +#include <stddef.h> +#include <stdlib.h> + +struct write +{ + struct aio *aio; + struct aio_done done; +}; + +static int done(const enum state s, void *const args) +{ + struct write *const w = args; + + free(w); + return 0; +} + +static enum state write_done(void *const args) +{ + return STATE_OK; +} + +struct aio *aio_write(const struct fs_write *const fw, + const struct aio_done *const d) +{ + struct aio *aio = NULL; + struct write *const w = malloc(sizeof *w); + struct fs_fd *const fd = fw->fd; + const struct fs *const fs = fd->mp->fs; + + if (!w || !(aio = malloc(sizeof *aio))) + goto failure; + + *aio = (const struct aio) + { + .done = + { + .f = done, + .args = w + } + }; + + aio->r = (const struct fs_ret){.f = write_done}; + + if (fs->write(fw, &aio->r)) + goto failure; + + if (d) + w->done = *d; + + return aio; + +failure: + free(w); + free(aio); + return NULL; +} |
