From 23e7b6010dea6c1c4b24cbaac3982c268dc633e2 Mon Sep 17 00:00:00 2001 From: Vadim Sadokhov Date: Wed, 26 Nov 2025 13:21:37 +0300 Subject: [PATCH 1/4] add file_exists --- .../kphp-light/stdlib/file-functions.txt | 4 ++-- runtime-light/k2-platform/k2-api.h | 13 +++++++++++-- runtime-light/k2-platform/k2-header.h | 12 ++++++++++-- runtime-light/stdlib/confdata/confdata-functions.h | 2 +- runtime-light/stdlib/file/file-system-functions.h | 5 +++++ 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/builtin-functions/kphp-light/stdlib/file-functions.txt b/builtin-functions/kphp-light/stdlib/file-functions.txt index 98935f2b24..334aec33d2 100644 --- a/builtin-functions/kphp-light/stdlib/file-functions.txt +++ b/builtin-functions/kphp-light/stdlib/file-functions.txt @@ -38,6 +38,8 @@ function sprintf ($format ::: string, ...$args) ::: string; function vsprintf ($format ::: string, $args ::: array) ::: string; +function file_exists ($name ::: string) ::: bool; + // === UNSUPPORTED === /** @kphp-extern-func-info stub generation-required */ @@ -51,8 +53,6 @@ function file ($name ::: string) ::: string[] | false; /** @kphp-extern-func-info stub generation-required */ function file_put_contents ($name ::: string, $content ::: mixed, $flags ::: int = 0) ::: int | false; /** @kphp-extern-func-info stub generation-required */ -function file_exists ($name ::: string) ::: bool; -/** @kphp-extern-func-info stub generation-required */ function filectime ($name ::: string) ::: int | false; /** @kphp-extern-func-info stub generation-required */ function filemtime ($name ::: string) ::: int | false; diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h index 4f127b589d..6594e985fc 100644 --- a/runtime-light/k2-platform/k2-api.h +++ b/runtime-light/k2-platform/k2-api.h @@ -45,6 +45,7 @@ inline constexpr int32_t errno_etimedout = ETIMEDOUT; inline constexpr int32_t errno_eshutdown = ESHUTDOWN; inline constexpr int32_t errno_ecanceled = ECANCELED; inline constexpr int32_t errno_erange = ERANGE; +inline constexpr int32_t errno_enoent = ENOENT; using descriptor = uint64_t; inline constexpr k2::descriptor INVALID_PLATFORM_DESCRIPTOR = 0; @@ -176,6 +177,14 @@ inline auto readdir(k2::descriptor descriptor) noexcept { : return_type{std::nullopt}; } +inline std::expected access(std::string_view path, int32_t mode) noexcept { + if (auto error_code{k2_access(path.data(), path.size(), mode)}; error_code != k2::errno_ok) [[unlikely]] { + return std::unexpected{error_code}; + } else { + return {}; + } +} + inline std::expected unlink(std::string_view path) noexcept { if (auto error_code{k2_unlink(path.data(), path.size())}; error_code != k2::errno_ok) [[unlikely]] { return std::unexpected{error_code}; @@ -184,8 +193,8 @@ inline std::expected unlink(std::string_view path) noexcept { } } -inline int32_t access(std::string_view component_name) noexcept { - return k2_access(component_name.size(), component_name.data()); +inline int32_t component_access(std::string_view component_name) noexcept { + return k2_component_access(component_name.size(), component_name.data()); } inline void stream_status(k2::descriptor descriptor, StreamStatus* status) noexcept { diff --git a/runtime-light/k2-platform/k2-header.h b/runtime-light/k2-platform/k2-header.h index f112520f0f..5bcf8a49d1 100644 --- a/runtime-light/k2-platform/k2-header.h +++ b/runtime-light/k2-platform/k2-header.h @@ -27,7 +27,7 @@ #include #endif -#define K2_PLATFORM_HEADER_H_VERSION 12 +#define K2_PLATFORM_HEADER_H_VERSION 13 // Always check that enum value is a valid value! @@ -280,6 +280,14 @@ struct DirEntry { */ int32_t k2_readdir(uint64_t dd, struct DirEntry* entry, struct DirEntry** result); +/** + * Semantically equivalent to libc's `access` function. + * + * @return On success (all requested permissions granted), zero is returned. On failure, returns a non-zero value corresponding to a libc-like `errno`. + * + */ +int32_t k2_access(const char *pathname, size_t pathname_len, int32_t mode); + /** * Semantically equivalent of libc's unlink * @@ -299,7 +307,7 @@ int32_t k2_unlink(const char* path, size_t path_len); * `EINVAL` => `name` has invalid format (empty, non ascii, too long, etc..) * `EACCES` => permission denied */ -int32_t k2_access(size_t name_len, const char* name); +int32_t k2_component_access(size_t name_len, const char* name); /** * If the write or read status is `Blocked` - then the platform ensures that diff --git a/runtime-light/stdlib/confdata/confdata-functions.h b/runtime-light/stdlib/confdata/confdata-functions.h index a5a2c809f3..0d6579df77 100644 --- a/runtime-light/stdlib/confdata/confdata-functions.h +++ b/runtime-light/stdlib/confdata/confdata-functions.h @@ -11,7 +11,7 @@ #include "runtime-light/stdlib/diagnostics/logs.h" inline bool f$is_confdata_loaded() noexcept { - return k2::access(kphp::confdata::COMPONENT_NAME) == k2::errno_ok; + return k2::component_access(kphp::confdata::COMPONENT_NAME) == k2::errno_ok; } // SAFETY: `key` is only used before await point diff --git a/runtime-light/stdlib/file/file-system-functions.h b/runtime-light/stdlib/file/file-system-functions.h index bb456e9c89..d408ed6aa4 100644 --- a/runtime-light/stdlib/file/file-system-functions.h +++ b/runtime-light/stdlib/file/file-system-functions.h @@ -114,6 +114,11 @@ inline kphp::coro::task f$fclose(resource stream) noexcept { co_return false; } +inline bool f$file_exists(const string& name) noexcept { + const auto exists_res{k2::access(std::string_view{name.c_str(), name.size()}, F_OK)}; + return exists_res.has_value(); +} + inline bool f$unlink(const string& name) noexcept { std::expected unlink_res{k2::unlink(std::string_view{name.c_str(), name.size()})}; return unlink_res.has_value(); From 6b24f58d9fcc88d06bb0fb6a029f6dc95f41c0c0 Mon Sep 17 00:00:00 2001 From: Vadim Sadokhov Date: Wed, 26 Nov 2025 19:46:19 +0300 Subject: [PATCH 2/4] add include --- runtime-light/stdlib/file/file-system-functions.h | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime-light/stdlib/file/file-system-functions.h b/runtime-light/stdlib/file/file-system-functions.h index d408ed6aa4..700d73f0f9 100644 --- a/runtime-light/stdlib/file/file-system-functions.h +++ b/runtime-light/stdlib/file/file-system-functions.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "runtime-common/core/runtime-core.h" From 228ae6c10ee9ae1f912c58064810d984dc2f8457 Mon Sep 17 00:00:00 2001 From: Vadim Sadokhov <65451602+astrophysik@users.noreply.github.com> Date: Mon, 1 Dec 2025 14:43:56 +0300 Subject: [PATCH 3/4] small fix --- runtime-light/k2-platform/k2-api.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h index 6594e985fc..a367a71a17 100644 --- a/runtime-light/k2-platform/k2-api.h +++ b/runtime-light/k2-platform/k2-api.h @@ -180,9 +180,8 @@ inline auto readdir(k2::descriptor descriptor) noexcept { inline std::expected access(std::string_view path, int32_t mode) noexcept { if (auto error_code{k2_access(path.data(), path.size(), mode)}; error_code != k2::errno_ok) [[unlikely]] { return std::unexpected{error_code}; - } else { - return {}; } + return {}; } inline std::expected unlink(std::string_view path) noexcept { From c91d8ffc612d63ed603010562b775803ce2a9369 Mon Sep 17 00:00:00 2001 From: Vadim Sadokhov Date: Mon, 1 Dec 2025 14:45:27 +0300 Subject: [PATCH 4/4] small fix --- runtime-light/k2-platform/k2-header.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-light/k2-platform/k2-header.h b/runtime-light/k2-platform/k2-header.h index 5bcf8a49d1..9a73d202f7 100644 --- a/runtime-light/k2-platform/k2-header.h +++ b/runtime-light/k2-platform/k2-header.h @@ -286,7 +286,7 @@ int32_t k2_readdir(uint64_t dd, struct DirEntry* entry, struct DirEntry** result * @return On success (all requested permissions granted), zero is returned. On failure, returns a non-zero value corresponding to a libc-like `errno`. * */ -int32_t k2_access(const char *pathname, size_t pathname_len, int32_t mode); +int32_t k2_access(const char* pathname, size_t pathname_len, int32_t mode); /** * Semantically equivalent of libc's unlink