|
5 | 5 | #pragma once |
6 | 6 |
|
7 | 7 | #include <chrono> |
| 8 | +#include <cstddef> |
8 | 9 | #include <cstdint> |
| 10 | +#include <memory> |
| 11 | +#include <pwd.h> |
| 12 | +#include <span> |
9 | 13 | #include <string_view> |
| 14 | +#include <sys/types.h> |
10 | 15 |
|
| 16 | +#include "runtime-common/core/allocator/script-malloc-interface.h" |
11 | 17 | #include "runtime-common/core/runtime-core.h" |
12 | 18 | #include "runtime-common/stdlib/serialization/json-functions.h" |
13 | 19 | #include "runtime-light/core/globals/php-script-globals.h" |
14 | 20 | #include "runtime-light/coroutine/io-scheduler.h" |
15 | 21 | #include "runtime-light/coroutine/task.h" |
| 22 | +#include "runtime-light/k2-platform/k2-api.h" |
16 | 23 | #include "runtime-light/state/image-state.h" |
17 | 24 | #include "runtime-light/stdlib/diagnostics/contextual-logger.h" |
18 | 25 | #include "runtime-light/stdlib/diagnostics/logs.h" |
19 | 26 | #include "runtime-light/stdlib/fork/fork-functions.h" |
20 | 27 | #include "runtime-light/stdlib/system/system-state.h" |
21 | 28 |
|
| 29 | +namespace kphp::posix::impl { |
| 30 | + |
| 31 | +constexpr std::string_view NAME_PWUID_KEY = "name"; |
| 32 | +constexpr std::string_view PASSWD_PWUID_KEY = "passwd"; |
| 33 | +constexpr std::string_view UID_PWUID_KEY = "uid"; |
| 34 | +constexpr std::string_view GID_PWUID_KEY = "gid"; |
| 35 | +constexpr std::string_view GECOS_PWUID_KEY = "gecos"; |
| 36 | +constexpr std::string_view DIR_PWUID_KEY = "dir"; |
| 37 | +constexpr std::string_view SHELL_PWUID_KEY = "shell"; |
| 38 | + |
| 39 | +} // namespace kphp::posix::impl |
| 40 | + |
22 | 41 | template<typename F> |
23 | 42 | bool f$register_kphp_on_oom_callback(F&& /*callback*/) { |
24 | 43 | kphp::log::error("call to unsupported function"); |
@@ -76,6 +95,37 @@ inline int64_t f$posix_getpid() noexcept { |
76 | 95 | return static_cast<int64_t>(ImageState::get().pid); |
77 | 96 | } |
78 | 97 |
|
| 98 | +inline int64_t f$posix_getuid() noexcept { |
| 99 | + return static_cast<int64_t>(ImageState::get().uid); |
| 100 | +} |
| 101 | + |
| 102 | +inline Optional<array<mixed>> f$posix_getpwuid(int64_t user_id) noexcept { |
| 103 | + static constexpr int64_t DEFAULT_PASSWD_BUFFER_SIZE = 4096; |
| 104 | + |
| 105 | + int64_t passwd_max_buffer_size{ImageState::get().passwd_max_buffer_size.value_or(DEFAULT_PASSWD_BUFFER_SIZE)}; |
| 106 | + passwd pwd{}; |
| 107 | + passwd* pwd_result{nullptr}; |
| 108 | + std::unique_ptr<std::byte, decltype(std::addressof(kphp::memory::script::free))> buffer{ |
| 109 | + static_cast<std::byte*>(kphp::memory::script::alloc(passwd_max_buffer_size)), kphp::memory::script::free}; |
| 110 | + |
| 111 | + int32_t error_code{k2::getpwuid_r(static_cast<uid_t>(user_id), std::addressof(pwd), std::span{buffer.get(), static_cast<size_t>(passwd_max_buffer_size)}, |
| 112 | + std::addressof(pwd_result))}; |
| 113 | + |
| 114 | + if (error_code != k2::errno_ok || pwd_result != std::addressof(pwd)) [[unlikely]] { |
| 115 | + return false; |
| 116 | + } |
| 117 | + |
| 118 | + array<mixed> result{array_size{7, false}}; |
| 119 | + result.set_value(string{kphp::posix::impl::NAME_PWUID_KEY.data(), kphp::posix::impl::NAME_PWUID_KEY.size()}, string{pwd.pw_name}); |
| 120 | + result.set_value(string{kphp::posix::impl::PASSWD_PWUID_KEY.data(), kphp::posix::impl::NAME_PWUID_KEY.size()}, string{pwd.pw_passwd}); |
| 121 | + result.set_value(string{kphp::posix::impl::UID_PWUID_KEY.data(), kphp::posix::impl::UID_PWUID_KEY.size()}, static_cast<int64_t>(pwd.pw_uid)); |
| 122 | + result.set_value(string{kphp::posix::impl::GID_PWUID_KEY.data(), kphp::posix::impl::GID_PWUID_KEY.size()}, static_cast<int64_t>(pwd.pw_gid)); |
| 123 | + result.set_value(string{kphp::posix::impl::GECOS_PWUID_KEY.data(), kphp::posix::impl::GECOS_PWUID_KEY.size()}, string{pwd.pw_gecos}); |
| 124 | + result.set_value(string{kphp::posix::impl::DIR_PWUID_KEY.data(), kphp::posix::impl::DIR_PWUID_KEY.size()}, string{pwd.pw_dir}); |
| 125 | + result.set_value(string{kphp::posix::impl::SHELL_PWUID_KEY.data(), kphp::posix::impl::SHELL_PWUID_KEY.size()}, string{pwd.pw_shell}); |
| 126 | + return result; |
| 127 | +} |
| 128 | + |
79 | 129 | inline string f$php_uname(const string& mode = string{1, 'a'}) noexcept { |
80 | 130 | const auto& image_st{ImageState::get()}; |
81 | 131 | const char mode_c{mode.empty() ? 'a' : mode[0]}; |
|
0 commit comments