|
@@ -313,6 +313,8 @@ static ErrorOr<size_t> copy_string_excluding_terminating_null(Configuration& con
|
|
|
}
|
|
|
|
|
|
static Errno errno_value_from_errno(int value);
|
|
|
+static FileType file_type_of(struct stat const& buf);
|
|
|
+static FDFlags fd_flags_of(struct stat const& buf);
|
|
|
|
|
|
Vector<AK::String> const& Implementation::arguments() const
|
|
|
{
|
|
@@ -778,6 +780,38 @@ ErrorOr<Result<Size>> Implementation::impl$fd_read(Configuration& configuration,
|
|
|
return bytes_read;
|
|
|
}
|
|
|
|
|
|
+ErrorOr<Result<FDStat>> Implementation::impl$fd_fdstat_get(Configuration&, FD fd)
|
|
|
+{
|
|
|
+ auto mapped_fd = map_fd(fd);
|
|
|
+ auto resolved_fd = -1;
|
|
|
+ mapped_fd.visit(
|
|
|
+ [&](PreopenedDirectoryDescriptor descriptor) {
|
|
|
+ auto& entry = preopened_directories()[descriptor.value()];
|
|
|
+ resolved_fd = entry.opened_fd.value_or_lazy_evaluated([&] {
|
|
|
+ ByteString path = entry.host_path.string();
|
|
|
+ return open(path.characters(), O_DIRECTORY, 0);
|
|
|
+ });
|
|
|
+ entry.opened_fd = resolved_fd;
|
|
|
+ },
|
|
|
+ [&](u32 fd) {
|
|
|
+ resolved_fd = fd;
|
|
|
+ },
|
|
|
+ [](UnmappedDescriptor) {});
|
|
|
+ if (resolved_fd < 0)
|
|
|
+ return errno_value_from_errno(errno);
|
|
|
+
|
|
|
+ struct stat stat_buf;
|
|
|
+ if (fstat(resolved_fd, &stat_buf) < 0)
|
|
|
+ return errno_value_from_errno(errno);
|
|
|
+
|
|
|
+ return FDStat {
|
|
|
+ .fs_filetype = file_type_of(stat_buf),
|
|
|
+ .fs_flags = fd_flags_of(stat_buf),
|
|
|
+ .fs_rights_base = Rights { .data = 0 },
|
|
|
+ .fs_rights_inheriting = Rights { .data = 0 },
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
#pragma GCC diagnostic push
|
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
|
|
|
@@ -788,7 +822,6 @@ ErrorOr<Result<Timestamp>> Implementation::impl$clock_res_get(Configuration&, Cl
|
|
|
ErrorOr<Result<void>> Implementation::impl$fd_advise(Configuration&, FD, FileSize offset, FileSize len, Advice) { return Errno::NoSys; }
|
|
|
ErrorOr<Result<void>> Implementation::impl$fd_allocate(Configuration&, FD, FileSize offset, FileSize len) { return Errno::NoSys; }
|
|
|
ErrorOr<Result<void>> Implementation::impl$fd_datasync(Configuration&, FD) { return Errno::NoSys; }
|
|
|
-ErrorOr<Result<FDStat>> Implementation::impl$fd_fdstat_get(Configuration&, FD) { return Errno::NoSys; }
|
|
|
ErrorOr<Result<void>> Implementation::impl$fd_fdstat_set_flags(Configuration&, FD, FDFlags) { return Errno::NoSys; }
|
|
|
ErrorOr<Result<void>> Implementation::impl$fd_fdstat_set_rights(Configuration&, FD, Rights fs_rights_base, Rights fs_rights_inheriting) { return Errno::NoSys; }
|
|
|
ErrorOr<Result<void>> Implementation::impl$fd_filestat_set_size(Configuration&, FD, FileSize) { return Errno::NoSys; }
|
|
@@ -1123,6 +1156,33 @@ Errno errno_value_from_errno(int value)
|
|
|
return Errno::Invalid;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+FileType file_type_of(struct stat const& buf)
|
|
|
+{
|
|
|
+ switch (buf.st_mode & S_IFMT) {
|
|
|
+ case S_IFDIR:
|
|
|
+ return FileType::Directory;
|
|
|
+ case S_IFCHR:
|
|
|
+ return FileType::CharacterDevice;
|
|
|
+ case S_IFBLK:
|
|
|
+ return FileType::BlockDevice;
|
|
|
+ case S_IFREG:
|
|
|
+ return FileType::RegularFile;
|
|
|
+ case S_IFIFO:
|
|
|
+ return FileType::Unknown; // FIXME: FileType::Pipe is currently not present in WASI (but it should be) so we use Unknown for now.
|
|
|
+ case S_IFLNK:
|
|
|
+ return FileType::SymbolicLink;
|
|
|
+ case S_IFSOCK:
|
|
|
+ return FileType::SocketStream;
|
|
|
+ default:
|
|
|
+ return FileType::Unknown;
|
|
|
+ }
|
|
|
+}
|
|
|
+FDFlags fd_flags_of(struct stat const&)
|
|
|
+{
|
|
|
+ FDFlags::Bits result {};
|
|
|
+ return FDFlags { result };
|
|
|
+}
|
|
|
}
|
|
|
|
|
|
namespace AK {
|