move orbis-kernel to kernel/orbis

This commit is contained in:
DH 2025-10-04 15:07:41 +03:00
parent 7419457efd
commit ecaf607a8f
120 changed files with 1 additions and 1 deletions

View file

@ -0,0 +1,6 @@
#include "error.hpp"
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_acct(Thread *thread, ptr<char> path) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,35 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_audit(Thread *thread, ptr<const void> record,
uint length) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_auditon(Thread *thread, sint cmd, ptr<void> data,
uint length) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getauid(Thread *thread, ptr<uid_t> auid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setauid(Thread *thread, ptr<uid_t> auid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getaudit(Thread *thread,
ptr<struct auditinfo> auditinfo) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setaudit(Thread *thread,
ptr<struct auditinfo> auditinfo) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getaudit_addr(
Thread *thread, ptr<struct auditinfo_addr> auditinfo_addr, uint length) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setaudit_addr(
Thread *thread, ptr<struct auditinfo_addr> auditinfo_addr, uint length) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_auditctl(Thread *thread, ptr<char> path) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,15 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_cap_enter(Thread *thread) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_cap_getmode(Thread *thread, ptr<uint> modep) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_cap_new(Thread *thread, sint fd, uint64_t rights) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_cap_getrights(Thread *thread, sint fd,
ptr<uint64_t> rights) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,12 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_getcontext(Thread *thread, ptr<UContext> ucp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setcontext(Thread *thread, ptr<UContext> ucp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_swapcontext(Thread *thread, ptr<UContext> oucp,
ptr<UContext> ucp) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,195 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/Thread.hpp"
#include "thread/cpuset.hpp"
#include "utils/Logs.hpp"
#include <bit>
#include <pthread.h>
#include <sched.h>
#include <sys/sysinfo.h>
enum class CpuLevel {
Root = 1,
CpuSet = 2,
Which = 3,
};
enum class CpuWhich {
Tid = 1,
Pid = 2,
CpuSet = 3,
Irq = 4,
Jail = 5,
};
static cpu_set_t toHostCpuSet(orbis::cpuset cpuSet) {
const int procCount = get_nprocs();
cpu_set_t result{};
for (unsigned cpu = std::countr_zero(cpuSet.bits);
cpu < sizeof(cpuSet.bits) * 8;
cpu = std::countr_zero(cpuSet.bits >> (cpu + 1)) + cpu + 1) {
unsigned hostCpu = cpu;
if (procCount < 8) {
hostCpu = cpu % procCount;
} else if (procCount >= 8 * 2) {
hostCpu = cpu * 2;
}
ORBIS_LOG_ERROR(__FUNCTION__, cpu, hostCpu);
CPU_SET(hostCpu, &result);
}
ORBIS_LOG_ERROR(__FUNCTION__, procCount, result.__bits[0], cpuSet.bits);
return result;
}
orbis::SysResult orbis::sys_cpuset(Thread *thread, ptr<cpusetid_t> setid) {
return {};
}
orbis::SysResult orbis::sys_cpuset_setid(Thread *thread, cpuwhich_t which,
id_t id, cpusetid_t setid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_cpuset_getid(Thread *thread, cpulevel_t level,
cpuwhich_t which, id_t id,
ptr<cpusetid_t> setid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_cpuset_getaffinity(Thread *thread, cpulevel_t level,
cpuwhich_t which, id_t id,
size_t cpusetsize,
ptr<cpuset> mask) {
if (cpusetsize < sizeof(cpuset)) {
return ErrorCode::INVAL;
}
std::lock_guard lock(thread->mtx);
std::lock_guard lockProc(thread->tproc->mtx);
switch (CpuLevel{level}) {
case CpuLevel::Root:
case CpuLevel::CpuSet:
ORBIS_LOG_ERROR(__FUNCTION__, level, which, id, cpusetsize);
return ErrorCode::INVAL;
case CpuLevel::Which:
switch (CpuWhich(which)) {
case CpuWhich::Tid: {
Thread *whichThread = nullptr;
if (id == ~id_t(0) || thread->tid == id) {
whichThread = thread;
} else {
whichThread = thread->tproc->threadsMap.get(id - thread->tproc->pid);
if (whichThread == nullptr) {
ORBIS_LOG_ERROR(__FUNCTION__, "thread not found", level, which, id,
cpusetsize);
return ErrorCode::SRCH;
}
}
return uwrite(mask, whichThread->affinity);
}
case CpuWhich::Pid: {
Process *whichProcess = nullptr;
if (id == ~id_t(0) || id == thread->tproc->pid) {
whichProcess = thread->tproc;
} else {
whichProcess = g_context.findProcessById(id);
if (whichProcess == nullptr) {
return ErrorCode::SRCH;
}
}
return uwrite(mask, whichProcess->affinity);
}
case CpuWhich::CpuSet:
case CpuWhich::Irq:
case CpuWhich::Jail:
ORBIS_LOG_ERROR(__FUNCTION__, level, which, id, cpusetsize);
return ErrorCode::INVAL;
}
break;
}
return ErrorCode::INVAL;
}
orbis::SysResult orbis::sys_cpuset_setaffinity(Thread *thread, cpulevel_t level,
cpuwhich_t which, id_t id,
size_t cpusetsize,
ptr<const cpuset> mask) {
std::lock_guard lock(thread->mtx);
std::lock_guard lockProc(thread->tproc->mtx);
switch (CpuLevel{level}) {
case CpuLevel::Root:
case CpuLevel::CpuSet:
ORBIS_LOG_ERROR(__FUNCTION__, level, which, id, cpusetsize);
return ErrorCode::INVAL;
case CpuLevel::Which:
switch (CpuWhich(which)) {
case CpuWhich::Tid: {
Thread *whichThread = nullptr;
if (id == ~id_t(0) || thread->tid == id) {
whichThread = thread;
} else {
whichThread = thread->tproc->threadsMap.get(id - thread->tproc->pid);
if (whichThread == nullptr) {
ORBIS_LOG_ERROR(__FUNCTION__, "thread not found", level, which, id,
cpusetsize);
return ErrorCode::SRCH;
}
}
ORBIS_RET_ON_ERROR(uread(whichThread->affinity, mask));
auto threadHandle = whichThread->getNativeHandle();
auto hostCpuSet = toHostCpuSet(whichThread->affinity);
ORBIS_LOG_ERROR(__FUNCTION__, threadHandle, thread->tid, id);
if (pthread_setaffinity_np(threadHandle, sizeof(hostCpuSet),
&hostCpuSet)) {
ORBIS_LOG_ERROR(__FUNCTION__,
"failed to set affinity mask for host thread",
whichThread->hostTid, whichThread->affinity.bits);
}
return {};
}
case CpuWhich::Pid: {
Process *whichProcess = nullptr;
if (id == ~id_t(0) || id == thread->tproc->pid) {
whichProcess = thread->tproc;
} else {
ORBIS_LOG_ERROR(__FUNCTION__, "process not found", level, which, id,
cpusetsize);
whichProcess = g_context.findProcessById(id);
if (whichProcess == nullptr) {
return ErrorCode::SRCH;
}
}
ORBIS_RET_ON_ERROR(uread(whichProcess->affinity, mask));
auto hostCpuSet = toHostCpuSet(whichProcess->affinity);
if (sched_setaffinity(whichProcess->hostPid, sizeof(hostCpuSet),
&hostCpuSet)) {
ORBIS_LOG_ERROR(__FUNCTION__,
"failed to set affinity mask for host process",
whichProcess->hostPid, whichProcess->affinity.bits);
}
return {};
}
case CpuWhich::CpuSet:
case CpuWhich::Irq:
case CpuWhich::Jail:
ORBIS_LOG_ERROR(__FUNCTION__, level, which, id, cpusetsize);
return ErrorCode::INVAL;
}
break;
}
return ErrorCode::INVAL;
}

View file

@ -0,0 +1,80 @@
#include "file.hpp"
#include "orbis/utils/Logs.hpp"
#include "stat.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/Thread.hpp"
orbis::SysResult orbis::sys_getdtablesize(Thread *thread) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_dup2(Thread *thread, uint from, uint to) {
auto file = thread->tproc->fileDescriptors.get(from);
if (file == nullptr) {
return ErrorCode::BADF;
}
thread->tproc->fileDescriptors.close(to);
thread->tproc->fileDescriptors.insert(to, file);
return {};
}
orbis::SysResult orbis::sys_dup(Thread *thread, uint fd) {
auto file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
thread->retval[0] = thread->tproc->fileDescriptors.insert(std::move(file));
return {};
}
orbis::SysResult orbis::sys_fcntl(Thread *thread, sint fd, sint cmd,
slong arg) {
ORBIS_LOG_TODO(__FUNCTION__, fd, cmd, arg);
return {};
}
orbis::SysResult orbis::sys_close(Thread *thread, sint fd) {
// ORBIS_LOG_NOTICE(__FUNCTION__, fd);
if (thread->tproc->fileDescriptors.close(fd)) {
return {};
}
return ErrorCode::BADF;
}
orbis::SysResult orbis::sys_closefrom(Thread *thread, sint lowfd) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fstat(Thread *thread, sint fd, ptr<Stat> ub) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto stat = file->ops->stat;
if (stat == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
Stat _ub;
auto result = uread(_ub, ub);
if (result != ErrorCode{}) {
return result;
}
result = stat(file.get(), &_ub, thread);
if (result != ErrorCode{}) {
return result;
}
return uwrite(ub, _ub);
}
orbis::SysResult orbis::sys_nfstat(Thread *thread, sint fd,
ptr<struct nstat> sb) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fpathconf(Thread *thread, sint fd, sint name) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_flock(Thread *thread, sint fd, sint how) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,86 @@
#include "sys/sysproto.hpp"
#include "KernelContext.hpp"
#include "thread/Process.hpp"
orbis::SysResult orbis::sys_kenv(Thread *thread, sint what,
ptr<const char> name, ptr<char> value,
sint len) {
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 {};
}

View file

@ -0,0 +1,402 @@
#include "KernelAllocator.hpp"
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "utils/Logs.hpp"
#include <chrono>
#include <list>
#include <span>
#include <sys/select.h>
orbis::SysResult orbis::sys_kqueue(Thread *thread) {
auto queue = knew<KQueue>();
if (queue == nullptr) {
return ErrorCode::NOMEM;
}
auto fd = thread->tproc->fileDescriptors.insert(queue);
ORBIS_LOG_TODO(__FUNCTION__, fd);
thread->retval[0] = fd;
return {};
}
orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr<char> name,
sint flags) {
auto queue = knew<KQueue>();
if (queue == nullptr) {
return ErrorCode::NOMEM;
}
auto fd = thread->tproc->fileDescriptors.insert(queue);
if (name != nullptr) {
queue->name = name;
}
ORBIS_LOG_TODO(__FUNCTION__, name, flags, fd);
thread->retval[0] = fd;
return {};
}
static bool isReadEventTriggered(int hostFd) {
fd_set fds{};
FD_SET(hostFd, &fds);
timeval timeout{};
if (::select(hostFd + 1, &fds, nullptr, nullptr, &timeout) < 0) {
return false;
}
return FD_ISSET(hostFd, &fds);
}
static bool isWriteEventTriggered(int hostFd) {
fd_set fds{};
FD_SET(hostFd, &fds);
timeval timeout{};
if (::select(hostFd + 1, nullptr, &fds, nullptr, &timeout) < 0) {
return false;
}
return FD_ISSET(hostFd, &fds);
}
namespace orbis {
static SysResult keventChange(KQueue *kq, KEvent &change, Thread *thread) {
auto nodeIt = kq->notes.end();
for (auto it = kq->notes.begin(); it != kq->notes.end(); ++it) {
if (it->event.ident == change.ident && it->event.filter == change.filter) {
nodeIt = it;
break;
}
}
if (change.flags & kEvDelete) {
if (nodeIt == kq->notes.end()) {
return orbis::ErrorCode::NOENT;
}
kq->notes.erase(nodeIt);
nodeIt = kq->notes.end();
}
std::unique_lock<shared_mutex> noteLock;
if (change.flags & kEvAdd) {
if (nodeIt == kq->notes.end()) {
auto &note = kq->notes.emplace_front();
note.event.flags &= ~(kEvAdd | kEvDelete | kEvDisable | kEvEnable);
note.queue = kq;
note.event = change;
note.enabled = true;
nodeIt = kq->notes.begin();
if (change.filter == kEvFiltProc) {
auto process = g_context.findProcessById(change.ident);
if (process == nullptr) {
return ErrorCode::SRCH;
}
noteLock = std::unique_lock(nodeIt->mutex);
std::unique_lock lock(process->event.mutex);
process->event.notes.insert(&*nodeIt);
nodeIt->linked = process;
if ((change.fflags & orbis::kNoteExit) != 0 &&
process->exitStatus.has_value()) {
note.event.data = *process->exitStatus;
note.triggered = true;
kq->cv.notify_all(kq->mtx);
}
} else if (change.filter == kEvFiltRead ||
change.filter == kEvFiltWrite) {
auto fd = thread->tproc->fileDescriptors.get(change.ident);
if (fd == nullptr) {
return ErrorCode::BADF;
}
nodeIt->file = fd;
if (auto eventEmitter = fd->event) {
eventEmitter->subscribe(&*nodeIt);
nodeIt->triggered = true;
kq->cv.notify_all(kq->mtx);
} else if (note.file->hostFd < 0) {
ORBIS_LOG_ERROR("Unimplemented event emitter", change.ident);
}
} else if (change.filter == kEvFiltGraphicsCore ||
change.filter == kEvFiltDisplay) {
g_context.deviceEventEmitter->subscribe(&*nodeIt);
}
}
}
if (nodeIt == kq->notes.end()) {
if (change.flags & kEvDelete) {
return {};
}
return orbis::ErrorCode::NOENT;
}
if (change.filter == kEvFiltDisplay || change.filter == kEvFiltGraphicsCore) {
change.flags |= kEvClear;
}
if (!noteLock.owns_lock()) {
noteLock = std::unique_lock(nodeIt->mutex);
}
if (change.flags & kEvDisable) {
nodeIt->enabled = false;
}
if (change.flags & kEvEnable) {
nodeIt->enabled = true;
}
if (change.flags & kEvClear) {
nodeIt->triggered = false;
}
if (change.filter == kEvFiltUser) {
auto fflags = 0;
switch (change.fflags & kNoteFFCtrlMask) {
case kNoteFFAnd:
fflags = nodeIt->event.fflags & change.fflags;
break;
case kNoteFFOr:
fflags = nodeIt->event.fflags | change.fflags;
break;
case kNoteFFCopy:
fflags = change.fflags;
break;
}
nodeIt->event.fflags =
(nodeIt->event.fflags & ~kNoteFFlagsMask) | (fflags & kNoteFFlagsMask);
if (change.fflags & kNoteTrigger) {
nodeIt->event.udata = change.udata;
nodeIt->triggered = true;
kq->cv.notify_all(kq->mtx);
}
} else if (change.filter == kEvFiltDisplay && change.ident >> 48 == 0x6301) {
nodeIt->triggered = true;
kq->cv.notify_all(kq->mtx);
} else if (change.filter == kEvFiltGraphicsCore && change.ident == 0x84) {
nodeIt->triggered = true;
nodeIt->event.data |= 1000ull << 16; // clock
kq->cv.notify_all(kq->mtx);
} else if (g_context.fwType == FwType::Ps5 &&
change.filter == kEvFiltGraphicsCore && change.ident == 0) {
nodeIt->triggered = true;
kq->cv.notify_all(kq->mtx);
}
return {};
}
static orbis::ErrorCode ureadTimespec(orbis::timespec &ts,
orbis::ptr<const orbis::timespec> addr) {
orbis::ErrorCode error = uread(ts, addr);
if (error != orbis::ErrorCode{})
return error;
if (ts.sec < 0 || ts.nsec < 0 || ts.nsec > 1000000000) {
return orbis::ErrorCode::INVAL;
}
return {};
}
} // namespace orbis
orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
ptr<KEvent> changelist, sint nchanges,
ptr<KEvent> eventlist, sint nevents,
ptr<const timespec> timeout) {
// ORBIS_LOG_TODO(__FUNCTION__, fd, changelist, nchanges, eventlist, nevents,
// timeout);
auto kq = thread->tproc->fileDescriptors.get(fd).cast<KQueue>();
if (kq == nullptr) {
return orbis::ErrorCode::BADF;
}
{
std::lock_guard lock(kq->mtx);
if (nchanges != 0) {
for (auto &changePtr : std::span(changelist, nchanges)) {
KEvent change;
ORBIS_RET_ON_ERROR(uread(change, &changePtr));
if (change.filter != kEvFiltUser) {
ORBIS_LOG_NOTICE(__FUNCTION__, fd, change.ident, change.filter,
change.flags, change.fflags, change.data,
change.udata);
}
if (auto result = keventChange(kq.get(), change, thread);
result.value() != 0) {
return result;
}
}
kq->cv.notify_all(kq->mtx);
}
}
if (nevents == 0) {
return {};
}
using clock = std::chrono::high_resolution_clock;
clock::time_point timeoutPoint = clock::time_point::max();
if (timeout != nullptr) {
timespec _timeout;
auto result = ureadTimespec(_timeout, timeout);
if (result != ErrorCode{}) {
return result;
}
__uint128_t nsec = _timeout.sec;
nsec *= 1000'000'000;
nsec += _timeout.nsec;
if (nsec < INT64_MAX) {
auto now = clock::now();
auto nowValue = now.time_since_epoch().count();
if (nowValue <= nowValue + nsec) {
timeoutPoint = now + std::chrono::nanoseconds(nsec);
}
}
}
std::vector<KEvent> result;
result.reserve(nevents);
ErrorCode errorCode{};
while (true) {
bool canSleep = true;
{
std::lock_guard lock(kq->mtx);
while (result.size() < nevents && !kq->triggeredEvents.empty()) {
result.push_back(kq->triggeredEvents.back());
kq->triggeredEvents.pop_back();
}
if (result.empty()) {
for (auto it = kq->notes.begin(); it != kq->notes.end();) {
auto &note = *it;
bool erase = false;
{
std::lock_guard lock(note.mutex);
if (!note.triggered) {
if (note.event.filter == kEvFiltRead) {
if (note.file->hostFd >= 0) {
if (isReadEventTriggered(note.file->hostFd)) {
note.triggered = true;
} else {
canSleep = false;
}
}
} else if (note.event.filter == kEvFiltWrite) {
if (note.file->hostFd >= 0) {
if (isWriteEventTriggered(note.file->hostFd)) {
note.triggered = true;
} else {
canSleep = false;
}
}
}
}
if (note.enabled && note.triggered) {
result.push_back(note.event);
if (note.event.filter == kEvFiltDisplay) {
note.triggered = false;
} else if (note.event.filter == kEvFiltGraphicsCore &&
note.event.ident != 0x84) {
note.triggered = false;
}
if (note.event.flags & kEvDispatch) {
note.enabled = false;
}
if (note.event.flags & kEvOneshot) {
erase = true;
}
if (note.event.filter == kEvFiltRead ||
note.event.filter == kEvFiltWrite) {
note.triggered = false;
}
}
}
if (erase) {
it = kq->notes.erase(it);
} else {
++it;
}
}
while (result.size() > nevents) {
kq->triggeredEvents.push_back(result.back());
result.pop_back();
}
}
}
if (!result.empty()) {
break;
}
if (timeoutPoint != clock::time_point::max()) {
std::lock_guard lock(kq->mtx);
auto now = clock::now();
if (now >= timeoutPoint) {
errorCode = ErrorCode::TIMEDOUT;
break;
}
auto waitTimeout = std::chrono::duration_cast<std::chrono::microseconds>(
timeoutPoint - now);
if (canSleep) {
if (waitTimeout.count() > 1000) {
orbis::scoped_unblock unblock;
kq->cv.wait(kq->mtx, waitTimeout.count());
} else {
kq->cv.wait(kq->mtx, waitTimeout.count());
}
}
} else {
if (canSleep) {
std::lock_guard lock(kq->mtx);
orbis::scoped_unblock unblock;
kq->cv.wait(kq->mtx);
} else {
std::this_thread::sleep_for(std::chrono::microseconds(30));
}
}
}
// ORBIS_LOG_TODO(__FUNCTION__, "kevent wakeup", fd);
// for (auto evt : result) {
// ORBIS_LOG_TODO(__FUNCTION__,
// evt.ident,
// evt.filter,
// evt.flags,
// evt.fflags,
// evt.data,
// evt.udata
// );
// }
ORBIS_RET_ON_ERROR(
uwriteRaw(eventlist, result.data(), result.size() * sizeof(KEvent)));
thread->retval[0] = result.size();
return {};
}

View file

@ -0,0 +1,23 @@
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
orbis::SysResult orbis::sys_execve(Thread *thread, ptr<char> fname,
ptr<ptr<char>> argv, ptr<ptr<char>> envv) {
if (auto execve = thread->tproc->ops->execve) {
return execve(thread, fname, argv, envv);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fexecve(Thread *thread, sint fd,
ptr<ptr<char>> argv, ptr<ptr<char>> envv) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_execve(Thread *thread, ptr<char> fname,
ptr<ptr<char>> argv,
ptr<ptr<char>> envv,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,59 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "utils/Logs.hpp"
#include <sys/resource.h>
#include <sys/wait.h>
#include <unistd.h>
orbis::SysResult orbis::sys_exit(Thread *thread, sint status) {
if (auto exit = thread->tproc->ops->exit) {
return exit(thread, status);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_abort2(Thread *thread, ptr<const char> why,
sint narg, ptr<ptr<void>> args) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr<sint> status,
sint options, ptr<struct rusage> rusage) {
// TODO
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage);
int hostPid = pid;
if (pid > 0) {
auto process = g_context.findProcessById(pid);
if (process == nullptr) {
return ErrorCode::SRCH;
}
hostPid = process->hostPid;
}
::rusage hostUsage;
while (true) {
int stat;
int result = ::wait4(hostPid, &stat, options, &hostUsage);
if (result < 0) {
return static_cast<ErrorCode>(errno);
}
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat);
auto process = g_context.findProcessByHostId(result);
if (process == nullptr) {
ORBIS_LOG_ERROR("host process not found", result);
continue;
}
if (status != nullptr) {
ORBIS_RET_ON_ERROR(uwrite(status, stat));
}
thread->retval[0] = process->pid;
break;
}
return {};
}

View file

@ -0,0 +1,24 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include <cstdlib>
#include <unistd.h>
orbis::SysResult orbis::sys_fork(Thread *thread) {
if (auto fork = thread->tproc->ops->fork) {
return fork(thread, RFFDG | RFPROC);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_pdfork(Thread *thread, ptr<sint> fdp, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_vfork(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_rfork(Thread *thread, sint flags) {
if (auto fork = thread->tproc->ops->fork) {
return fork(thread, flags);
}
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,507 @@
#include "file.hpp"
#include "orbis/utils/Logs.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/Thread.hpp"
#include "uio.hpp"
#include <sstream>
orbis::SysResult orbis::sys_read(Thread *thread, sint fd, ptr<void> buf,
size_t nbyte) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto read = file->ops->read;
if (read == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
IoVec vec{.base = (void *)buf, .len = nbyte};
Uio io{
.offset = file->nextOff,
.iov = &vec,
.iovcnt = 1,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Read,
.td = thread,
};
auto error = read(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
if (error == ErrorCode::BUSY) {
return SysResult::notAnError(error);
}
return error;
}
auto cnt = io.offset - file->nextOff;
file->nextOff = io.offset;
// ORBIS_LOG_ERROR(__FUNCTION__, fd, buf, nbyte, cnt);
thread->retval[0] = cnt;
return {};
}
orbis::SysResult orbis::sys_pread(Thread *thread, sint fd, ptr<void> buf,
size_t nbyte, off_t offset) {
// ORBIS_LOG_ERROR(__FUNCTION__, fd, buf, nbyte, offset);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto read = file->ops->read;
if (read == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
IoVec vec{.base = (void *)buf, .len = nbyte};
Uio io{
.offset = static_cast<std::uint64_t>(offset),
.iov = &vec,
.iovcnt = 1,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Read,
.td = thread,
};
auto error = read(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
return error;
}
thread->retval[0] = io.offset - offset;
return {};
}
orbis::SysResult orbis::sys_freebsd6_pread(Thread *thread, sint fd,
ptr<void> buf, size_t nbyte, sint,
off_t offset) {
return sys_pread(thread, fd, buf, nbyte, offset);
}
orbis::SysResult orbis::sys_readv(Thread *thread, sint fd, ptr<IoVec> iovp,
uint iovcnt) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto read = file->ops->read;
if (read == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
Uio io{
.offset = file->nextOff,
.iov = iovp,
.iovcnt = iovcnt,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Read,
.td = thread,
};
auto error = read(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
return error;
}
auto cnt = io.offset - file->nextOff;
file->nextOff = io.offset;
thread->retval[0] = cnt;
return {};
}
orbis::SysResult orbis::sys_preadv(Thread *thread, sint fd, ptr<IoVec> iovp,
uint iovcnt, off_t offset) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto read = file->ops->read;
if (read == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
Uio io{
.offset = static_cast<std::uint64_t>(offset),
.iov = iovp,
.iovcnt = iovcnt,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Read,
.td = thread,
};
auto error = read(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
return error;
}
thread->retval[0] = io.offset - offset;
return {};
}
orbis::SysResult orbis::sys_write(Thread *thread, sint fd, ptr<const void> buf,
size_t nbyte) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto write = file->ops->write;
if (write == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
IoVec vec{.base = (void *)buf, .len = nbyte};
Uio io{
.offset = file->nextOff,
.iov = &vec,
.iovcnt = 1,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Write,
.td = thread,
};
auto error = write(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
return error;
}
auto cnt = io.offset - file->nextOff;
file->nextOff = io.offset;
thread->retval[0] = cnt;
return {};
}
orbis::SysResult orbis::sys_pwrite(Thread *thread, sint fd, ptr<const void> buf,
size_t nbyte, off_t offset) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto write = file->ops->write;
if (write == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
IoVec vec{.base = (void *)buf, .len = nbyte};
Uio io{
.offset = static_cast<std::uint64_t>(offset),
.iov = &vec,
.iovcnt = 1,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Write,
.td = thread,
};
auto error = write(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
return error;
}
thread->retval[0] = io.offset - offset;
return {};
}
orbis::SysResult orbis::sys_freebsd6_pwrite(Thread *thread, sint fd,
ptr<const void> buf, size_t nbyte,
sint, off_t offset) {
return sys_pwrite(thread, fd, buf, nbyte, offset);
}
orbis::SysResult orbis::sys_writev(Thread *thread, sint fd, ptr<IoVec> iovp,
uint iovcnt) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto write = file->ops->write;
if (write == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
Uio io{
.offset = file->nextOff,
.iov = iovp,
.iovcnt = iovcnt,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Write,
.td = thread,
};
auto error = write(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
return error;
}
auto cnt = io.offset - file->nextOff;
file->nextOff = io.offset;
thread->retval[0] = cnt;
return {};
}
orbis::SysResult orbis::sys_pwritev(Thread *thread, sint fd, ptr<IoVec> iovp,
uint iovcnt, off_t offset) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto write = file->ops->write;
if (write == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
Uio io{
.offset = static_cast<std::uint64_t>(offset),
.iov = iovp,
.iovcnt = iovcnt,
.segflg = UioSeg::UserSpace,
.rw = UioRw::Write,
.td = thread,
};
auto error = write(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
return error;
}
thread->retval[0] = io.offset - offset;
return {};
}
orbis::SysResult orbis::sys_ftruncate(Thread *thread, sint fd, off_t length) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto truncate = file->ops->truncate;
if (truncate == nullptr) {
return ErrorCode::NOTSUP;
}
ORBIS_LOG_WARNING(__FUNCTION__, fd, length);
std::lock_guard lock(file->mtx);
return truncate(file.get(), length, thread);
}
orbis::SysResult orbis::sys_freebsd6_ftruncate(Thread *thread, sint fd, sint,
off_t length) {
return sys_ftruncate(thread, fd, length);
}
// clang-format off
#define IOCPARM_SHIFT 13 /* number of bits for ioctl size */
#define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask */
#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
#define IOCGROUP(x) (((x) >> 8) & 0xff)
#define IOCPARM_MAX (1 << IOCPARM_SHIFT) /* max size of ioctl */
#define IOC_VOID 0x20000000 /* no parameters */
#define IOC_OUT 0x40000000 /* copy out parameters */
#define IOC_IN 0x80000000 /* copy in parameters */
#define IOC_INOUT (IOC_IN | IOC_OUT)
#define IOC_DIRMASK (IOC_VOID | IOC_OUT | IOC_IN)
#define _IOC(inout, group, num, len) \
((unsigned long)((inout) | (((len) & IOCPARM_MASK) << 16) | ((group) << 8) | \
(num)))
#define _IO(g, n) _IOC(IOC_VOID, (g), (n), 0)
#define _IOWINT(g, n) _IOC(IOC_VOID, (g), (n), sizeof(int))
#define _IOR(g, n, t) _IOC(IOC_OUT, (g), (n), sizeof(t))
#define _IOW(g, n, t) _IOC(IOC_IN, (g), (n), sizeof(t))
/* this should be _IORW, but stdio got there first */
#define _IOWR(g, n, t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
// clang-format on
static std::string iocGroupToString(unsigned iocGroup) {
if (iocGroup >= 128) {
const char *sceGroups[] = {
"DEV",
"DMEM",
"GC",
"DCE",
"UVD",
"VCE",
"DBGGC",
"TWSI",
"MDBG",
"DEVENV",
"AJM",
"TRACE",
"IBS",
"MBUS",
"HDMI",
"CAMERA",
"FAN",
"THERMAL",
"PFS",
"ICC_CONFIG",
"IPC",
"IOSCHED",
"ICC_INDICATOR",
"EXFATFS",
"ICC_NVS",
"DVE",
"ICC_POWER",
"AV_CONTROL",
"ICC_SC_CONFIGURATION",
"ICC_DEVICE_POWER",
"SSHOT",
"DCE_SCANIN",
"FSCTRL",
"HMD",
"SHM",
"PHYSHM",
"HMDDFU",
"BLUETOOTH_HID",
"SBI",
"S3DA",
"SPM",
"BLOCKPOOL",
"SDK_EVENTLOG",
};
if (iocGroup - 127 >= std::size(sceGroups)) {
return "'?'";
}
return sceGroups[iocGroup - 127];
}
if (isprint(iocGroup)) {
return "'" + std::string(1, (char)iocGroup) + "'";
}
return "'?'";
}
static void printIoctl(unsigned long arg) {
std::printf("0x%lx { IO%s%s %lu(%s), %lu, %lu }\n", arg,
arg & IOC_OUT ? "R" : "", arg & IOC_IN ? "W" : "", IOCGROUP(arg),
iocGroupToString(IOCGROUP(arg)).c_str(), arg & 0xFF,
IOCPARM_LEN(arg));
}
static void ioctlToStream(std::ostream &stream, unsigned long arg) {
stream << "0x" << std::hex << arg << " { IO";
if ((arg & IOC_OUT) != 0) {
stream << 'R';
}
if ((arg & IOC_IN) != 0) {
stream << 'W';
}
if ((arg & IOC_VOID) != 0) {
stream << 'i';
}
stream << " 0x" << IOCGROUP(arg);
stream << "('" << iocGroupToString(IOCGROUP(arg)) << "'), ";
stream << std::dec << (arg & 0xFF) << ", " << IOCPARM_LEN(arg) << " }";
}
static std::string ioctlToString(unsigned long arg) {
std::ostringstream stream;
ioctlToStream(stream, arg);
return std::move(stream).str();
}
orbis::SysResult orbis::sys_ioctl(Thread *thread, sint fd, ulong com,
caddr_t data) {
auto str = ioctlToString(com);
// ORBIS_LOG_WARNING(__FUNCTION__, fd, com, str);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto ioctl = file->ops->ioctl;
if (ioctl == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
return ioctl(file.get(), com, data, thread);
}
orbis::SysResult orbis::sys_pselect(Thread *thread, sint nd, ptr<fd_set> in,
ptr<fd_set> ou, ptr<fd_set> ex,
ptr<const timespec> ts,
ptr<const sigset_t> sm) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_select(Thread *thread, sint nd,
ptr<struct fd_set_t> in,
ptr<struct fd_set_t> out,
ptr<struct fd_set_t> ex,
ptr<struct timeval> tv) {
if (tv == nullptr) {
orbis::scoped_unblock_now unblock;
std::this_thread::sleep_for(std::chrono::days(1));
} else {
std::this_thread::sleep_for(std::chrono::seconds(tv->tv_sec));
return orbis::ErrorCode::TIMEDOUT;
}
return {};
}
orbis::SysResult orbis::sys_poll(Thread *thread, ptr<struct pollfd> fds,
uint nfds, sint timeout) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_openbsd_poll(Thread *thread, ptr<struct pollfd> fds,
uint nfds, sint timeout) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_nlm_syscall(Thread *thread, sint debug_level,
sint grace_period, sint addr_count,
ptr<ptr<char>> addrs) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_nfssvc(Thread *thread, sint flag, caddr_t argp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sysarch(Thread *thread, sint op, ptr<char> parms) {
if (op == 129) {
uint64_t fs;
if (auto error = uread(fs, (ptr<uint64_t>)parms); error != ErrorCode{})
return error;
ORBIS_LOG_WARNING("sys_sysarch: set FS", (std::size_t)fs);
thread->fsBase = fs;
return {};
}
ORBIS_LOG_WARNING(__FUNCTION__, op, parms);
return {};
}
orbis::SysResult orbis::sys_nnpfs_syscall(Thread *thread, sint operation,
ptr<char> a_pathP, sint opcode,
ptr<void> a_paramsP,
sint a_followSymlinks) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_afs3_syscall(Thread *thread, slong syscall,
slong param1, slong param2,
slong param3, slong param4,
slong param5, slong param6) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_gssd_syscall(Thread *thread, ptr<char> path) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,19 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_jail(Thread *thread, ptr<struct jail> jail) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_jail_set(Thread *thread, ptr<IoVec> iovp,
uint iovcnt, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_jail_get(Thread *thread, ptr<IoVec> iovp,
uint iovcnt, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_jail_remove(Thread *thread, sint jid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_jail_attach(Thread *thread, sint jid) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,10 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_ktrace(Thread *thread, ptr<const char> fname,
sint ops, sint facs, sint pit) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_utrace(Thread *thread, ptr<const void> addr,
size_t len) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,29 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_kldload(Thread *thread, ptr<const char> file) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kldunload(Thread *thread, sint fileid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kldunloadf(Thread *thread, slong fileid,
sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kldfind(Thread *thread, ptr<const char> name) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kldnext(Thread *thread, sint fileid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kldstat(Thread *thread, sint fileid,
ptr<struct kld_file_stat> stat) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kldfirstmod(Thread *thread, sint fileid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kldsym(Thread *thread, sint fileid, sint cmd,
ptr<void> data) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,9 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_getloginclass(Thread *thread, ptr<char> namebuf,
size_t namelen) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setloginclass(Thread *thread, ptr<char> namebuf) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,44 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys___mac_get_pid(Thread *thread, pid_t pid,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_get_proc(Thread *thread,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_set_proc(Thread *thread,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_get_fd(Thread *thread, sint fd,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_get_file(Thread *thread, ptr<const char> path,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_set_fd(Thread *thread, sint fd,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_set_file(Thread *thread, ptr<const char> path,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_get_link(Thread *thread,
ptr<const char> path_p,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___mac_set_link(Thread *thread,
ptr<const char> path_p,
ptr<struct mac> mac_p) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mac_syscall(Thread *thread, ptr<const char> policy,
sint call, ptr<void> arg) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,15 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_modnext(Thread *thread, sint modid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_modfnext(Thread *thread, sint modid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_modstat(Thread *thread, sint modid,
ptr<struct module_stat> stat) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_modfind(Thread *thread, ptr<const char> name) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,22 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_msgctl(Thread *thread, sint msqid, sint cmd,
ptr<struct msqid_ds> buf) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_msgget(Thread *thread, key_t key, sint msgflg) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_msgsnd(Thread *thread, sint msqid,
ptr<const void> msgp, size_t msgsz,
sint msgflg) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_msgrcv(Thread *thread, sint msqid, ptr<void> msgp,
size_t msgsz, slong msgtyp, sint msgflg) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_msgsys(Thread *thread, sint which, sint a2, sint a3,
sint a4, sint a5, sint a6) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,13 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_ntp_gettime(Thread *thread,
ptr<struct ntptimeval> ntvp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ntp_adjtime(Thread *thread, ptr<struct timex> tp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_adjtime(Thread *thread, ptr<struct timeval> delta,
ptr<struct timeval> olddelta) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,42 @@
#include "sys/sysproto.hpp"
#include "thread/Thread.hpp"
#include "utils/Logs.hpp"
#include <thread>
orbis::SysResult
orbis::sys_sched_setparam(Thread *thread, pid_t pid,
ptr<const struct sched_param> param) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sched_getparam(Thread *thread, pid_t pid,
ptr<struct sched_param> param) {
return ErrorCode::NOSYS;
}
orbis::SysResult
orbis::sys_sched_setscheduler(Thread *thread, pid_t pid, sint policy,
ptr<const struct sched_param> param) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sched_getscheduler(Thread *thread, pid_t pid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sched_yield(Thread *thread) {
std::this_thread::yield();
return {};
}
orbis::SysResult orbis::sys_sched_get_priority_max(Thread *thread,
sint policy) {
ORBIS_LOG_ERROR(__FUNCTION__, policy);
thread->retval[0] = 90;
return {};
}
orbis::SysResult orbis::sys_sched_get_priority_min(Thread *thread,
sint policy) {
ORBIS_LOG_ERROR(__FUNCTION__, policy);
thread->retval[0] = 10;
return {};
}
orbis::SysResult orbis::sys_sched_rr_get_interval(Thread *thread, pid_t pid,
ptr<timespec> interval) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,15 @@
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/Thread.hpp"
#include "utils/Logs.hpp"
#include <pipe.hpp>
orbis::SysResult orbis::sys_pipe(Thread *thread) {
auto [a, b] = createPipe();
auto fd0 = thread->tproc->fileDescriptors.insert(a);
auto fd1 = thread->tproc->fileDescriptors.insert(b);
ORBIS_LOG_ERROR(__FUNCTION__, fd0, fd1);
thread->retval[0] = fd0;
thread->retval[1] = fd1;
return {};
}

View file

@ -0,0 +1,5 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_pdgetpid(Thread *thread, sint fd, ptr<pid_t> pidp) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,6 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_ptrace(Thread *thread, sint req, pid_t pid,
caddr_t addr, sint data) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,90 @@
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/Thread.hpp"
#include "utils/Logs.hpp"
orbis::SysResult orbis::sys_getpid(Thread *thread) {
thread->retval[0] = thread->tproc->pid;
return {};
}
orbis::SysResult orbis::sys_getppid(Thread *thread) {
thread->retval[0] = thread->tproc->parentProcess
? thread->tproc->parentProcess->pid
: thread->tproc->pid;
return {};
}
orbis::SysResult orbis::sys_getpgrp(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_getpgid(Thread *thread, pid_t pid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getsid(Thread *thread, pid_t pid) { return {}; }
orbis::SysResult orbis::sys_getuid(Thread *thread) {
thread->retval[0] = 1;
return {};
}
orbis::SysResult orbis::sys_geteuid(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_getgid(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_getegid(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_getgroups(Thread *thread, uint gidsetsize,
ptr<gid_t> gidset) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setsid(Thread *thread) {
ORBIS_LOG_WARNING(__FUNCTION__);
return {};
}
orbis::SysResult orbis::sys_setpgid(Thread *thread, sint pid, sint pgid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setuid(Thread *thread, uid_t uid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_seteuid(Thread *thread, uid_t euid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setgid(Thread *thread, gid_t gid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setegid(Thread *thread, gid_t egid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setgroups(Thread *thread, uint gidsetsize,
ptr<gid_t> gidset) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setreuid(Thread *thread, sint ruid, sint euid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setregid(Thread *thread, sint rgid, sint egid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setresuid(Thread *thread, uid_t ruid, uid_t euid,
uid_t suid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setresgid(Thread *thread, gid_t rgid, gid_t egid,
gid_t sgid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getresuid(Thread *thread, ptr<uid_t> ruid,
ptr<uid_t> euid, ptr<uid_t> suid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getresgid(Thread *thread, ptr<gid_t> rgid,
ptr<gid_t> egid, ptr<gid_t> sgid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_issetugid(Thread *thread) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___setugid(Thread *thread, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getlogin(Thread *thread, ptr<char> namebuf,
uint namelen) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setlogin(Thread *thread, ptr<char> namebuf) {
ORBIS_LOG_WARNING(__FUNCTION__, namebuf);
return {};
}

View file

@ -0,0 +1,5 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_posix_openpt(Thread *thread, sint flags) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,32 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_rctl_get_racct(Thread *thread,
ptr<const void> inbufp,
size_t inbuflen, ptr<void> outbuf,
size_t outbuflen) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_rctl_get_rules(Thread *thread,
ptr<const void> inbufp,
size_t inbuflen, ptr<void> outbuf,
size_t outbuflen) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_rctl_get_limits(Thread *thread,
ptr<const void> inbufp,
size_t inbuflen, ptr<void> outbuf,
size_t outbuflen) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_rctl_add_rule(Thread *thread,
ptr<const void> inbufp,
size_t inbuflen, ptr<void> outbuf,
size_t outbuflen) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_rctl_remove_rule(Thread *thread,
ptr<const void> inbufp,
size_t inbuflen, ptr<void> outbuf,
size_t outbuflen) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,140 @@
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/Thread.hpp"
#include "utils/Logs.hpp"
#include <sched.h>
namespace orbis {
struct rlimit {
int64_t softLimit;
int64_t hardLimit;
};
} // namespace orbis
orbis::SysResult orbis::sys_getpriority(Thread *thread, sint which, sint who) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setpriority(Thread *thread, sint which, sint who,
sint prio) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_rtprio_thread(Thread *thread, sint function,
lwpid_t lwpid,
ptr<struct rtprio> rtp) {
ORBIS_LOG_ERROR(__FUNCTION__, function, lwpid, rtp->prio, rtp->type);
thread->where();
Thread *targetThread;
if (lwpid == thread->tid || lwpid == -1) {
targetThread = thread;
} else {
targetThread = thread->tproc->threadsMap.get(lwpid - thread->tproc->pid);
if (targetThread == nullptr) {
return ErrorCode::SRCH;
}
}
if (function == 0) {
return orbis::uwrite(rtp, targetThread->prio);
} else if (function == 1) {
ORBIS_RET_ON_ERROR(orbis::uread(targetThread->prio, rtp));
int hostPolicy = SCHED_RR;
auto prioMin = sched_get_priority_min(hostPolicy);
auto prioMax = sched_get_priority_max(hostPolicy);
auto hostPriority =
(targetThread->prio.prio * (prioMax - prioMin + 1)) / 1000 - prioMin;
::sched_param hostParam{};
hostParam.sched_priority = hostPriority;
if (pthread_setschedparam(targetThread->getNativeHandle(), hostPolicy,
&hostParam)) {
auto normPrio = targetThread->prio.prio / 1000.f;
hostParam.sched_priority = 0;
if (normPrio < 0.3f) {
hostPolicy = SCHED_BATCH;
} else if (normPrio < 0.7f) {
hostPolicy = SCHED_OTHER;
} else {
hostPolicy = SCHED_IDLE;
}
if (pthread_setschedparam(targetThread->getNativeHandle(), hostPolicy,
&hostParam)) {
ORBIS_LOG_ERROR(
__FUNCTION__, "failed to set host priority", hostPriority,
targetThread->prio.prio, targetThread->prio.type, errno,
targetThread->getNativeHandle(), prioMin, prioMax, errno);
}
} else {
ORBIS_LOG_ERROR(__FUNCTION__, "set host priority", hostPriority,
targetThread->tid, targetThread->prio.prio,
targetThread->prio.type, prioMin, prioMax);
}
}
return {};
}
orbis::SysResult orbis::sys_rtprio(Thread *thread, sint function, pid_t pid,
ptr<struct rtprio> rtp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setrlimit(Thread *thread, uint which,
ptr<struct rlimit> rlp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getrlimit(Thread *thread, uint which,
ptr<struct rlimit> rlp) {
switch (which) {
case 0: { // cpu
break;
}
case 1: { // fsize
break;
}
case 2: { // data
break;
}
case 3: { // stack
break;
}
case 4: { // core
break;
}
case 5: { // rss
break;
}
case 6: { // memlock
break;
}
case 7: { // nproc
break;
}
case 8: { // nofile
break;
}
case 9: { // sbsize
break;
}
case 10: { // vmem
break;
}
case 11: { // npts
break;
}
case 12: { // swap
break;
}
default:
return ErrorCode::INVAL;
}
rlp->softLimit = 4096;
rlp->hardLimit = 4096;
return {};
}
orbis::SysResult orbis::sys_getrusage(Thread *thread, sint who,
ptr<struct rusage> rusage) {
return {};
}

View file

@ -0,0 +1,5 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_setfib(Thread *thread, sint fib) {
return ErrorCode::NOSYS;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys___semctl(Thread *thread, sint semid, sint semnum,
sint cmd, ptr<union semun> arg) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_semget(Thread *thread, key_t key, sint nsems,
sint semflg) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_semop(Thread *thread, sint semid,
ptr<struct sembuf> sops, size_t nspos) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_semsys(Thread *thread, sint which, sint a2, sint a3,
sint a4, sint a5) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,21 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_shmdt(Thread *thread, ptr<const void> shmaddr) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_shmat(Thread *thread, sint shmid,
ptr<const void> shmaddr, sint shmflg) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_shmctl(Thread *thread, sint shmid, sint cmd,
ptr<struct shmid_ds> buf) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_shmget(Thread *thread, key_t key, size_t size,
sint shmflg) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_shmsys(Thread *thread, sint which, sint a2, sint a3,
sint a4) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,5 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_reboot(Thread *thread, sint opt) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,153 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
#include "ucontext.hpp"
#include "utils/Logs.hpp"
#include <csignal>
orbis::SysResult orbis::sys_sigaction(Thread *thread, sint sig,
ptr<SigAction> act, ptr<SigAction> oact) {
ORBIS_LOG_WARNING(__FUNCTION__, sig, act, oact);
auto &sigAct = thread->tproc->sigActions[sig];
if (oact != nullptr) {
if (auto errc = uwrite(oact, sigAct); errc != orbis::ErrorCode{}) {
return errc;
}
}
if (act != nullptr) {
if (auto errc = uread(sigAct, act); errc != ErrorCode{}) {
return errc;
}
ORBIS_LOG_WARNING(__FUNCTION__, sigAct.handler, sigAct.flags,
sigAct.mask.bits[0], sigAct.mask.bits[1],
sigAct.mask.bits[2], sigAct.mask.bits[3]);
}
return {};
}
orbis::SysResult orbis::sys_sigprocmask(Thread *thread, sint how,
ptr<SigSet> set, ptr<SigSet> oset) {
std::lock_guard lock(thread->mtx);
if (oset) {
ORBIS_RET_ON_ERROR(uwrite(oset, thread->sigMask));
}
if (set) {
SigSet _set;
ORBIS_RET_ON_ERROR(uread(_set, set));
auto newSigMask = thread->sigMask;
auto oldSigMask = newSigMask;
switch (how) {
case 1: // block
for (std::size_t i = 0; i < 4; ++i) {
newSigMask.bits[i] |= _set.bits[i];
}
break;
case 2: // unblock
for (std::size_t i = 0; i < 4; ++i) {
newSigMask.bits[i] &= ~_set.bits[i];
}
break;
case 3: // set
newSigMask = _set;
break;
default:
ORBIS_LOG_ERROR("sys_sigprocmask: unimplemented how", how);
thread->where();
return ErrorCode::INVAL;
}
newSigMask.clear(kSigKill);
newSigMask.clear(kSigStop);
thread->sigMask = newSigMask;
for (std::size_t word = 0; word < std::size(newSigMask.bits); ++word) {
auto unblockedBits = ~oldSigMask.bits[word] & newSigMask.bits[word];
std::uint32_t offset = word * 32 + 1;
for (std::uint32_t i = std::countr_zero(unblockedBits); i < 32;
i += std::countr_zero(unblockedBits >> (i + 1)) + 1) {
thread->notifyUnblockedSignal(offset + i);
}
}
}
return {};
}
orbis::SysResult orbis::sys_sigwait(Thread *thread, ptr<const SigSet> set,
ptr<sint> sig) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sigtimedwait(Thread *thread, ptr<const SigSet> set,
ptr<struct siginfo> info,
ptr<const timespec> timeout) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sigwaitinfo(Thread *thread, ptr<const SigSet> set,
ptr<struct siginfo> info) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sigpending(Thread *thread, ptr<SigSet> set) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sigsuspend(Thread *thread, ptr<const SigSet> set) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sigaltstack(Thread *thread, ptr<struct stack_t> ss,
ptr<struct stack_t> oss) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kill(Thread *thread, sint pid, sint signum) {
ORBIS_LOG_WARNING(__FUNCTION__, pid, signum);
int hostPid = pid;
if (pid > 0) {
auto process = g_context.findProcessById(pid);
if (process == nullptr) {
return ErrorCode::SRCH;
}
hostPid = process->hostPid;
}
// FIXME: invoke subscriber thread
int result = ::sigqueue(hostPid, SIGUSR1, {.sival_int = signum});
if (result < 0) {
return static_cast<ErrorCode>(errno);
}
return {};
}
orbis::SysResult orbis::sys_pdkill(Thread *thread, sint fd, sint signum) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sigqueue(Thread *thread, pid_t pid, sint signum,
ptr<void> value) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sigreturn(Thread *thread, ptr<UContext> sigcntxp) {
ORBIS_LOG_WARNING(__FUNCTION__, sigcntxp);
if (auto sigreturn = thread->tproc->ops->sigreturn) {
return sigreturn(thread, sigcntxp);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::nosys(Thread *thread) {
thread->sendSignal(kSigSys);
return {};
}

View file

@ -0,0 +1,6 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_profil(Thread *thread, caddr_t samples, size_t size,
size_t offset, uint scale) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,8 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_swapon(Thread *thread, ptr<char> name) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_swapoff(Thread *thread, ptr<const char> name) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,7 @@
#include "sys/sysproto.hpp"
#include <thread>
orbis::SysResult orbis::sys_yield(Thread *thread) {
std::this_thread::yield();
return {};
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,77 @@
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
#include "ucontext.hpp"
orbis::SysResult orbis::sys_thr_create(Thread *thread, ptr<UContext> ctxt,
ptr<slong> arg, sint flags) {
if (auto thr_create = thread->tproc->ops->thr_create) {
return thr_create(thread, ctxt, arg, flags);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_new(Thread *thread, ptr<struct thr_param> param,
sint param_size) {
if (auto thr_new = thread->tproc->ops->thr_new) {
return thr_new(thread, param, param_size);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_self(Thread *thread, ptr<slong> id) {
return uwrite(id, (slong)thread->tid);
}
orbis::SysResult orbis::sys_thr_exit(Thread *thread, ptr<slong> state) {
if (auto thr_exit = thread->tproc->ops->thr_exit) {
return thr_exit(thread, state);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_kill(Thread *thread, slong id, sint sig) {
if (auto thr_kill = thread->tproc->ops->thr_kill) {
return thr_kill(thread, id, sig);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_kill2(Thread *thread, pid_t pid, slong id,
sint sig) {
if (auto thr_kill2 = thread->tproc->ops->thr_kill2) {
return thr_kill2(thread, pid, id, sig);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_suspend(Thread *thread,
ptr<const timespec> timeout) {
if (auto thr_suspend = thread->tproc->ops->thr_suspend) {
return thr_suspend(thread, timeout);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_wake(Thread *thread, slong id) {
if (auto thr_wake = thread->tproc->ops->thr_wake) {
return thr_wake(thread, id);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_set_name(Thread *thread, slong id,
ptr<const char> name) {
if (auto thr_set_name = thread->tproc->ops->thr_set_name) {
return thr_set_name(thread, id, name);
}
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,199 @@
#include "sys/sysproto.hpp"
#include "time.hpp"
#include "utils/Logs.hpp"
#include <sys/time.h>
enum class ClockId {
Realtime = 0,
Virtual = 1,
Prof = 2,
Monotonic = 4,
Uptime = 5, // FreeBSD-specific
UptimePrecise = 7, // FreeBSD-specific
UptimeFast = 8, // FreeBSD-specific
RealtimePrecise = 9, // FreeBSD-specific
RealtimeFast = 10, // FreeBSD-specific
MonotonicPrecise = 11, // FreeBSD-specific
MonotonicFast = 12, // FreeBSD-specific
Second = 13, // FreeBSD-specific
ThreadCputimeId = 14,
// orbis extension
Proctime = 15,
Network = 16,
DebugNetwork = 17,
AdNetwork = 18,
RawNetwork = 19,
};
orbis::SysResult orbis::sys_clock_gettime(Thread *, clockid_t clock_id,
ptr<timespec> tp) {
timespec result{};
auto getHostClock = [](clockid_t clock_id) {
::timespec hostClock;
::clock_gettime(clock_id, &hostClock);
timespec result;
result.sec = hostClock.tv_sec;
result.nsec = hostClock.tv_nsec;
return result;
};
switch (static_cast<ClockId>(clock_id)) {
case ClockId::Realtime:
case ClockId::RealtimePrecise:
result = getHostClock(CLOCK_REALTIME);
break;
case ClockId::RealtimeFast: {
result = getHostClock(CLOCK_REALTIME); // FIXME
break;
}
case ClockId::Virtual:
ORBIS_LOG_ERROR("Unimplemented ClockId::Virtual\n");
break;
case ClockId::Prof:
ORBIS_LOG_ERROR("Unimplemented ClockId::Prof\n");
break;
case ClockId::Monotonic:
case ClockId::MonotonicPrecise:
case ClockId::Uptime:
case ClockId::UptimePrecise: {
result = getHostClock(CLOCK_MONOTONIC);
break;
}
case ClockId::UptimeFast:
case ClockId::MonotonicFast:
result = getHostClock(CLOCK_MONOTONIC); // FIXME
break;
case ClockId::Second: {
result = getHostClock(CLOCK_MONOTONIC); // FIXME
result.nsec = 0;
break;
}
case ClockId::ThreadCputimeId:
result = getHostClock(CLOCK_THREAD_CPUTIME_ID);
break;
case ClockId::Proctime:
result = getHostClock(CLOCK_PROCESS_CPUTIME_ID);
break;
case ClockId::Network:
// TODO
// ORBIS_LOG_ERROR("Unimplemented ClockId::Network");
result = getHostClock(CLOCK_PROCESS_CPUTIME_ID);
break;
case ClockId::DebugNetwork:
// TODO
// ORBIS_LOG_ERROR("Unimplemented ClockId::DebugNetwork");
result = getHostClock(CLOCK_PROCESS_CPUTIME_ID);
break;
case ClockId::AdNetwork:
// TODO
// ORBIS_LOG_ERROR("Unimplemented ClockId::AdNetwork");
result = getHostClock(CLOCK_PROCESS_CPUTIME_ID);
break;
case ClockId::RawNetwork:
// TODO
// ORBIS_LOG_ERROR("Unimplemented ClockId::RawNetwork");
result = getHostClock(CLOCK_PROCESS_CPUTIME_ID);
break;
default:
return ErrorCode::INVAL;
}
return uwrite(tp, result);
}
orbis::SysResult orbis::sys_clock_settime(Thread *thread, clockid_t clock_id,
ptr<const timespec> tp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_clock_getres(Thread *thread, clockid_t clock_id,
ptr<timespec> tp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_nanosleep(Thread *thread,
cptr<orbis::timespec> rqtp,
ptr<orbis::timespec> rmtp) {
ORBIS_LOG_TRACE(__FUNCTION__, rqtp, rmtp);
struct ::timespec rq;
struct ::timespec rm;
orbis::timespec value;
if (auto e = uread(value, rqtp); e != ErrorCode{})
return e;
rq.tv_sec = value.sec;
rq.tv_nsec = value.nsec;
if (::nanosleep(&rq, &rm) == EINTR) {
if (rmtp) {
value.sec = rm.tv_sec;
value.nsec = rm.tv_nsec;
if (auto e = uwrite(rmtp, value); e != ErrorCode{})
return e;
}
return ErrorCode::INTR;
}
return {};
}
orbis::SysResult orbis::sys_gettimeofday(Thread *thread, ptr<orbis::timeval> tp,
ptr<orbis::timezone> tzp) {
ORBIS_LOG_TRACE(__FUNCTION__, tp, tzp);
struct ::timeval tv;
if (::gettimeofday(&tv, nullptr) != 0)
std::abort();
if (tp) {
orbis::timeval value;
value.tv_sec = tv.tv_sec;
value.tv_usec = tv.tv_usec;
if (auto e = uwrite(tp, value); e != ErrorCode{})
return e;
}
if (tzp) {
struct ::tm tp;
if (localtime_r(&tv.tv_sec, &tp) != &tp)
std::abort();
orbis::timezone value;
value.tz_dsttime = 0; // TODO
value.tz_mineast = tp.tm_gmtoff / 60;
if (auto e = uwrite(tzp, value); e != ErrorCode{})
return e;
}
return {};
}
orbis::SysResult orbis::sys_settimeofday(Thread *thread, ptr<struct timeval> tp,
ptr<orbis::timezone> tzp) {
return {};
}
orbis::SysResult orbis::sys_getitimer(Thread *thread, uint which,
ptr<struct itimerval> itv) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_setitimer(Thread *thread, uint which,
ptr<struct itimerval> itv,
ptr<struct itimerval> oitv) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ktimer_create(Thread *thread, clockid_t clock_id,
ptr<struct sigevent> evp,
ptr<sint> timerid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ktimer_delete(Thread *thread, sint timerid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ktimer_settime(Thread *thread, sint timerid,
sint flags,
ptr<const struct itimerspec> value,
ptr<struct itimerspec> ovalue) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ktimer_gettime(Thread *thread, sint timerid,
ptr<struct itimerspec> value) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ktimer_getoverrun(Thread *thread, sint timerid) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,229 @@
#include "file.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
#include "uio.hpp"
#include "utils/Logs.hpp"
#include <sys/socket.h>
orbis::SysResult orbis::sys_socket(Thread *thread, sint domain, sint type,
sint protocol) {
ORBIS_LOG_TODO(__FUNCTION__, domain, type, protocol);
if (auto socket = thread->tproc->ops->socket) {
Ref<File> file;
auto result = socket(thread, nullptr, domain, type, protocol, &file);
if (result.isError()) {
return result;
}
auto fd = thread->tproc->fileDescriptors.insert(file);
ORBIS_LOG_WARNING("Socket opened", fd);
thread->retval[0] = fd;
return {};
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_bind(Thread *thread, sint s, caddr_t name,
sint namelen) {
// ORBIS_LOG_ERROR(__FUNCTION__, s, name, namelen);
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto bind = file->ops->bind) {
return bind(file.get(), ptr<SocketAddress>(name), namelen, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_listen(Thread *thread, sint s, sint backlog) {
ORBIS_LOG_ERROR(__FUNCTION__, s, backlog);
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto listen = file->ops->listen) {
return listen(file.get(), backlog, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_accept(Thread *thread, sint s,
ptr<SocketAddress> from,
ptr<uint32_t> fromlenaddr) {
ORBIS_LOG_ERROR(__FUNCTION__, s, from, fromlenaddr);
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto accept = file->ops->accept) {
return accept(file.get(), from, fromlenaddr, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_connect(Thread *thread, sint s, caddr_t name,
sint namelen) {
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto connect = file->ops->connect) {
return connect(file.get(), ptr<SocketAddress>(name), namelen, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_socketpair(Thread *thread, sint domain, sint type,
sint protocol, ptr<sint> rsv) {
ORBIS_LOG_TODO(__FUNCTION__, domain, type, protocol, rsv);
if (auto socketpair = thread->tproc->ops->socketpair) {
Ref<File> a;
Ref<File> b;
auto result = socketpair(thread, domain, type, protocol, &a, &b);
if (result.isError()) {
return result;
}
auto aFd = thread->tproc->fileDescriptors.insert(a);
auto bFd = thread->tproc->fileDescriptors.insert(b);
if (auto errc = uwrite(rsv, aFd); errc != ErrorCode{}) {
return errc;
}
return uwrite(rsv + 1, bFd);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sendto(Thread *thread, sint s, caddr_t buf,
size_t len, sint flags, caddr_t to,
sint tolen) {
return {};
}
orbis::SysResult orbis::sys_sendmsg(Thread *thread, sint s,
ptr<struct msghdr> msg, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_recvfrom(Thread *thread, sint s, caddr_t buf,
size_t len, sint flags,
ptr<SocketAddress> from,
ptr<uint32_t> fromlenaddr) {
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto recvfrom = file->ops->recvfrom) {
return SysResult::notAnError(
recvfrom(file.get(), buf, len, flags, from, fromlenaddr, thread));
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_recvmsg(Thread *thread, sint s,
ptr<struct msghdr> msg, sint flags) {
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto recvmsg = file->ops->recvmsg) {
return recvmsg(file.get(), msg, flags, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_shutdown(Thread *thread, sint s, sint how) {
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto shutdown = file->ops->shutdown) {
return shutdown(file.get(), how, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_setsockopt(Thread *thread, sint s, sint level,
sint name, caddr_t val, sint valsize) {
ORBIS_LOG_TODO(__FUNCTION__, s, level, name, val, valsize);
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto setsockopt = file->ops->setsockopt) {
return setsockopt(file.get(), level, name, val, valsize, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_getsockopt(Thread *thread, sint s, sint level,
sint name, caddr_t val,
ptr<sint> avalsize) {
ORBIS_LOG_TODO(__FUNCTION__, s, level, name, val, avalsize);
auto file = thread->tproc->fileDescriptors.get(s);
if (file == nullptr) {
return ErrorCode::BADF;
}
if (auto getsockopt = file->ops->getsockopt) {
return getsockopt(file.get(), level, name, val, avalsize, thread);
}
return ErrorCode::NOTSUP;
}
orbis::SysResult orbis::sys_getsockname(Thread *thread, sint fdes,
ptr<SocketAddress> asa,
ptr<uint32_t> alen) {
// return uwrite<uint32_t>(alen, sizeof(SockAddr));
ORBIS_LOG_TODO(__FUNCTION__);
return {};
}
orbis::SysResult orbis::sys_getpeername(Thread *thread, sint fdes,
ptr<SocketAddress> asa,
ptr<uint32_t> alen) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sendfile(Thread *thread, sint fd, sint s,
off_t offset, size_t nbytes,
ptr<struct sf_hdtr> hdtr,
ptr<off_t> sbytes, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sctp_peeloff(Thread *thread, sint sd,
uint32_t name) {
return ErrorCode::NOSYS;
}
orbis::SysResult
orbis::sys_sctp_generic_sendmsg(Thread *thread, sint sd, caddr_t msg, sint mlen,
caddr_t to, __socklen_t tolen,
ptr<struct sctp_sndrcvinfo> sinfo, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sctp_generic_sendmsg_iov(
Thread *thread, sint sd, ptr<IoVec> iov, sint iovlen, caddr_t to,
__socklen_t tolen, ptr<struct sctp_sndrcvinfo> sinfo, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult
orbis::sys_sctp_generic_recvmsg(Thread *thread, sint sd, ptr<IoVec> iov,
sint iovlen, caddr_t from, __socklen_t fromlen,
ptr<struct sctp_sndrcvinfo> sinfo, sint flags) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,31 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_kmq_open(Thread *thread, ptr<const char> path,
sint flags, mode_t mode,
ptr<const struct mq_attr> attr) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kmq_unlink(Thread *thread, ptr<const char> path) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kmq_setattr(Thread *thread, sint mqd,
ptr<const struct mq_attr> attr,
ptr<struct mq_attr> oattr) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kmq_timedreceive(Thread *thread, sint mqd,
ptr<const char> msg_ptr,
size_t msg_len, ptr<uint> msg_prio,
ptr<const timespec> abstimeout) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kmq_timedsend(Thread *thread, sint mqd,
ptr<char> msg_ptr, size_t msg_len,
ptr<uint> msg_prio,
ptr<const timespec> abstimeout) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kmq_notify(Thread *thread, sint mqd,
ptr<const struct sigevent> sigev) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,37 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_ksem_init(Thread *thread, ptr<semid_t> idp,
uint value) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_open(Thread *thread, ptr<semid_t> idp,
ptr<const char> name, sint oflag,
mode_t mode, uint value) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_unlink(Thread *thread, ptr<const char> name) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_close(Thread *thread, semid_t id) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_post(Thread *thread, semid_t id) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_wait(Thread *thread, semid_t id) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_timedwait(Thread *thread, semid_t id,
ptr<const timespec> abstime) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_trywait(Thread *thread, semid_t id) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_getvalue(Thread *thread, semid_t id,
ptr<sint> value) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ksem_destroy(Thread *thread, semid_t id) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,45 @@
#include "file.hpp"
#include "orbis-config.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
orbis::SysResult orbis::sys_shm_open(Thread *thread, ptr<const char> path,
sint flags, mode_t mode) {
char _name[256];
if (auto result = ureadString(_name, sizeof(_name), path);
result != ErrorCode{}) {
return result;
}
if (auto shm_open = thread->tproc->ops->shm_open) {
Ref<File> file;
auto result = shm_open(thread, path, flags, mode, &file);
if (result.isError()) {
return result;
}
thread->retval[0] = thread->tproc->fileDescriptors.insert(file);
return {};
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_shm_unlink(Thread *thread, ptr<const char> path) {
char _name[256];
if (auto result = ureadString(_name, sizeof(_name), path);
result != ErrorCode{}) {
return result;
}
if (auto shm_unlink = thread->tproc->ops->shm_unlink) {
auto result = shm_unlink(thread, path);
if (result.isError()) {
return result;
}
return {};
}
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,177 @@
#include "orbis/utils/Logs.hpp"
#include "sys/sysproto.hpp"
#include "thread/Thread.hpp"
#include "time.hpp"
#include "umtx.hpp"
#include <chrono>
static orbis::ErrorCode ureadTimespec(orbis::timespec &ts,
orbis::ptr<orbis::timespec> addr) {
orbis::ErrorCode error = uread(ts, addr);
if (error != orbis::ErrorCode{})
return error;
if (ts.sec < 0 || ts.nsec < 0 || ts.nsec > 1000000000) {
return orbis::ErrorCode::INVAL;
}
return {};
}
orbis::SysResult orbis::sys__umtx_lock(Thread *thread, ptr<umtx> umtx) {
ORBIS_LOG_TRACE(__FUNCTION__, umtx);
if (reinterpret_cast<std::uintptr_t>(umtx) - 0x10000 > 0xff'fffe'ffff)
return ErrorCode::FAULT;
return umtx_lock_umtx(thread, umtx, thread->tid, -1);
}
orbis::SysResult orbis::sys__umtx_unlock(Thread *thread, ptr<umtx> umtx) {
ORBIS_LOG_TRACE(__FUNCTION__, umtx);
if (reinterpret_cast<std::uintptr_t>(umtx) - 0x10000 > 0xff'fffe'ffff)
return ErrorCode::FAULT;
return umtx_unlock_umtx(thread, umtx, thread->tid);
}
orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr<void> obj, sint op,
ulong val, ptr<void> uaddr1,
ptr<void> uaddr2) {
ORBIS_LOG_TRACE(__FUNCTION__, obj, op, val, uaddr1, uaddr2);
if (reinterpret_cast<std::uintptr_t>(obj) - 0x10000 > 0xff'fffe'ffff)
return ErrorCode::FAULT;
auto with_timeout = [&](auto op, bool loop = true) -> SysResult {
timespec *ts = nullptr;
timespec timeout{};
if (uaddr2 != nullptr) {
auto result = ureadTimespec(timeout, (ptr<timespec>)uaddr2);
if (result != ErrorCode{}) {
return result;
}
ts = &timeout;
}
if (!ts) {
if (!loop)
return op(-1);
while (true) {
if (auto r = op(-1); r != ErrorCode::TIMEDOUT)
return r;
}
} else {
__uint128_t usec = timeout.sec;
usec *= 1000'000;
usec += (timeout.nsec + 999) / 1000;
if (usec >= UINT64_MAX)
usec = -2;
if (!loop) {
if (auto result = op(usec); result != ErrorCode::TIMEDOUT) {
return result;
}
return SysResult::notAnError(ErrorCode::TIMEDOUT);
}
auto start = std::chrono::steady_clock::now();
std::uint64_t udiff = 0;
while (true) {
if (auto r = op(usec - udiff); r != ErrorCode::TIMEDOUT)
return r;
udiff = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - start)
.count();
if (udiff >= usec)
return SysResult::notAnError(ErrorCode::TIMEDOUT);
}
}
};
switch (op) {
case kUmtxOpLock: {
return with_timeout([&](std::uint64_t ut) {
return umtx_lock_umtx(thread, (ptr<umtx>)obj, val, ut);
});
}
case kUmtxOpUnlock:
return umtx_unlock_umtx(thread, (ptr<umtx>)obj, val);
case kUmtxOpWait: {
return with_timeout(
[&](std::uint64_t ut) {
return umtx_wait(thread, obj, val, ut, false, true);
},
false);
}
case kUmtxOpWake:
return umtx_wake(thread, obj, val);
case kUmtxOpMutexTrylock:
return umtx_trylock_umutex(thread, (ptr<umutex>)obj);
case kUmtxOpMutexLock: {
return with_timeout([&](std::uint64_t ut) {
return umtx_lock_umutex(thread, (ptr<umutex>)obj, ut);
});
}
case kUmtxOpMutexUnock:
return umtx_unlock_umutex(thread, (ptr<umutex>)obj);
case kUmtxOpSetCeiling:
return umtx_set_ceiling(thread, (ptr<umutex>)obj, val,
(ptr<uint32_t>)uaddr1);
case kUmtxOpCvWait: {
return with_timeout(
[&](std::uint64_t ut) {
return umtx_cv_wait(thread, (ptr<ucond>)obj, (ptr<umutex>)uaddr1, ut,
val);
},
false);
}
case kUmtxOpCvSignal:
return umtx_cv_signal(thread, (ptr<ucond>)obj);
case kUmtxOpCvBroadcast:
return umtx_cv_broadcast(thread, (ptr<ucond>)obj);
case kUmtxOpWaitUint: {
return with_timeout(
[&](std::uint64_t ut) {
return umtx_wait(thread, obj, val, ut, true, true);
},
false);
}
case kUmtxOpRwRdLock:
return with_timeout([&](std::uint64_t ut) {
return umtx_rw_rdlock(thread, (ptr<urwlock>)obj, val, ut);
});
case kUmtxOpRwWrLock:
return with_timeout([&](std::uint64_t ut) {
return umtx_rw_wrlock(thread, (ptr<urwlock>)obj, ut);
});
case kUmtxOpRwUnlock:
return umtx_rw_unlock(thread, (ptr<urwlock>)obj);
case kUmtxOpWaitUintPrivate: {
return with_timeout(
[&](std::uint64_t ut) {
return umtx_wait(thread, obj, val, ut, true, false);
},
false);
}
case kUmtxOpWakePrivate:
return umtx_wake_private(thread, obj, val);
case kUmtxOpMutexWait: {
return with_timeout([&](std::uint64_t ut) {
return umtx_wait_umutex(thread, (ptr<umutex>)obj, ut);
});
}
case kUmtxOpMutexWake:
return umtx_wake_umutex(thread, (ptr<umutex>)obj, 0);
case kUmtxOpSemWait:
return with_timeout(
[&](std::uint64_t ut) {
return umtx_sem_wait(thread, (ptr<usem>)obj, ut);
},
false);
case kUmtxOpSemWake:
return umtx_sem_wake(thread, (ptr<usem>)obj);
case kUmtxOpNwakePrivate:
return umtx_nwake_private(thread, (ptr<void *>)obj, val);
case kUmtxOpMutexWake2:
return umtx_wake2_umutex(thread, (orbis::ptr<orbis::umutex>)obj, val);
case kUmtxOpMutexWake3:
return umtx_wake3_umutex(thread, (orbis::ptr<orbis::umutex>)obj, val);
}
return ErrorCode::INVAL;
}

View file

@ -0,0 +1,6 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_uuidgen(Thread *thread, ptr<struct uuid> store,
sint count) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,498 @@
#include "stat.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
#include "utils/Logs.hpp"
#include <filesystem>
#include <span>
orbis::SysResult orbis::sys_sync(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_quotactl(Thread *thread, ptr<char> path, sint cmd,
sint uid, caddr_t arg) {
return ErrorCode::NOSYS;
}
namespace orbis {
struct statfs {
char pad[0x118];
char f_fstypename[16]; /* filesystem type name */
char f_mntfromname[88]; /* mounted filesystem */
char f_mntonname[88]; /* directory on which mounted */
};
} // namespace orbis
orbis::SysResult orbis::sys_statfs(Thread *thread, ptr<char> path,
ptr<struct statfs> buf) {
if (buf == 0) {
thread->retval[0] = 1;
return {};
}
std::strncpy(buf->f_fstypename, "unionfs", sizeof(buf->f_fstypename));
std::strncpy(buf->f_mntfromname, "/dev/super-hdd",
sizeof(buf->f_mntfromname));
std::strncpy(buf->f_mntonname, "/system/", sizeof(buf->f_mntonname));
thread->retval[0] = 1;
return {};
}
orbis::SysResult orbis::sys_fstatfs(Thread *thread, sint fd,
ptr<struct statfs> buf) {
if (buf == 0) {
thread->retval[0] = 1;
return {};
}
std::strncpy(buf->f_fstypename, "unionfs", sizeof(buf->f_fstypename));
std::strncpy(buf->f_mntfromname, "/dev/super-hdd",
sizeof(buf->f_mntfromname));
std::strncpy(buf->f_mntonname, "/system/", sizeof(buf->f_mntonname));
thread->retval[0] = 1;
return {};
}
orbis::SysResult orbis::sys_getfsstat(Thread *thread, ptr<struct statfs> buf,
slong bufsize, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fchdir(Thread *thread, sint fd) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_chdir(Thread *thread, ptr<char> path) {
ORBIS_LOG_WARNING(__FUNCTION__, path);
thread->tproc->cwd = std::filesystem::path(path).lexically_normal().string();
return {};
}
orbis::SysResult orbis::sys_chroot(Thread *thread, ptr<char> path) {
ORBIS_LOG_WARNING(__FUNCTION__, path);
thread->tproc->root = path;
return {};
}
// volatile bool debuggerPresent = false;
orbis::SysResult orbis::sys_open(Thread *thread, ptr<const char> path,
sint flags, sint mode) {
if (auto open = thread->tproc->ops->open) {
Ref<File> file;
auto result = open(thread, path, flags, mode, &file);
if (result.isError()) {
return result;
}
auto fd = thread->tproc->fileDescriptors.insert(file);
thread->retval[0] = fd;
// if (path ==
// std::string_view{"/app0/psm/Application/resource/Sce.Vsh.ShellUI.SystemMessage.rco"})
// {
ORBIS_LOG_SUCCESS(__FUNCTION__, thread->tid, path, flags, mode, fd);
if (path == std::string_view{"/app0/wave/wave1.fbxd"}) {
thread->where();
}
// while (debuggerPresent == false) {
// std::this_thread::sleep_for(std::chrono::seconds(1));
// }
// // thread->where();
// }
return {};
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_openat(Thread *thread, sint fd, ptr<char> path,
sint flag, mode_t mode) {
ORBIS_LOG_WARNING(__FUNCTION__, fd, path, flag, mode);
if (fd == -100) {
std::string cwd;
{
std::lock_guard lock(thread->tproc->mtx);
cwd = std::string(thread->tproc->cwd);
}
return sys_open(thread, (cwd + "/" + path).c_str(), flag, mode);
}
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mknod(Thread *thread, ptr<char> path, sint mode,
sint dev) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mknodat(Thread *thread, sint fd, ptr<char> path,
mode_t mode, dev_t dev) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mkfifo(Thread *thread, ptr<char> path, sint mode) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mkfifoat(Thread *thread, sint fd, ptr<char> path,
mode_t mode) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_link(Thread *thread, ptr<char> path,
ptr<char> link) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_linkat(Thread *thread, sint fd1, ptr<char> path1,
sint fd2, ptr<char> path2, sint flag) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_symlink(Thread *thread, ptr<char> path,
ptr<char> link) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_symlinkat(Thread *thread, ptr<char> path1, sint fd,
ptr<char> path2) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_undelete(Thread *thread, ptr<char> path) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_unlink(Thread *thread, ptr<char> path) {
if (auto unlink = thread->tproc->ops->unlink) {
return unlink(thread, path);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_unlinkat(Thread *thread, sint fd, ptr<char> path,
sint flag) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lseek(Thread *thread, sint fd, off_t offset,
sint whence) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
std::lock_guard lock(file->mtx);
// TODO: use ioctl?
switch (whence) {
case SEEK_SET:
file->nextOff = offset;
break;
case SEEK_CUR:
file->nextOff += offset;
break;
case SEEK_END: {
if (file->ops->stat == nullptr) {
ORBIS_LOG_ERROR("seek with end whence: unimplemented stat");
return ErrorCode::NOTSUP;
}
orbis::Stat stat;
auto result = file->ops->stat(file.get(), &stat, thread);
if (result != ErrorCode{}) {
return result;
}
file->nextOff = stat.size + offset;
break;
}
default:
ORBIS_LOG_ERROR("sys_lseek: unimplemented whence", whence);
return ErrorCode::NOSYS;
}
ORBIS_LOG_ERROR(__FUNCTION__, fd, offset, whence, file->nextOff);
thread->retval[0] = file->nextOff;
return {};
}
orbis::SysResult orbis::sys_freebsd6_lseek(Thread *thread, sint fd, sint,
off_t offset, sint whence) {
return sys_lseek(thread, fd, offset, whence);
}
orbis::SysResult orbis::sys_access(Thread *thread, ptr<char> path, sint flags) {
if (auto open = thread->tproc->ops->open) {
Ref<File> file;
return open(thread, path, flags, 0, &file);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_faccessat(Thread *thread, sint fd, ptr<char> path,
sint mode, sint flag) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_eaccess(Thread *thread, ptr<char> path,
sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_stat(Thread *thread, ptr<char> path, ptr<Stat> ub) {
ORBIS_LOG_WARNING(__FUNCTION__, path);
Ref<File> file;
auto result = thread->tproc->ops->open(thread, path, 0, 0, &file);
if (result.isError()) {
return result;
}
auto stat = file->ops->stat;
if (stat == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
Stat _ub;
result = uread(_ub, ub);
if (result.isError()) {
return result;
}
result = stat(file.get(), &_ub, thread);
if (result.isError()) {
return result;
}
return uwrite(ub, _ub);
}
orbis::SysResult orbis::sys_fstatat(Thread *thread, sint fd, ptr<char> path,
ptr<Stat> buf, sint flag) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lstat(Thread *thread, ptr<char> path,
ptr<Stat> ub) {
return sys_stat(thread, path, ub);
}
orbis::SysResult orbis::sys_nstat(Thread *thread, ptr<char> path,
ptr<struct nstat> ub) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_nlstat(Thread *thread, ptr<char> path,
ptr<struct nstat> ub) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_pathconf(Thread *thread, ptr<char> path,
sint name) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lpathconf(Thread *thread, ptr<char> path,
sint name) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_readlink(Thread *thread, ptr<char> path,
ptr<char> buf, size_t count) {
char _path[1024];
ORBIS_RET_ON_ERROR(ureadString(_path, sizeof(_path), path));
auto pathLen = std::strlen(_path);
if (pathLen > count) {
return ErrorCode::NAMETOOLONG;
}
Ref<File> file;
if (auto error = thread->tproc->ops->open(thread, path, 0, 0, &file);
error.value()) {
return error;
}
ORBIS_RET_ON_ERROR(uwriteRaw(buf, _path, pathLen));
thread->retval[0] = pathLen;
return {};
}
orbis::SysResult orbis::sys_readlinkat(Thread *thread, sint fd, ptr<char> path,
ptr<char> buf, size_t bufsize) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_chflags(Thread *thread, ptr<char> path,
sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lchflags(Thread *thread, ptr<const char> path,
sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fchflags(Thread *thread, sint fd, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_chmod(Thread *thread, ptr<char> path, sint mode) {
return {};
}
orbis::SysResult orbis::sys_fchmodat(Thread *thread, sint fd, ptr<char> path,
mode_t mode, sint flag) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lchmod(Thread *thread, ptr<char> path,
mode_t mode) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fchmod(Thread *thread, sint fd, sint mode) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_chown(Thread *thread, ptr<char> path, sint uid,
sint gid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fchownat(Thread *thread, sint fd, ptr<char> path,
uid_t uid, gid_t gid, sint flag) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lchown(Thread *thread, ptr<char> path, sint uid,
sint gid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fchown(Thread *thread, sint fd, sint uid,
sint gid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_utimes(Thread *thread, ptr<char> path,
ptr<struct timeval> tptr) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_futimesat(Thread *thread, sint fd, ptr<char> path,
ptr<struct timeval> times) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lutimes(Thread *thread, ptr<char> path,
ptr<struct timeval> tptr) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_futimes(Thread *thread, sint fd,
ptr<struct timeval> tptr) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_truncate(Thread *thread, ptr<char> path,
off_t length) {
Ref<File> file;
auto result = thread->tproc->ops->open(thread, path, 2, 0, &file);
if (result.isError()) {
return result;
}
auto truncate = file->ops->truncate;
if (truncate == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
return truncate(file.get(), length, thread);
}
orbis::SysResult orbis::sys_freebsd6_truncate(Thread *thread, ptr<char> path,
sint, off_t length) {
return sys_truncate(thread, path, length);
}
orbis::SysResult orbis::sys_fsync(Thread *thread, sint fd) { return {}; }
orbis::SysResult orbis::sys_rename(Thread *thread, ptr<char> from,
ptr<char> to) {
if (auto rename = thread->tproc->ops->rename) {
return rename(thread, from, to);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_renameat(Thread *thread, sint oldfd, ptr<char> old,
sint newfd, ptr<char> new_) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mkdir(Thread *thread, ptr<char> path, sint mode) {
if (auto mkdir = thread->tproc->ops->mkdir) {
return mkdir(thread, path, mode);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mkdirat(Thread *thread, sint fd, ptr<char> path,
mode_t mode) {
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto mkdir = file->ops->mkdir;
if (mkdir == nullptr) {
return ErrorCode::NOTSUP;
}
std::lock_guard lock(file->mtx);
return mkdir(file.get(), path, mode);
}
orbis::SysResult orbis::sys_rmdir(Thread *thread, ptr<char> path) {
if (auto rmdir = thread->tproc->ops->rmdir) {
return rmdir(thread, path);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getdirentries(Thread *thread, sint fd,
ptr<char> buf, uint count,
ptr<slong> basep) {
ORBIS_LOG_WARNING(__FUNCTION__, fd, (void *)buf, count, basep);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
std::lock_guard lock(file->mtx);
const orbis::Dirent *entries = file->dirEntries.data();
auto pos = file->nextOff / sizeof(orbis::Dirent); // TODO
auto rmax = count / sizeof(orbis::Dirent);
auto next = std::min<uint64_t>(file->dirEntries.size(), pos + rmax);
file->nextOff = next * sizeof(orbis::Dirent);
SysResult result{};
result = uwrite(ptr<orbis::Dirent>(buf), entries + pos, next - pos);
if (result.isError())
return result;
for (auto &entry : std::span(entries + pos, next - pos)) {
ORBIS_LOG_ERROR(__FUNCTION__, entry.name);
}
if (basep) {
result = uwrite(basep, slong(file->nextOff));
if (result.isError())
return result;
}
thread->retval[0] = (next - pos) * sizeof(orbis::Dirent);
return {};
}
orbis::SysResult orbis::sys_getdents(Thread *thread, sint fd, ptr<char> buf,
size_t count) {
ORBIS_LOG_WARNING(__FUNCTION__, fd, (void *)buf, count);
return orbis::sys_getdirentries(thread, fd, buf, count, nullptr);
}
orbis::SysResult orbis::sys_umask(Thread *thread, sint newmask) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_revoke(Thread *thread, ptr<char> path) {
ORBIS_LOG_WARNING(__FUNCTION__);
return {};
}
orbis::SysResult orbis::sys_lgetfh(Thread *thread, ptr<char> fname,
ptr<struct fhandle> fhp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getfh(Thread *thread, ptr<char> fname,
ptr<struct fhandle> fhp) {
return ErrorCode::NOSYS;
}
orbis::SysResult
orbis::sys_fhopen(Thread *thread, ptr<const struct fhandle> u_fhp, sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fhstat(Thread *thread,
ptr<const struct fhandle> u_fhp,
ptr<Stat> sb) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fhstatfs(Thread *thread,
ptr<const struct fhandle> u_fhp,
ptr<struct statfs> buf) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_posix_fallocate(Thread *thread, sint fd,
off_t offset, off_t len) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_posix_fadvise(Thread *thread, sint fd, off_t offset,
off_t len, sint advice) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,61 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys___acl_get_file(Thread *thread, ptr<char> path,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_get_link(Thread *thread, ptr<const char> path,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_set_file(Thread *thread, ptr<char> path,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_set_link(Thread *thread, ptr<const char> path,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_get_fd(Thread *thread, sint filedes,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_set_fd(Thread *thread, sint filedes,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_delete_link(Thread *thread,
ptr<const char> path,
acl_type_t type) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_delete_file(Thread *thread, ptr<char> path,
acl_type_t type) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_delete_fd(Thread *thread, sint filedes,
acl_type_t type) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_aclcheck_file(Thread *thread, ptr<char> path,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_aclcheck_link(Thread *thread,
ptr<const char> path,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys___acl_aclcheck_fd(Thread *thread, sint filedes,
acl_type_t type,
ptr<struct acl> aclp) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,53 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_aio_return(Thread *thread,
ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_aio_suspend(Thread *thread,
ptr<struct aiocb> aiocbp, sint nent,
ptr<const timespec> timeout) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_aio_cancel(Thread *thread, sint fd,
ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_aio_error(Thread *thread,
ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_oaio_read(Thread *thread,
ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_aio_read(Thread *thread, ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_oaio_write(Thread *thread,
ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_aio_write(Thread *thread,
ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_olio_listio(Thread *thread, sint mode,
ptr<cptr<struct aiocb>> acb_list,
sint nent, ptr<struct osigevent> sig) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_lio_listio(Thread *thread, sint mode,
ptr<cptr<struct aiocb>> aiocbp,
sint nent, ptr<struct sigevent> sig) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_aio_waitcomplete(Thread *thread,
ptr<ptr<struct aiocb>> aiocbp,
ptr<timespec> timeout) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_aio_fsync(Thread *thread, sint op,
ptr<struct aiocb> aiocbp) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,23 @@
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/Thread.hpp"
#include <mutex>
#include <string>
orbis::SysResult orbis::sys___getcwd(Thread *thread, ptr<char> buf,
uint buflen) {
std::string cwd;
{
std::lock_guard lock(thread->tproc->mtx);
cwd = std::string(thread->tproc->cwd);
}
if (buflen < cwd.size() + 1) {
return ErrorCode::NOMEM;
}
ORBIS_RET_ON_ERROR(uwriteRaw(buf, cwd.data(), cwd.size() + 1));
return {};
}

View file

@ -0,0 +1,79 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_extattrctl(Thread *thread, ptr<char> path, char cmd,
ptr<const char> filename,
sint attrnamespace,
ptr<const char> attrname) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_set_fd(Thread *thread, sint fd,
sint attrnamespace,
ptr<const char> attrname,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_set_file(Thread *thread, ptr<char> path,
sint attrnamespace,
ptr<const char> filename,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_set_link(Thread *thread,
ptr<const char> path,
sint attrnamespace,
ptr<const char> attrname,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_get_fd(Thread *thread, sint fd,
sint attrnamespace,
ptr<const char> attrname,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_get_file(Thread *thread, ptr<char> path,
sint attrnamespace,
ptr<const char> filename,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_get_link(Thread *thread,
ptr<const char> path,
sint attrnamespace,
ptr<const char> attrname,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_delete_fd(Thread *thread, sint fd,
sint attrnamespace,
ptr<const char> attrname) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_delete_file(Thread *thread, ptr<char> path,
sint attrnamespace,
ptr<const char> attrname) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_delete_link(Thread *thread,
ptr<const char> path,
sint attrnamespace,
ptr<const char> attrname) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_list_fd(Thread *thread, sint fd,
sint attrnamespace, ptr<void> data,
size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_list_file(Thread *thread,
ptr<const char> path,
sint attrnamespace,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_extattr_list_link(Thread *thread,
ptr<const char> path,
sint attrnamespace,
ptr<void> data, size_t nbytes) {
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,27 @@
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
orbis::SysResult orbis::sys_mount(Thread *thread, ptr<char> type,
ptr<char> path, sint flags, caddr_t data) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_unmount(Thread *thread, ptr<char> path,
sint flags) {
if (auto unmount = thread->tproc->ops->unmount) {
return unmount(thread, path, flags);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_nmount(Thread *thread, ptr<IoVec> iovp, uint iovcnt,
sint flags) {
if (auto nmount = thread->tproc->ops->nmount) {
return nmount(thread, iovp, iovcnt, flags);
}
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,104 @@
#include "error.hpp"
#include "sys/sysproto.hpp"
#include "thread/Process.hpp"
#include "thread/ProcessOps.hpp"
#include "thread/Thread.hpp"
orbis::SysResult orbis::sys_sbrk(Thread *, sint) {
return ErrorCode::OPNOTSUPP;
}
orbis::SysResult orbis::sys_sstk(Thread *, sint) {
return ErrorCode::OPNOTSUPP;
}
orbis::SysResult orbis::sys_mmap(Thread *thread, caddr_t addr, size_t len,
sint prot, sint flags, sint fd, off_t pos) {
if (auto impl = thread->tproc->ops->mmap) {
return impl(thread, addr, len, prot, flags, fd, pos);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_freebsd6_mmap(Thread *thread, caddr_t addr,
size_t len, sint prot, sint flags,
sint fd, sint, off_t pos) {
return sys_mmap(thread, addr, len, prot, flags, fd, pos);
}
orbis::SysResult orbis::sys_msync(Thread *thread, ptr<void> addr, size_t len,
sint flags) {
if (auto impl = thread->tproc->ops->msync) {
return impl(thread, addr, len, flags);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_munmap(Thread *thread, ptr<void> addr, size_t len) {
if (auto impl = thread->tproc->ops->munmap) {
return impl(thread, addr, len);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mprotect(Thread *thread, ptr<const void> addr,
size_t len, sint prot) {
if (auto impl = thread->tproc->ops->mprotect) {
return impl(thread, addr, len, prot);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_minherit(Thread *thread, ptr<void> addr, size_t len,
sint inherit) {
if (auto impl = thread->tproc->ops->minherit) {
return impl(thread, addr, len, inherit);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_madvise(Thread *thread, ptr<void> addr, size_t len,
sint behav) {
if (auto impl = thread->tproc->ops->madvise) {
return impl(thread, addr, len, behav);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mincore(Thread *thread, ptr<const void> addr,
size_t len, ptr<char> vec) {
if (auto impl = thread->tproc->ops->mincore) {
return impl(thread, addr, len, vec);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mlock(Thread *thread, ptr<const void> addr,
size_t len) {
if (auto impl = thread->tproc->ops->mlock) {
return impl(thread, addr, len);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_mlockall(Thread *thread, sint how) {
if (auto impl = thread->tproc->ops->mlockall) {
return impl(thread, how);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_munlockall(Thread *thread) {
if (auto impl = thread->tproc->ops->munlockall) {
return impl(thread);
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_munlock(Thread *thread, ptr<const void> addr,
size_t len) {
if (auto impl = thread->tproc->ops->munlock) {
return impl(thread, addr, len);
}
return ErrorCode::NOSYS;
}

View file

@ -0,0 +1,8 @@
#include "sys/sysproto.hpp"
orbis::SysResult orbis::sys_obreak(Thread *thread, ptr<char> nsize) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_ovadvise(Thread *thread, sint anom) {
return ErrorCode::NOSYS;
}