فهرست منبع

LibWasm/WASI: Add support for fd_fdstat_get()

Ali Mohammad Pur 1 سال پیش
والد
کامیت
708abf6bb1
1فایلهای تغییر یافته به همراه61 افزوده شده و 1 حذف شده
  1. 61 1
      Userland/Libraries/LibWasm/WASI/Wasi.cpp

+ 61 - 1
Userland/Libraries/LibWasm/WASI/Wasi.cpp

@@ -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 {