Skip to content

Commit b9f8afc

Browse files
authored
[k2] add posix builtins (#1391)
1 parent 73de7c0 commit b9f8afc

File tree

5 files changed

+64
-5
lines changed

5 files changed

+64
-5
lines changed

builtin-functions/kphp-light/stdlib/server-functions.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,6 @@ function memory_get_static_usage() ::: int;
9797
/** @kphp-extern-func-info stub generation-required */
9898
function memory_get_detailed_stats() ::: int[];
9999

100-
/** @kphp-extern-func-info stub generation-required */
101-
function posix_getuid() ::: int;
102-
/** @kphp-extern-func-info stub generation-required */
103-
function posix_getpwuid($uid ::: int) ::: mixed[] | false;
104-
105100
/** @kphp-extern-func-info stub */
106101
function kphp_extended_instance_cache_metrics_init(callable(string $key):string $normalization_function) ::: void;
107102

builtin-functions/kphp-light/stdlib/system-functions.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ function php_uname($mode ::: string = "a"): string;
44

55
function posix_getpid(): int;
66

7+
function posix_getuid() ::: int;
8+
9+
function posix_getpwuid($uid ::: int) ::: mixed[] | false;
10+
711
function iconv ($input_encoding ::: string, $output_encoding ::: string, $input_str ::: string) ::: string | false;
812

913
function php_sapi_name() ::: string;

runtime-light/k2-platform/k2-api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ inline constexpr int32_t errno_enomem = ENOMEM;
4040
inline constexpr int32_t errno_etimedout = ETIMEDOUT;
4141
inline constexpr int32_t errno_eshutdown = ESHUTDOWN;
4242
inline constexpr int32_t errno_ecanceled = ECANCELED;
43+
inline constexpr int32_t errno_erange = ERANGE;
4344

4445
using descriptor = uint64_t;
4546
inline constexpr k2::descriptor INVALID_PLATFORM_DESCRIPTOR = 0;

runtime-light/state/image-state.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
#include <cstddef>
88
#include <cstdint>
99
#include <memory>
10+
#include <optional>
11+
#include <sys/types.h>
1012
#include <sys/utsname.h>
13+
#include <unistd.h>
1114

1215
#include "common/mixin/not_copyable.h"
1316
#include "common/php-functions.h"
@@ -25,6 +28,8 @@ struct ImageState final : private vk::not_copyable {
2528
AllocatorState image_allocator_state{INIT_IMAGE_ALLOCATOR_SIZE, 0};
2629

2730
uint32_t pid{k2::getpid()};
31+
uid_t uid{k2::getuid()};
32+
std::optional<int64_t> passwd_max_buffer_size;
2833
string uname_info_s;
2934
string uname_info_n;
3035
string uname_info_r;
@@ -40,6 +45,10 @@ struct ImageState final : private vk::not_copyable {
4045
RpcImageState rpc_image_state;
4146

4247
ImageState() noexcept {
48+
if (const int64_t sysconf_max_buffer_size{k2::sysconf(_SC_GETPW_R_SIZE_MAX)}; sysconf_max_buffer_size != -1) {
49+
passwd_max_buffer_size.emplace(sysconf_max_buffer_size);
50+
}
51+
4352
utsname uname_info{};
4453
if (const auto errc{k2::uname(std::addressof(uname_info))}; errc != k2::errno_ok) [[unlikely]] {
4554
kphp::log::error("can't get uname, error code: {}", errc);

runtime-light/stdlib/system/system-functions.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,39 @@
55
#pragma once
66

77
#include <chrono>
8+
#include <cstddef>
89
#include <cstdint>
10+
#include <memory>
11+
#include <pwd.h>
12+
#include <span>
913
#include <string_view>
14+
#include <sys/types.h>
1015

16+
#include "runtime-common/core/allocator/script-malloc-interface.h"
1117
#include "runtime-common/core/runtime-core.h"
1218
#include "runtime-common/stdlib/serialization/json-functions.h"
1319
#include "runtime-light/core/globals/php-script-globals.h"
1420
#include "runtime-light/coroutine/io-scheduler.h"
1521
#include "runtime-light/coroutine/task.h"
22+
#include "runtime-light/k2-platform/k2-api.h"
1623
#include "runtime-light/state/image-state.h"
1724
#include "runtime-light/stdlib/diagnostics/contextual-logger.h"
1825
#include "runtime-light/stdlib/diagnostics/logs.h"
1926
#include "runtime-light/stdlib/fork/fork-functions.h"
2027
#include "runtime-light/stdlib/system/system-state.h"
2128

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+
2241
template<typename F>
2342
bool f$register_kphp_on_oom_callback(F&& /*callback*/) {
2443
kphp::log::error("call to unsupported function");
@@ -76,6 +95,37 @@ inline int64_t f$posix_getpid() noexcept {
7695
return static_cast<int64_t>(ImageState::get().pid);
7796
}
7897

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+
79129
inline string f$php_uname(const string& mode = string{1, 'a'}) noexcept {
80130
const auto& image_st{ImageState::get()};
81131
const char mode_c{mode.empty() ? 'a' : mode[0]};

0 commit comments

Comments
 (0)