diff --git a/Userland/Libraries/LibFileSystem/FileSystem.cpp b/Userland/Libraries/LibFileSystem/FileSystem.cpp index f6b5767da6..8adb2246ff 100644 --- a/Userland/Libraries/LibFileSystem/FileSystem.cpp +++ b/Userland/Libraries/LibFileSystem/FileSystem.cpp @@ -12,8 +12,12 @@ #include #include -#ifdef AK_OS_SERENITY +#if defined(AK_OS_SERENITY) # include +#elif defined(AK_OS_BSD_GENERIC) +# include +#elif defined(AK_OS_LINUX) +# include #endif // On Linux distros that use glibc `basename` is defined as a macro that expands to `__xpg_basename`, so we undefine it @@ -362,6 +366,52 @@ ErrorOr size_from_fstat(int fd) return st.st_size; } +ErrorOr block_device_size_from_ioctl(StringView path) +{ + if (!path.characters_without_null_termination()) + return Error::from_syscall("ioctl"sv, -EFAULT); + + ByteString path_string = path; + int fd = open(path_string.characters(), O_RDONLY); + + if (fd < 0) + return Error::from_errno(errno); + + off_t size = TRY(block_device_size_from_ioctl(fd)); + + if (close(fd) != 0) + return Error::from_errno(errno); + + return size; +} + +ErrorOr block_device_size_from_ioctl(int fd) +{ +#if defined(AK_OS_SERENITY) + u64 size = 0; + TRY(Core::System::ioctl(fd, STORAGE_DEVICE_GET_SIZE, &size)); + return static_cast(size); +#elif defined(AK_OS_MACOS) + u64 block_count = 0; + u32 block_size = 0; + TRY(Core::System::ioctl(fd, DKIOCGETBLOCKCOUNT, &block_count)); + TRY(Core::System::ioctl(fd, DKIOCGETBLOCKSIZE, &block_size)); + return static_cast(block_count * block_size); +#elif defined(AK_OS_FREEBSD) || defined(AK_OS_NETBSD) + off_t size = 0; + TRY(Core::System::ioctl(fd, DIOCGMEDIASIZE, &size)); + return size; +#elif defined(AK_OS_LINUX) + u64 size = 0; + TRY(Core::System::ioctl(fd, BLKGETSIZE64, &size)); + return static_cast(size); +#else + // FIXME: Add support for more platforms. + (void)fd; + return Error::from_string_literal("Platform does not support getting block device size"); +#endif +} + bool can_delete_or_move(StringView path) { VERIFY(!path.is_empty()); diff --git a/Userland/Libraries/LibFileSystem/FileSystem.h b/Userland/Libraries/LibFileSystem/FileSystem.h index 400f07b09d..64a5d02e82 100644 --- a/Userland/Libraries/LibFileSystem/FileSystem.h +++ b/Userland/Libraries/LibFileSystem/FileSystem.h @@ -73,6 +73,8 @@ ErrorOr move_file(StringView destination_path, StringView source_path, Pre ErrorOr remove(StringView path, RecursionMode); ErrorOr size_from_stat(StringView path); ErrorOr size_from_fstat(int fd); +ErrorOr block_device_size_from_ioctl(StringView path); +ErrorOr block_device_size_from_ioctl(int fd); bool can_delete_or_move(StringView path); ErrorOr read_link(StringView link_path);