diff --git a/builtin-functions/kphp-light/file.txt b/builtin-functions/kphp-light/file.txt index de1c546a1c..20b28f0970 100644 --- a/builtin-functions/kphp-light/file.txt +++ b/builtin-functions/kphp-light/file.txt @@ -38,8 +38,6 @@ function is_readable ($name ::: string) ::: bool; /** @kphp-extern-func-info generate-stub */ function mkdir ($name ::: string, $mode ::: int = 0777, $recursive ::: bool = false) ::: bool; /** @kphp-extern-func-info generate-stub */ -function php_uname ($mode ::: string = "a") ::: string; -/** @kphp-extern-func-info generate-stub */ function realpath ($path ::: string) ::: string | false; /** @kphp-extern-func-info generate-stub */ function rename ($oldname ::: string, $newname ::: string) ::: bool; diff --git a/builtin-functions/kphp-light/functions.txt b/builtin-functions/kphp-light/functions.txt index 3a3f4f94e3..2b34ae00d7 100644 --- a/builtin-functions/kphp-light/functions.txt +++ b/builtin-functions/kphp-light/functions.txt @@ -11,6 +11,7 @@ require_once __DIR__ . '/rpc.txt'; require_once __DIR__ . '/serialize.txt'; require_once __DIR__ . '/string.txt'; require_once __DIR__ . '/server.txt'; +require_once __DIR__ . '/system.txt'; require_once __DIR__ . '/kphp-toggles.txt'; require_once __DIR__ . '/kphp_internal.txt'; require_once __DIR__ . '/math.txt'; diff --git a/builtin-functions/kphp-light/system.txt b/builtin-functions/kphp-light/system.txt new file mode 100644 index 0000000000..444a31c1d3 --- /dev/null +++ b/builtin-functions/kphp-light/system.txt @@ -0,0 +1,5 @@ + #include #include +#include #include #define K2_API_HEADER_H @@ -85,6 +86,14 @@ inline void free_checked(void *ptr, size_t size, size_t align) noexcept { k2_exit(exit_code); } +inline uint32_t getpid() noexcept { + return k2_getpid(); +} + +inline int32_t uname(struct utsname *addr) noexcept { + return k2_uname(addr); +} + inline int32_t open(uint64_t *stream_d, size_t name_len, const char *name) noexcept { return k2_open(stream_d, name_len, name); } diff --git a/runtime-light/state/image-state.h b/runtime-light/state/image-state.h index 7a293d58b3..6c5340b06c 100644 --- a/runtime-light/state/image-state.h +++ b/runtime-light/state/image-state.h @@ -5,9 +5,15 @@ #pragma once #include +#include +#include +#include #include "common/mixin/not_copyable.h" +#include "common/php-functions.h" #include "runtime-common/core/allocator/runtime-allocator.h" +#include "runtime-common/core/runtime-core.h" +#include "runtime-common/core/utils/kphp-assert-core.h" #include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/stdlib/rpc/rpc-state.h" #include "runtime-light/stdlib/string/string-state.h" @@ -16,11 +22,47 @@ struct ImageState final : private vk::not_copyable { RuntimeAllocator allocator; char *c_linear_mem{nullptr}; - RpcImageState rpc_image_state{}; - StringImageState string_image_state{}; + uint32_t pid{}; + string uname_info_s; + string uname_info_n; + string uname_info_r; + string uname_info_v; + string uname_info_m; + string uname_info_a; + + RpcImageState rpc_image_state; + StringImageState string_image_state; ImageState() noexcept - : allocator(INIT_IMAGE_ALLOCATOR_SIZE, 0) {} + : allocator(INIT_IMAGE_ALLOCATOR_SIZE, 0) + , pid(k2::getpid()) { + utsname uname_info{}; + if (const auto err{k2::uname(std::addressof(uname_info))}; err != k2::errno_ok) [[unlikely]] { + php_error("can't get uname, error '%d'", err); + } + uname_info_s = string{uname_info.sysname}; + uname_info_s.set_reference_counter_to(ExtraRefCnt::for_global_const); + uname_info_n = string{uname_info.nodename}; + uname_info_n.set_reference_counter_to(ExtraRefCnt::for_global_const); + uname_info_r = string{uname_info.release}; + uname_info_r.set_reference_counter_to(ExtraRefCnt::for_global_const); + uname_info_v = string{uname_info.version}; + uname_info_v.set_reference_counter_to(ExtraRefCnt::for_global_const); + uname_info_m = string{uname_info.machine}; + uname_info_m.set_reference_counter_to(ExtraRefCnt::for_global_const); + // +4 for whitespaces + uname_info_a.reserve_at_least(uname_info_s.size() + uname_info_n.size() + uname_info_r.size() + uname_info_v.size() + uname_info_m.size() + 4); + uname_info_a.append(uname_info_s); + uname_info_a.push_back(' '); + uname_info_a.append(uname_info_n); + uname_info_a.push_back(' '); + uname_info_a.append(uname_info_r); + uname_info_a.push_back(' '); + uname_info_a.append(uname_info_v); + uname_info_a.push_back(' '); + uname_info_a.append(uname_info_m); + uname_info_a.set_reference_counter_to(ExtraRefCnt::for_global_const); + } static const ImageState &get() noexcept { return *k2::image_state(); diff --git a/runtime-light/stdlib/system/system-functions.h b/runtime-light/stdlib/system/system-functions.h index 1a3182ff13..4a93b4d441 100644 --- a/runtime-light/stdlib/system/system-functions.h +++ b/runtime-light/stdlib/system/system-functions.h @@ -4,35 +4,39 @@ #pragma once +#include + +#include "runtime-common/core/runtime-core.h" #include "runtime-common/core/utils/kphp-assert-core.h" +#include "runtime-light/state/image-state.h" #include "runtime-light/stdlib/system/system-state.h" template -int64_t f$estimate_memory_usage(const T &) { +int64_t f$estimate_memory_usage(const T & /*unused*/) { php_critical_error("call to unsupported function"); } template -void f$register_kphp_on_warning_callback(F &&callback) { +void f$register_kphp_on_warning_callback(F && /*callback*/) { php_critical_error("call to unsupported function"); } template -bool f$register_kphp_on_oom_callback(F &&callback) { +bool f$register_kphp_on_oom_callback(F && /*callback*/) { php_critical_error("call to unsupported function"); } template -void f$kphp_extended_instance_cache_metrics_init(F &&callback) { +void f$kphp_extended_instance_cache_metrics_init(F && /*callback*/) { php_critical_error("call to unsupported function"); } -inline int64_t f$system(const string &command, int64_t &result_code = SystemInstanceState::get().result_code_dummy) { +inline int64_t f$system(const string & /*command*/, int64_t & /*result_code*/ = SystemInstanceState::get().result_code_dummy) { php_critical_error("call to unsupported function"); } -inline Optional> f$getopt(const string &options, array longopts = {}, - Optional &rest_index = SystemInstanceState::get().rest_index_dummy) { +inline Optional> f$getopt(const string & /*options*/, const array & /*longopts*/ = {}, + Optional & /*rest_index*/ = SystemInstanceState::get().rest_index_dummy) { php_critical_error("call to unsupported function"); } @@ -42,3 +46,27 @@ inline int64_t f$numa_get_bound_node() noexcept { inline void f$kphp_set_context_on_error([[maybe_unused]] const array &tags, [[maybe_unused]] const array &extra_info, [[maybe_unused]] const string &env = {}) noexcept {} + +inline int64_t f$posix_getpid() noexcept { + return static_cast(ImageState::get().pid); +} + +inline string f$php_uname(const string &mode = string{1, 'a'}) noexcept { + const auto &image_st{ImageState::get()}; + const char mode_c{mode.empty() ? 'a' : mode[0]}; + switch (mode_c) { + case 's': + return image_st.uname_info_s; + case 'n': + return image_st.uname_info_n; + case 'r': + return image_st.uname_info_r; + case 'v': + return image_st.uname_info_v; + case 'm': + return image_st.uname_info_m; + default: { + return image_st.uname_info_a; + } + } +}