Skip to content

Commit

Permalink
[orbis-kenel] implement sys_kenv (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
viniciuslrangel authored Nov 13, 2023
1 parent 3a81827 commit 77efd03
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 4 deletions.
14 changes: 11 additions & 3 deletions orbis-kernel/include/orbis/KernelContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {
void deleteProcess(Process *proc);
Process *findProcessById(pid_t pid) const;

utils::LinkedNode<Process> *getProcessList() {
return m_processes;
}
utils::LinkedNode<Process> *getProcessList() { return m_processes; }

long allocatePid() {
std::lock_guard lock(m_thread_id_mtx);
Expand Down Expand Up @@ -143,6 +141,13 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {
return {};
}

std::tuple<utils::kmap<utils::kstring, char[128]> &,
std::unique_lock<shared_mutex>>
getKernelEnv() {
std::unique_lock lock(m_kenv_mtx);
return {m_kenv, std::move(lock)};
}

enum {
c_golden_ratio_prime = 2654404609u,
c_umtx_chains = 512,
Expand Down Expand Up @@ -193,6 +198,9 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {

shared_mutex mIpmiServerMtx;
utils::kmap<utils::kstring, Ref<IpmiServer>> mIpmiServers;

shared_mutex m_kenv_mtx;
utils::kmap<utils::kstring, char[128]> m_kenv; // max size: 127 + '\0'
};

extern KernelContext &g_context;
Expand Down
80 changes: 79 additions & 1 deletion orbis-kernel/src/sys/sys_environment.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,85 @@
#include "sys/sysproto.hpp"

#include "KernelContext.hpp"

orbis::SysResult orbis::sys_kenv(Thread *thread, sint what,
ptr<const char> name, ptr<char> value,
sint len) {
return ErrorCode::NOSYS;
enum action { kenv_get, kenv_set, kenv_unset, kenv_dump };

const auto &[kenv, _] = thread->tproc->context->getKernelEnv();

if (what == kenv_dump) {
int needed = 0;
int done = 0;

for (const auto &[key, env_value] : kenv) {
size_t entry = 0;
// Entry: size of both full buffers, the '=' and the '\0' at the end
if (value == nullptr || len == 0) {
entry = key.size() + 1 + strnlen(env_value, 128) + 1;
} else {
char buf[128 * 2 + 2];

char *_buf = buf;
std::strncpy(buf, key.data(), key.size());
_buf += key.size();

*_buf++ = '=';

const size_t value_size = strnlen(env_value, 128);
std::strncpy(_buf, env_value, value_size);
_buf += value_size;

*_buf++ = '\0';

entry = _buf - buf;
ORBIS_RET_ON_ERROR(uwriteRaw(value + done, buf, entry));
len -= entry;
done += entry;
}
needed += entry;
}

if (done != needed) {
thread->retval[0] = needed;
}
return {};
}

char _name_buf[128];
ORBIS_RET_ON_ERROR(ureadString(_name_buf, sizeof(_name_buf), name));
const std::string_view _name(_name_buf, strnlen(_name_buf, 128));

switch (what) {
case kenv_get: {
const auto it = kenv.find(_name);
if (it == kenv.end()) {
return ErrorCode::NOENT;
}
const char *buf = it->second;
ORBIS_RET_ON_ERROR(uwriteRaw(value, buf, std::min(len, 128)));
break;
}
case kenv_set: {
if (len < 1) {
return ErrorCode::INVAL;
}
char *_value_buf = kenv[kstring(_name)];
ORBIS_RET_ON_ERROR(ureadString(_value_buf, 128, value));
break;
}
case kenv_unset: {
const auto it = kenv.find(_name);
if (it == kenv.end()) {
return ErrorCode::NOENT;
}
kenv.erase(it);
break;
}
default:
return ErrorCode::INVAL;
}

return {};
}

0 comments on commit 77efd03

Please sign in to comment.