diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-07 13:22:53 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-11-11 00:08:15 +0100 |
| commit | 7861a52adf92a083bb2aed4c35f98d8035dce032 (patch) | |
| tree | 28cd3c40e4c878f730f5df3c1d93bdf91af490c3 /src/aio | |
| parent | 7fc48e9216ff809da5f8055a50b0be17628ef1df (diff) | |
| download | wnix-7861a52adf92a083bb2aed4c35f98d8035dce032.tar.gz | |
Setup project skeleton
Diffstat (limited to 'src/aio')
| -rw-r--r-- | src/aio/CMakeLists.txt | 26 | ||||
| -rw-r--r-- | src/aio/include/aio.h | 40 | ||||
| -rw-r--r-- | src/aio/private_include/aio/types.h | 34 | ||||
| -rw-r--r-- | src/aio/src/CMakeLists.txt | 28 | ||||
| -rw-r--r-- | src/aio/src/close.c | 19 | ||||
| -rw-r--r-- | src/aio/src/free.c | 25 | ||||
| -rw-r--r-- | src/aio/src/mkdir.c | 137 | ||||
| -rw-r--r-- | src/aio/src/mount.c | 174 | ||||
| -rw-r--r-- | src/aio/src/open.c | 103 | ||||
| -rw-r--r-- | src/aio/src/poll.c | 77 | ||||
| -rw-r--r-- | src/aio/src/read.c | 82 | ||||
| -rw-r--r-- | src/aio/src/read_nb.c | 29 | ||||
| -rw-r--r-- | src/aio/src/stat.c | 117 | ||||
| -rw-r--r-- | src/aio/src/write.c | 82 |
14 files changed, 933 insertions, 40 deletions
diff --git a/src/aio/CMakeLists.txt b/src/aio/CMakeLists.txt index 3f4561a..278192b 100644 --- a/src/aio/CMakeLists.txt +++ b/src/aio/CMakeLists.txt @@ -1,6 +1,20 @@ -set(src - "src/close.c" - "src/open.c" -) -add_library(aio ${src}) -target_include_directories(aio PUBLIC "include" PRIVATE "private_include") +# wnix, 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(aio) +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..9486f3f 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 + * wnix, 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,41 @@ #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_stat(const struct fs_stat *s, const struct aio_done *d); +int aio_read_nb(const struct fs_read *r); +int aio_poll(struct aio_poll *p, int ms); +int aio_close(struct fs_fd *fd); +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..1fee8c1 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 +/* + * wnix, 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..ba4af9c --- /dev/null +++ b/src/aio/src/CMakeLists.txt @@ -0,0 +1,28 @@ +# wnix, 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(aio PRIVATE + close.c + free.c + mkdir.c + mount.c + open.c + poll.c + read.c + read_nb.c + stat.c + write.c +) diff --git a/src/aio/src/close.c b/src/aio/src/close.c index a6067a8..68c5dd7 100644 --- a/src/aio/src/close.c +++ b/src/aio/src/close.c @@ -1,5 +1,5 @@ /* - * wanix, a Unix-like operating system for WebAssembly + * wnix, 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,13 @@ */ #include <aio.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> +#include <aio/types.h> +#include <fs/fs.h> -int aio_close(struct aio *const aio) +int aio_close(struct fs_fd *const fd) { - if (!aio) - { - errno = EINVAL; - return EOF; - } + if (fd->mp && fd->mp->fs) + return fd->mp->fs->close(fd); - free(aio); - return 0; + return -1; } diff --git a/src/aio/src/free.c b/src/aio/src/free.c new file mode 100644 index 0000000..cfefb1c --- /dev/null +++ b/src/aio/src/free.c @@ -0,0 +1,25 @@ +/* + * wnix, 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 <stdlib.h> + +void aio_free(struct aio *const aio) +{ + free(aio); +} diff --git a/src/aio/src/mkdir.c b/src/aio/src/mkdir.c new file mode 100644 index 0000000..40b09b6 --- /dev/null +++ b/src/aio/src/mkdir.c @@ -0,0 +1,137 @@ +/* + * wnix, 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..418fb69 --- /dev/null +++ b/src/aio/src/mount.c @@ -0,0 +1,174 @@ +/* + * wnix, 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; + else 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..4ee94a9 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 + * wnix, 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,111 @@ * 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; + const struct aio_done *const d = &o->done; + + if (d->f) + d->f(s, d->args); + + free(o); + return 0; +} + +static enum state opened(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 = opened, + .args = o + }; + + if (fs->open(&o->open, mp, inode, &aio->r)) + { + aio->error = errno; + goto failure; + } + + return 0; + +failure: + aio->done = o->done; + free(o); + 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; + else 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..9a792a8 --- /dev/null +++ b/src/aio/src/poll.c @@ -0,0 +1,77 @@ +/* + * wnix, 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;) + { + struct aio_poll *const next = 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; + } + } + + p = next; + } + + 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/read.c b/src/aio/src/read.c new file mode 100644 index 0000000..f57c3b0 --- /dev/null +++ b/src/aio/src/read.c @@ -0,0 +1,82 @@ +/* + * wnix, 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 read +{ + struct aio_done done; +}; + +static int done(const enum state s, void *const args) +{ + int ret = 0; + struct read *const r = args; + const struct aio_done *const d = &r->done; + + if (d->f) + ret = d->f(s, d->args); + + free(r); + return ret; +} + +static enum state read_done(void *const args) +{ + return STATE_OK; +} + +struct aio *aio_read(const struct fs_read *const fr, + const struct aio_done *const d) +{ + struct aio *aio = NULL; + struct read *const r = malloc(sizeof *r); + struct fs_fd *const fd = fr->fd; + const struct fs *const fs = fd->mp->fs; + + if (!r || !(aio = malloc(sizeof *aio))) + goto failure; + + *r = (const struct read){0}; + *aio = (const struct aio) + { + .r.f = read_done, + .done = + { + .f = done, + .args = r + } + }; + + if (fs->read(fr, &aio->r)) + goto failure; + else if (d) + r->done = *d; + + return aio; + +failure: + free(r); + free(aio); + return NULL; +} diff --git a/src/aio/src/read_nb.c b/src/aio/src/read_nb.c new file mode 100644 index 0000000..133a75a --- /dev/null +++ b/src/aio/src/read_nb.c @@ -0,0 +1,29 @@ +/* + * wnix, 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> + +int aio_read_nb(const struct fs_read *const fr) +{ + const struct fs_fd *const fd = fr->fd; + const struct fs *const fs = fd->mp->fs; + + return fs->read_nb(fr); +} diff --git a/src/aio/src/stat.c b/src/aio/src/stat.c new file mode 100644 index 0000000..4c8ae35 --- /dev/null +++ b/src/aio/src/stat.c @@ -0,0 +1,117 @@ +/* + * wnix, 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; + else 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..75f167f --- /dev/null +++ b/src/aio/src/write.c @@ -0,0 +1,82 @@ +/* + * wnix, 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_done done; +}; + +static int done(const enum state s, void *const args) +{ + int ret = 0; + struct write *const w = args; + const struct aio_done *const d = &w->done; + + if (d->f) + ret = d->f(s, d->args); + + free(w); + return ret; +} + +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; + + *w = (const struct write){0}; + *aio = (const struct aio) + { + .r.f = write_done, + .done = + { + .f = done, + .args = w + } + }; + + if (fs->write(fw, &aio->r)) + goto failure; + else if (d) + w->done = *d; + + return aio; + +failure: + free(w); + free(aio); + return NULL; +} |
