Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibFileSystem: Port to Windows #2189

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
45 changes: 45 additions & 0 deletions Libraries/LibCore/SystemWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,49 @@ ErrorOr<void> ioctl(int, unsigned, ...)
VERIFY_NOT_REACHED();
}

ErrorOr<ByteString> getcwd()
{
auto* cwd = _getcwd(nullptr, 0);
if (!cwd)
return Error::from_syscall("getcwd"sv, -errno);

ByteString string_cwd(cwd);
free(cwd);
return string_cwd;
}

ErrorOr<struct stat> stat(StringView path)
{
if (path.is_null())
return Error::from_syscall("stat"sv, -EFAULT);

struct stat st = {};
ByteString path_string = path;
if (::stat(path_string.characters(), &st) < 0)
return Error::from_syscall("stat"sv, -errno);
return st;
}

ErrorOr<void> rmdir(StringView path)
{
if (path.is_null())
return Error::from_errno(EFAULT);

ByteString path_string = path;
if (_rmdir(path_string.characters()) < 0)
return Error::from_syscall("rmdir"sv, -errno);
return {};
}

ErrorOr<void> unlink(StringView path)
{
if (path.is_null())
return Error::from_errno(EFAULT);

ByteString path_string = path;
if (_unlink(path_string.characters()) < 0)
return Error::from_syscall("unlink"sv, -errno);
return {};
}

}
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

}
Loading