Skip to content

Commit

Permalink
LibFileSystem: Port to Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
stasoid committed Nov 10, 2024
1 parent 0537e1e commit 49ac191
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 27 deletions.
4 changes: 2 additions & 2 deletions AK/LexicalPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ LexicalPath::LexicalPath(ByteString path)
}
}

bool LexicalPath::is_absolute() const
bool LexicalPath::is_absolute_path(StringView path)
{
return m_string.starts_with('/');
return path.starts_with('/');
}

Vector<ByteString> LexicalPath::parts() const
Expand Down
3 changes: 2 additions & 1 deletion AK/LexicalPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class LexicalPath {

explicit LexicalPath(ByteString);

bool is_absolute() const;
static bool is_absolute_path(StringView path);
bool is_absolute() const { return is_absolute_path(m_string); }
ByteString const& string() const { return m_string; }

StringView dirname() const { return m_dirname; }
Expand Down
11 changes: 3 additions & 8 deletions AK/LexicalPathWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,9 @@

namespace AK {

static bool is_absolute_path(StringView path)
{
return path.length() >= 2 && path[1] == ':';
}

static bool is_root(auto const& parts)
{
return parts.size() == 1 && is_absolute_path(parts[0]);
return parts.size() == 1 && LexicalPath::is_absolute_path(parts[0]);
}

LexicalPath::LexicalPath(ByteString path)
Expand Down Expand Up @@ -45,9 +40,9 @@ LexicalPath::LexicalPath(ByteString path)
}
}

bool LexicalPath::is_absolute() const
bool LexicalPath::is_absolute_path(StringView path)
{
return is_absolute_path(m_string);
return path.length() >= 2 && path[1] == ':';
}

Vector<ByteString> LexicalPath::parts() const
Expand Down
17 changes: 13 additions & 4 deletions Libraries/LibFileSystem/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
set(SOURCES
FileSystem.cpp
TempFile.cpp
)
if (WIN32)
set(SOURCES FileSystem.cpp)
else()
set(SOURCES
FileSystem.cpp
TempFile.cpp
)
endif()

serenity_lib(LibFileSystem filesystem)
target_link_libraries(LibFileSystem PRIVATE LibCoreMinimal)

if (WIN32)
find_path(DIRENT_INCLUDE_DIR dirent.h REQUIRED)
target_include_directories(LibFileSystem PRIVATE ${DIRENT_INCLUDE_DIR})
endif()
52 changes: 40 additions & 12 deletions Libraries/LibFileSystem/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <LibCore/DirIterator.h>
#include <LibCore/System.h>
#include <LibFileSystem/FileSystem.h>
#include <dirent.h>
#include <limits.h>

#if !defined(AK_OS_IOS) && defined(AK_OS_BSD_GENERIC)
Expand All @@ -32,16 +33,19 @@ ErrorOr<ByteString> current_working_directory()

ErrorOr<ByteString> absolute_path(StringView path)
{
#ifndef AK_OS_WINDOWS
if (exists(path))
return real_path(path);
#endif

if (path.starts_with("/"sv))
if (LexicalPath::is_absolute_path(path))
return LexicalPath::canonicalized_path(path);

auto working_directory = TRY(current_working_directory());
return LexicalPath::absolute_path(working_directory, path);
}

#ifndef AK_OS_WINDOWS
ErrorOr<ByteString> real_path(StringView path)
{
if (path.is_null())
Expand All @@ -56,12 +60,20 @@ ErrorOr<ByteString> real_path(StringView path)

return ByteString { real_path, strlen(real_path) };
}
#else
// NOTE: real_path on Windows does not resolve symlinks
ErrorOr<ByteString> real_path(StringView path)
{
return absolute_path(path);
}
#endif

bool exists(StringView path)
{
return !Core::System::stat(path).is_error();
}

#ifndef AK_OS_WINDOWS
bool exists(int fd)
{
return !Core::System::fstat(fd).is_error();
Expand Down Expand Up @@ -120,6 +132,7 @@ bool is_char_device(int fd)
auto st = st_or_error.release_value();
return S_ISCHR(st.st_mode);
}
#endif

