diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 13:54:38 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 13:54:38 +0000 |
commit | 8c1ab65c0f548d20b7f177bdb736daaf603340e1 (patch) | |
tree | df55b7e75bf43f2bf500845b105afe3ac3a5157e /libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c | |
parent | Initial commit. (diff) | |
download | wasi-libc-upstream/0.0_git20221206.8b7148f.tar.xz wasi-libc-upstream/0.0_git20221206.8b7148f.zip |
Adding upstream version 0.0~git20221206.8b7148f.upstream/0.0_git20221206.8b7148f
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c')
-rw-r--r-- | libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c b/libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c new file mode 100644 index 0000000..ffaef6e --- /dev/null +++ b/libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c @@ -0,0 +1,53 @@ +// Copyright (c) 2016 Nuxi, https://nuxi.nl/ +// +// SPDX-License-Identifier: BSD-2-Clause + +#include <wasi/api.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +int __wasilibc_nocwd_faccessat(int fd, const char *path, int amode, int flag) { + // Validate function parameters. + if ((amode & ~(F_OK | R_OK | W_OK | X_OK)) != 0 || + (flag & ~AT_EACCESS) != 0) { + errno = EINVAL; + return -1; + } + + // Check for target file existence and obtain the file type. + __wasi_lookupflags_t lookup_flags = __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; + __wasi_filestat_t file; + __wasi_errno_t error = + __wasi_path_filestat_get(fd, lookup_flags, path, &file); + if (error != 0) { + errno = error; + return -1; + } + + // Test whether the requested access rights are present on the + // directory file descriptor. + if (amode != 0) { + __wasi_fdstat_t directory; + error = __wasi_fd_fdstat_get(fd, &directory); + if (error != 0) { + errno = error; + return -1; + } + + __wasi_rights_t min = 0; + if ((amode & R_OK) != 0) + min |= file.filetype == __WASI_FILETYPE_DIRECTORY + ? __WASI_RIGHTS_FD_READDIR + : __WASI_RIGHTS_FD_READ; + if ((amode & W_OK) != 0) + min |= __WASI_RIGHTS_FD_WRITE; + + if ((min & directory.fs_rights_inheriting) != min) { + errno = EACCES; + return -1; + } + } + return 0; +} |