diff options
Diffstat (limited to 'libc-bottom-half/cloudlibc/src/libc/fcntl')
4 files changed, 179 insertions, 0 deletions
diff --git a/libc-bottom-half/cloudlibc/src/libc/fcntl/fcntl.c b/libc-bottom-half/cloudlibc/src/libc/fcntl/fcntl.c new file mode 100644 index 0000000..5d4055d --- /dev/null +++ b/libc-bottom-half/cloudlibc/src/libc/fcntl/fcntl.c @@ -0,0 +1,62 @@ +// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ +// +// SPDX-License-Identifier: BSD-2-Clause + +#include <wasi/api.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> + +int fcntl(int fildes, int cmd, ...) { + switch (cmd) { + case F_GETFD: + // Act as if the close-on-exec flag is always set. + return FD_CLOEXEC; + case F_SETFD: + // The close-on-exec flag is ignored. + return 0; + case F_GETFL: { + // Obtain the flags and the rights of the descriptor. + __wasi_fdstat_t fds; + __wasi_errno_t error = __wasi_fd_fdstat_get(fildes, &fds); + if (error != 0) { + errno = error; + return -1; + } + + // Roughly approximate the access mode by converting the rights. + int oflags = fds.fs_flags; + if ((fds.fs_rights_base & + (__WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR)) != 0) { + if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0) + oflags |= O_RDWR; + else + oflags |= O_RDONLY; + } else if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0) { + oflags |= O_WRONLY; + } else { + oflags |= O_SEARCH; + } + return oflags; + } + case F_SETFL: { + // Set new file descriptor flags. + va_list ap; + va_start(ap, cmd); + int flags = va_arg(ap, int); + va_end(ap); + + __wasi_fdflags_t fs_flags = flags & 0xfff; + __wasi_errno_t error = + __wasi_fd_fdstat_set_flags(fildes, fs_flags); + if (error != 0) { + errno = error; + return -1; + } + return 0; + } + default: + errno = EINVAL; + return -1; + } +} diff --git a/libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c b/libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c new file mode 100644 index 0000000..09cbbf8 --- /dev/null +++ b/libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c @@ -0,0 +1,80 @@ +// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ +// +// SPDX-License-Identifier: BSD-2-Clause + +#include <assert.h> +#include <wasi/api.h> +#include <wasi/libc.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> + +static_assert(O_APPEND == __WASI_FDFLAGS_APPEND, "Value mismatch"); +static_assert(O_DSYNC == __WASI_FDFLAGS_DSYNC, "Value mismatch"); +static_assert(O_NONBLOCK == __WASI_FDFLAGS_NONBLOCK, "Value mismatch"); +static_assert(O_RSYNC == __WASI_FDFLAGS_RSYNC, "Value mismatch"); +static_assert(O_SYNC == __WASI_FDFLAGS_SYNC, "Value mismatch"); + +static_assert(O_CREAT >> 12 == __WASI_OFLAGS_CREAT, "Value mismatch"); +static_assert(O_DIRECTORY >> 12 == __WASI_OFLAGS_DIRECTORY, "Value mismatch"); +static_assert(O_EXCL >> 12 == __WASI_OFLAGS_EXCL, "Value mismatch"); +static_assert(O_TRUNC >> 12 == __WASI_OFLAGS_TRUNC, "Value mismatch"); + +int __wasilibc_nocwd_openat_nomode(int fd, const char *path, int oflag) { + // Compute rights corresponding with the access modes provided. + // Attempt to obtain all rights, except the ones that contradict the + // access mode provided to openat(). + __wasi_rights_t max = + ~(__WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_READ | + __WASI_RIGHTS_FD_WRITE | __WASI_RIGHTS_FD_ALLOCATE | + __WASI_RIGHTS_FD_READDIR | __WASI_RIGHTS_FD_FILESTAT_SET_SIZE); + switch (oflag & O_ACCMODE) { + case O_RDONLY: + case O_RDWR: + case O_WRONLY: + if ((oflag & O_RDONLY) != 0) { + max |= __WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR; + } + if ((oflag & O_WRONLY) != 0) { + max |= __WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_WRITE | + __WASI_RIGHTS_FD_ALLOCATE | + __WASI_RIGHTS_FD_FILESTAT_SET_SIZE; + } + break; + case O_EXEC: + break; + case O_SEARCH: + break; + default: + errno = EINVAL; + return -1; + } + + // Ensure that we can actually obtain the minimal rights needed. + __wasi_fdstat_t fsb_cur; + __wasi_errno_t error = __wasi_fd_fdstat_get(fd, &fsb_cur); + if (error != 0) { + errno = error; + return -1; + } + + // Path lookup properties. + __wasi_lookupflags_t lookup_flags = 0; + if ((oflag & O_NOFOLLOW) == 0) + lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; + + // Open file with appropriate rights. + __wasi_fdflags_t fs_flags = oflag & 0xfff; + __wasi_rights_t fs_rights_base = max & fsb_cur.fs_rights_inheriting; + __wasi_rights_t fs_rights_inheriting = fsb_cur.fs_rights_inheriting; + __wasi_fd_t newfd; + error = __wasi_path_open(fd, lookup_flags, path, + (oflag >> 12) & 0xfff, + fs_rights_base, fs_rights_inheriting, fs_flags, + &newfd); + if (error != 0) { + errno = error; + return -1; + } + return newfd; +} diff --git a/libc-bottom-half/cloudlibc/src/libc/fcntl/posix_fadvise.c b/libc-bottom-half/cloudlibc/src/libc/fcntl/posix_fadvise.c new file mode 100644 index 0000000..d683d39 --- /dev/null +++ b/libc-bottom-half/cloudlibc/src/libc/fcntl/posix_fadvise.c @@ -0,0 +1,24 @@ +// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ +// +// SPDX-License-Identifier: BSD-2-Clause + +#include <assert.h> +#include <wasi/api.h> +#include <errno.h> +#include <fcntl.h> + +static_assert(POSIX_FADV_DONTNEED == __WASI_ADVICE_DONTNEED, + "Value mismatch"); +static_assert(POSIX_FADV_NOREUSE == __WASI_ADVICE_NOREUSE, "Value mismatch"); +static_assert(POSIX_FADV_NORMAL == __WASI_ADVICE_NORMAL, "Value mismatch"); +static_assert(POSIX_FADV_RANDOM == __WASI_ADVICE_RANDOM, "Value mismatch"); +static_assert(POSIX_FADV_SEQUENTIAL == __WASI_ADVICE_SEQUENTIAL, + "Value mismatch"); +static_assert(POSIX_FADV_WILLNEED == __WASI_ADVICE_WILLNEED, + "Value mismatch"); + +int posix_fadvise(int fd, off_t offset, off_t len, int advice) { + if (offset < 0 || len < 0) + return EINVAL; + return __wasi_fd_advise(fd, offset, len, advice); +} diff --git a/libc-bottom-half/cloudlibc/src/libc/fcntl/posix_fallocate.c b/libc-bottom-half/cloudlibc/src/libc/fcntl/posix_fallocate.c new file mode 100644 index 0000000..4b41c4b --- /dev/null +++ b/libc-bottom-half/cloudlibc/src/libc/fcntl/posix_fallocate.c @@ -0,0 +1,13 @@ +// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ +// +// SPDX-License-Identifier: BSD-2-Clause + +#include <wasi/api.h> +#include <errno.h> +#include <fcntl.h> + +int posix_fallocate(int fd, off_t offset, off_t len) { + if (offset < 0 || len < 0) + return EINVAL; + return __wasi_fd_allocate(fd, offset, len); +} |