bool is_regular_file(StringView path)
{
Expand Down Expand Up @@ -157,6 +170,7 @@ bool is_directory(int fd)
return S_ISDIR(st.st_mode);
}

#ifndef AK_OS_WINDOWS
bool is_link(StringView path)
{
auto st_or_error = Core::System::lstat(path);
Expand All @@ -165,7 +179,18 @@ bool is_link(StringView path)
auto st = st_or_error.release_value();
return S_ISLNK(st.st_mode);
}
#else
bool is_link(StringView path)
{
ByteString string_path = path;
auto attr = GetFileAttributes(string_path.characters());
if (attr == INVALID_FILE_ATTRIBUTES)
return false;
return attr & FILE_ATTRIBUTE_REPARSE_POINT;
}
#endif

#ifndef AK_OS_WINDOWS
bool is_link(int fd)
{
auto st_or_error = Core::System::fstat(fd);
Expand Down Expand Up @@ -232,13 +257,13 @@ ErrorOr<void> copy_file(StringView destination_path, StringView source_path, str

if (has_flag(preserve_mode, PreserveMode::Timestamps)) {
struct timespec times[2] = {
#if defined(AK_OS_MACOS) || defined(AK_OS_IOS)
# if defined(AK_OS_MACOS) || defined(AK_OS_IOS)
source_stat.st_atimespec,
source_stat.st_mtimespec,
#else
# else
source_stat.st_atim,
source_stat.st_mtim,
#endif
# endif
};
TRY(Core::System::utimensat(AT_FDCWD, destination_path, times, 0));
}
Expand Down Expand Up @@ -280,13 +305,13 @@ ErrorOr<void> copy_directory(StringView destination_path, StringView source_path

if (has_flag(preserve_mode, PreserveMode::Timestamps)) {
struct timespec times[2] = {
#if defined(AK_OS_MACOS) || defined(AK_OS_IOS)
# if defined(AK_OS_MACOS) || defined(AK_OS_IOS)
source_stat.st_atimespec,
source_stat.st_mtimespec,
#else
# else
source_stat.st_atim,
source_stat.st_mtim,
#endif
# endif
};
TRY(Core::System::utimensat(AT_FDCWD, destination_path, times, 0));
}
Expand Down Expand Up @@ -337,6 +362,7 @@ ErrorOr<void> move_file(StringView destination_path, StringView source_path, Pre

return Core::System::unlink(source_path);
}
#endif

ErrorOr<void> remove(StringView path, RecursionMode mode)
{
Expand Down Expand Up @@ -368,6 +394,7 @@ ErrorOr<off_t> size_from_fstat(int fd)
return st.st_size;
}

#ifndef AK_OS_WINDOWS
ErrorOr<off_t> block_device_size_from_ioctl(StringView path)
{
if (!path.characters_without_null_termination())
Expand All @@ -389,25 +416,25 @@ ErrorOr<off_t> block_device_size_from_ioctl(StringView path)

ErrorOr<off_t> block_device_size_from_ioctl(int fd)
{
#if defined(AK_OS_MACOS)
# if 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<off_t>(block_count * block_size);
#elif defined(AK_OS_FREEBSD) || defined(AK_OS_NETBSD)
# 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)
# elif defined(AK_OS_LINUX)
u64 size = 0;
TRY(Core::System::ioctl(fd, BLKGETSIZE64, &size));
return static_cast<off_t>(size);
#else
# else
// FIXME: Add support for more platforms.
(void)fd;
return Error::from_string_literal("Platform does not support getting block device size");
#endif
# endif
}

bool can_delete_or_move(StringView path)
Expand Down Expand Up @@ -451,5 +478,6 @@ bool looks_like_shared_library(StringView path)
{
return path.ends_with(".so"sv) || path.contains(".so."sv);
}
#endif

}

0 comments on commit 49ac191

Please sign in to comment.