mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 22:19:02 +00:00
implement unix socket ops
implement cross process dmem support implement ipmi try send message implement sys_batch_map store saves to game directory (.rpcsx subfolder) fix get dir entries added uvd & vce devices
This commit is contained in:
parent
a6211b514f
commit
6e25f347d3
39 changed files with 1526 additions and 294 deletions
9
orbis-kernel/include/orbis/SocketAddress.hpp
Normal file
9
orbis-kernel/include/orbis/SocketAddress.hpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
namespace orbis {
|
||||
struct SocketAddress {
|
||||
unsigned char len;
|
||||
unsigned char family;
|
||||
char data[14];
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
@ -14,6 +14,9 @@ struct KNote;
|
|||
struct Thread;
|
||||
struct Stat;
|
||||
struct Uio;
|
||||
struct SocketAddress;
|
||||
struct msghdr;
|
||||
struct sf_hdtr;
|
||||
|
||||
struct FileOps {
|
||||
std::int32_t flags;
|
||||
|
|
@ -41,6 +44,33 @@ struct FileOps {
|
|||
Thread *thread) = nullptr;
|
||||
ErrorCode (*munmap)(File *file, void **address, std::uint64_t size,
|
||||
Thread *thread) = nullptr;
|
||||
|
||||
ErrorCode (*bind)(orbis::File *file, SocketAddress *address,
|
||||
std::size_t addressLen, Thread *thread) = nullptr;
|
||||
ErrorCode (*listen)(orbis::File *file, int backlog, Thread *thread) = nullptr;
|
||||
ErrorCode (*accept)(orbis::File *file, SocketAddress *address,
|
||||
std::uint32_t *addressLen, Thread *thread) = nullptr;
|
||||
ErrorCode (*connect)(orbis::File *file, SocketAddress *address,
|
||||
std::uint32_t addressLen, Thread *thread) = nullptr;
|
||||
ErrorCode (*sendto)(orbis::File *file, const void *buf, size_t len,
|
||||
sint flags, caddr_t to, sint tolen,
|
||||
Thread *thread) = nullptr;
|
||||
ErrorCode (*sendmsg)(orbis::File *file, msghdr *msg, sint flags,
|
||||
Thread *thread) = nullptr;
|
||||
ErrorCode (*recvfrom)(orbis::File *file, void *buf, size_t len,
|
||||
sint flags, SocketAddress *from, uint32_t *fromlenaddr,
|
||||
Thread *thread) = nullptr;
|
||||
ErrorCode (*recvmsg)(orbis::File *file, msghdr *msg, sint flags,
|
||||
Thread *thread) = nullptr;
|
||||
ErrorCode (*shutdown)(orbis::File *file, sint how, Thread *thread) = nullptr;
|
||||
ErrorCode (*setsockopt)(orbis::File *file, sint level, sint name,
|
||||
const void *val, sint valsize,
|
||||
Thread *thread) = nullptr;
|
||||
ErrorCode (*getsockopt)(orbis::File *file, sint level, sint name, void *val,
|
||||
sint *avalsize, Thread *thread) = nullptr;
|
||||
ErrorCode (*sendfile)(orbis::File *file, sint fd, off_t offset, size_t nbytes,
|
||||
ptr<struct sf_hdtr> hdtr, ptr<off_t> sbytes, sint flags,
|
||||
Thread *thread) = nullptr;
|
||||
};
|
||||
|
||||
struct File : RcBase {
|
||||
|
|
@ -49,6 +79,7 @@ struct File : RcBase {
|
|||
const FileOps *ops = nullptr;
|
||||
Ref<RcBase> device;
|
||||
std::uint64_t nextOff = 0;
|
||||
int hostFd = -1;
|
||||
utils::kvector<Dirent> dirEntries;
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@ struct IpmiSession : RcBase {
|
|||
EventFlag evf{0, 0};
|
||||
shared_cv connectCv;
|
||||
bool expectedOutput = false; // TODO: verify
|
||||
bool connected = false; // TODO: implement more states
|
||||
sint connectionStatus{0};
|
||||
};
|
||||
|
||||
|
|
@ -152,8 +151,16 @@ SysResult sysIpmiSendConnectResult(Thread *thread, ptr<uint> result, uint kid,
|
|||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionRespondSync(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientGetMessage(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientTryGetMessage(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionTrySendMessage(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiClientDisconnect(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionGetClientPid(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <set>
|
||||
|
||||
namespace orbis {
|
||||
|
||||
struct File;
|
||||
static constexpr auto kEvFiltRead = -1;
|
||||
static constexpr auto kEvFiltWrite = -2;
|
||||
static constexpr auto kEvFiltAio = -3;
|
||||
|
|
@ -75,6 +75,7 @@ struct KQueue;
|
|||
struct KNote {
|
||||
shared_mutex mutex;
|
||||
Ref<KQueue> queue;
|
||||
Ref<File> file;
|
||||
KEvent event{};
|
||||
bool enabled = true;
|
||||
bool triggered = false;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct timespec;
|
|||
struct Stat;
|
||||
struct stack_t;
|
||||
struct IoVec;
|
||||
struct BatchMapEntry;
|
||||
|
||||
SysResult nosys(Thread *thread);
|
||||
|
||||
|
|
@ -53,13 +54,13 @@ SysResult sys_recvmsg(Thread *thread, sint s, ptr<struct msghdr> msg,
|
|||
SysResult sys_sendmsg(Thread *thread, sint s, ptr<struct msghdr> msg,
|
||||
sint flags);
|
||||
SysResult sys_recvfrom(Thread *thread, sint s, caddr_t buf, size_t len,
|
||||
sint flags, ptr<struct sockaddr> from,
|
||||
sint flags, ptr<SocketAddress> from,
|
||||
ptr<uint32_t> fromlenaddr);
|
||||
SysResult sys_accept(Thread *thread, sint s, ptr<struct sockaddr> from,
|
||||
SysResult sys_accept(Thread *thread, sint s, ptr<SocketAddress> from,
|
||||
ptr<uint32_t> fromlenaddr);
|
||||
SysResult sys_getpeername(Thread *thread, sint fdes, ptr<struct sockaddr> asa,
|
||||
SysResult sys_getpeername(Thread *thread, sint fdes, ptr<SocketAddress> asa,
|
||||
ptr<uint32_t> alen);
|
||||
SysResult sys_getsockname(Thread *thread, sint fdes, ptr<struct sockaddr> asa,
|
||||
SysResult sys_getsockname(Thread *thread, sint fdes, ptr<SocketAddress> asa,
|
||||
ptr<uint32_t> alen);
|
||||
SysResult sys_access(Thread *thread, ptr<char> path, sint flags);
|
||||
SysResult sys_chflags(Thread *thread, ptr<char> path, sint flags);
|
||||
|
|
@ -634,7 +635,8 @@ SysResult sys_evf_cancel(Thread *thread, sint id, uint64_t value,
|
|||
ptr<sint> pNumWaitThreads);
|
||||
SysResult sys_query_memory_protection(Thread *thread, ptr<void> address,
|
||||
ptr<MemoryProtection> protection);
|
||||
SysResult sys_batch_map(Thread *thread /* TODO */);
|
||||
SysResult sys_batch_map(Thread *thread, sint unk, sint flags, ptr<BatchMapEntry> entries,
|
||||
sint entriesCount, ptr<sint> processedCount);
|
||||
SysResult sys_osem_create(Thread *thread, ptr<const char[32]> name, uint attrs,
|
||||
sint initCount, sint maxCount);
|
||||
SysResult sys_osem_delete(Thread *thread, sint id);
|
||||
|
|
@ -720,7 +722,8 @@ SysResult sys_get_proc_type_info(Thread *thread, ptr<sint> destProcessInfo);
|
|||
SysResult sys_get_resident_count(Thread *thread, pid_t pid);
|
||||
SysResult sys_prepare_to_suspend_process(Thread *thread, pid_t pid);
|
||||
SysResult sys_get_resident_fmem_count(Thread *thread, pid_t pid);
|
||||
SysResult sys_thr_get_name(Thread *thread, lwpid_t lwpid);
|
||||
SysResult sys_thr_get_name(Thread *thread, lwpid_t lwpid, char *buf,
|
||||
size_t buflen);
|
||||
SysResult sys_set_gpo(Thread *thread /* TODO */);
|
||||
SysResult sys_get_paging_stats_of_all_objects(Thread *thread /* TODO */);
|
||||
SysResult sys_test_debug_rwmem(Thread *thread /* TODO */);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ struct ProcessOps {
|
|||
SysResult (*blockpool_unmap)(Thread *thread, caddr_t addr, size_t len);
|
||||
SysResult (*socket)(Thread *thread, ptr<const char> name, sint domain,
|
||||
sint type, sint protocol, Ref<File> *file);
|
||||
SysResult (*socketpair)(Thread *thread, sint domain, sint type, sint protocol,
|
||||
Ref<File> *a, Ref<File> *b);
|
||||
SysResult (*shm_unlink)(Thread *thread, const char *path);
|
||||
SysResult (*dynlib_get_obj_member)(Thread *thread, ModuleHandle handle,
|
||||
uint64_t index, ptr<ptr<void>> addrp);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <span>
|
||||
|
||||
namespace orbis {
|
||||
struct IoVec {
|
||||
|
|
@ -25,5 +28,27 @@ struct Uio {
|
|||
UioSeg segflg;
|
||||
UioRw rw;
|
||||
void *td;
|
||||
|
||||
std::size_t write(const void *data, std::size_t size) {
|
||||
auto pos = reinterpret_cast<const std::byte *>(data);
|
||||
auto end = pos + size;
|
||||
|
||||
for (auto vec : std::span(iov, iovcnt)) {
|
||||
if (pos >= end) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto nextPos = std::min(pos + vec.len, end);
|
||||
std::memcpy(vec.base, pos, nextPos - pos);
|
||||
pos = nextPos;
|
||||
}
|
||||
|
||||
return size - (end - pos);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::size_t write(const T &object) {
|
||||
return write(&object, sizeof(T));
|
||||
}
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ struct RcBase {
|
|||
void incRef() {
|
||||
if (!_total_size)
|
||||
std::abort();
|
||||
if (references.fetch_add(1, std::memory_order::relaxed) > 512) {
|
||||
if (references.fetch_add(1, std::memory_order::relaxed) > 4096) {
|
||||
assert(!"too many references");
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ public:
|
|||
template <typename OT>
|
||||
requires(std::is_base_of_v<T, OT>)
|
||||
Ref &operator=(Ref<OT> &&other) {
|
||||
other.swap(*this);
|
||||
other.template cast<T>().swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -340,6 +340,23 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
|
|||
session->responseCv.notify_one(session->mutex);
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
orbis::SysResult orbis::sysIpmiClientGetMessage(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();
|
||||
|
||||
if (client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, client->name, client->messages.size(),
|
||||
paramsSz);
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::days(1));
|
||||
}
|
||||
return uwrite<uint>(result, 0x80020000 + static_cast<int>(ErrorCode::AGAIN));
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
|
|
@ -365,6 +382,8 @@ orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread,
|
|||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
// ORBIS_LOG_ERROR(__FUNCTION__, client->name, client->messages.size());
|
||||
|
||||
SceIpmiClientTryGetArgs _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, ptr<SceIpmiClientTryGetArgs>(params)));
|
||||
|
||||
|
|
@ -389,6 +408,81 @@ orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread,
|
|||
return uwrite<uint>(result, 0);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiSessionTrySendMessage(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct SceIpmiClientTrySendArgs {
|
||||
uint32_t unk; // 0
|
||||
uint32_t padding;
|
||||
ptr<std::byte> message;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SceIpmiClientTrySendArgs) == 0x18);
|
||||
|
||||
if (paramsSz != sizeof(SceIpmiClientTrySendArgs)) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
auto session = thread->tproc->ipmiMap.get(kid).cast<IpmiSession>();
|
||||
|
||||
if (session == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
SceIpmiClientTrySendArgs _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, ptr<SceIpmiClientTrySendArgs>(params)));
|
||||
|
||||
std::lock_guard lock(session->mutex);
|
||||
|
||||
if (session->client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
auto client = session->client;
|
||||
std::lock_guard lockClient(client->mutex);
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, session->server->name, client->name,
|
||||
client->messages.size(), _params.message, _params.size);
|
||||
auto &message = client->messages.emplace_back();
|
||||
message.resize(_params.size);
|
||||
ORBIS_RET_ON_ERROR(ureadRaw(message.data(), _params.message, _params.size));
|
||||
client->messageCv.notify_one(client->mutex);
|
||||
return uwrite<uint>(result, 0);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiClientDisconnect(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct SceIpmiClientDisconnectArgs {
|
||||
ptr<sint> status;
|
||||
};
|
||||
|
||||
if (paramsSz != sizeof(SceIpmiClientDisconnectArgs)) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();
|
||||
|
||||
if (client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
SceIpmiClientDisconnectArgs _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, ptr<SceIpmiClientDisconnectArgs>(params)));
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, client->name, _params.status);
|
||||
|
||||
std::lock_guard lock(client->mutex);
|
||||
|
||||
auto &message = client->messages.front();
|
||||
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.status, 0));
|
||||
return uwrite<uint>(result, 0);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiSessionGetClientPid(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
|
|
@ -474,7 +568,6 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
|
|||
// _params.numInData, _params.unk, _params.numOutData,
|
||||
// _params.pInData, _params.pOutData, _params.pResult,
|
||||
// _params.flags);
|
||||
|
||||
std::size_t inSize = 0;
|
||||
for (auto &data : std::span(_params.pInData, _params.numInData)) {
|
||||
inSize += data.size;
|
||||
|
|
@ -499,8 +592,6 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
|
|||
|
||||
ORBIS_LOG_TODO("IPMI: sync call", client->name, _params.method,
|
||||
thread->tproc->pid);
|
||||
thread->where();
|
||||
|
||||
auto bufLoc = std::bit_cast<char *>(msg + 1);
|
||||
|
||||
for (auto &data : std::span(_params.pInData, _params.numInData)) {
|
||||
|
|
@ -539,6 +630,10 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
|
|||
auto response = std::move(session->messageResponses.front());
|
||||
session->messageResponses.pop_front();
|
||||
|
||||
if (response.errorCode != 0) {
|
||||
thread->where();
|
||||
}
|
||||
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pResult, response.errorCode));
|
||||
if (_params.numOutData > 0 && _params.pOutData->size < response.data.size()) {
|
||||
return ErrorCode::INVAL;
|
||||
|
|
@ -753,11 +848,12 @@ orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread,
|
|||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, client->name, _params.index, _params.patternSet,
|
||||
_params.mode, _params.pPatternSet);
|
||||
// ORBIS_LOG_TODO(__FUNCTION__, client->name, _params.index,
|
||||
// _params.patternSet,
|
||||
// _params.mode, _params.pPatternSet);
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, 0u));
|
||||
// client->evf.set(_params.a);
|
||||
return ErrorCode::BUSY;
|
||||
return SysResult::notAnError(ErrorCode::BUSY);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiSessionWaitEventFlag(Thread *thread,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "pipe.hpp"
|
||||
#include "error/ErrorCode.hpp"
|
||||
#include "file.hpp"
|
||||
#include "thread/Thread.hpp"
|
||||
#include "uio.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
#include <span>
|
||||
|
||||
static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio,
|
||||
|
|
@ -9,16 +11,31 @@ static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio,
|
|||
auto pipe = static_cast<orbis::Pipe *>(file);
|
||||
while (true) {
|
||||
if (pipe->data.empty()) {
|
||||
pipe->cv.wait(file->mtx);
|
||||
continue;
|
||||
// pipe->cv.wait(file->mtx);
|
||||
// ORBIS_LOG_ERROR(__FUNCTION__, "wakeup", thread->name, thread->tid, file);
|
||||
// continue;
|
||||
return orbis::ErrorCode::WOULDBLOCK;
|
||||
}
|
||||
|
||||
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
|
||||
auto size = std::min<std::size_t>(pipe->data.size(), vec.len);
|
||||
|
||||
if (size == 0) {
|
||||
pipe->data.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (size > pipe->data.size()) {
|
||||
size = pipe->data.size();
|
||||
}
|
||||
|
||||
uio->offset += size;
|
||||
std::memcpy(vec.base, pipe->data.data(), size);
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file, size, pipe->data.size(), uio->offset, file->nextOff);
|
||||
|
||||
if (pipe->data.size() == size) {
|
||||
pipe->data.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -37,20 +54,30 @@ static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio,
|
|||
static orbis::ErrorCode pipe_write(orbis::File *file, orbis::Uio *uio,
|
||||
orbis::Thread *thread) {
|
||||
auto pipe = static_cast<orbis::Pipe *>(file);
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file);
|
||||
|
||||
std::size_t cnt = 0;
|
||||
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
|
||||
auto offset = pipe->data.size();
|
||||
pipe->data.resize(offset + vec.len);
|
||||
std::memcpy(pipe->data.data(), vec.base, vec.len);
|
||||
ORBIS_RET_ON_ERROR(orbis::ureadRaw(pipe->data.data(), vec.base, vec.len));
|
||||
cnt += vec.len;
|
||||
}
|
||||
|
||||
file->event.emit(orbis::kEvFiltRead);
|
||||
pipe->cv.notify_one(file->mtx);
|
||||
uio->resid = 0;
|
||||
return {};
|
||||
uio->resid -= cnt;
|
||||
uio->offset += cnt;
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file, uio->resid, uio->offset, file->nextOff, cnt);
|
||||
thread->where();
|
||||
return{};
|
||||
}
|
||||
|
||||
static orbis::FileOps pipe_ops = {.read = pipe_read, .write = pipe_write};
|
||||
static orbis::FileOps pipe_ops = {
|
||||
.read = pipe_read,
|
||||
.write = pipe_write,
|
||||
};
|
||||
|
||||
orbis::Ref<orbis::Pipe> orbis::createPipe() {
|
||||
auto result = knew<Pipe>();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <chrono>
|
||||
#include <list>
|
||||
#include <span>
|
||||
#include <sys/select.h>
|
||||
|
||||
orbis::SysResult orbis::sys_kqueue(Thread *thread) {
|
||||
auto queue = knew<KQueue>();
|
||||
|
|
@ -33,6 +34,28 @@ orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr<char> name,
|
|||
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();
|
||||
|
|
@ -82,11 +105,11 @@ static SysResult keventChange(KQueue *kq, KEvent &change, Thread *thread) {
|
|||
}
|
||||
|
||||
std::unique_lock lock(fd->event.mutex);
|
||||
|
||||
if (change.filter == kEvFiltWrite) {
|
||||
nodeIt->triggered = true;
|
||||
kq->cv.notify_all(kq->mtx);
|
||||
}
|
||||
nodeIt->file = fd;
|
||||
// if (change.filter == kEvFiltWrite) {
|
||||
// nodeIt->triggered = true;
|
||||
// kq->cv.notify_all(kq->mtx);
|
||||
// }
|
||||
|
||||
fd->event.notes.insert(&*nodeIt);
|
||||
}
|
||||
|
|
@ -176,14 +199,16 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
|
|||
for (auto &changePtr : std::span(changelist, nchanges)) {
|
||||
KEvent change;
|
||||
ORBIS_RET_ON_ERROR(uread(change, &changePtr));
|
||||
ORBIS_LOG_TODO(__FUNCTION__, change.ident, change.filter, change.flags,
|
||||
change.fflags, change.data, change.udata);
|
||||
ORBIS_LOG_TODO(__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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +242,17 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
|
|||
std::vector<KEvent> result;
|
||||
result.reserve(nevents);
|
||||
|
||||
if (kq->notes.empty()) {
|
||||
// ORBIS_LOG_ERROR(__FUNCTION__, "attempt to wait empty kqueue", fd,
|
||||
// nevents, timeoutPoint.time_since_epoch().count()); thread->where();
|
||||
// return{};
|
||||
// std::abort();
|
||||
return {};
|
||||
}
|
||||
|
||||
while (true) {
|
||||
bool waitHack = false;
|
||||
bool canSleep = true;
|
||||
std::lock_guard lock(kq->mtx);
|
||||
for (auto it = kq->notes.begin(); it != kq->notes.end();) {
|
||||
if (result.size() >= nevents) {
|
||||
|
|
@ -227,9 +262,32 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
|
|||
auto ¬e = *it;
|
||||
std::lock_guard lock(note.mutex);
|
||||
|
||||
if (!note.triggered) {
|
||||
if (note.event.filter == kEvFiltRead) {
|
||||
if (note.file->hostFd < 0 ||
|
||||
isReadEventTriggered(note.file->hostFd)) {
|
||||
note.triggered = true;
|
||||
} else {
|
||||
canSleep = false;
|
||||
}
|
||||
} else if (note.event.filter == kEvFiltWrite) {
|
||||
if (note.file->hostFd < 0 ||
|
||||
isWriteEventTriggered(note.file->hostFd)) {
|
||||
note.triggered = true;
|
||||
} else {
|
||||
canSleep = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (note.enabled && note.triggered) {
|
||||
result.push_back(note.event);
|
||||
|
||||
if (note.event.filter == kEvFiltGraphicsCore ||
|
||||
note.event.filter == kEvFiltDisplay) {
|
||||
waitHack = true;
|
||||
}
|
||||
|
||||
if (note.event.flags & kEvDispatch) {
|
||||
note.enabled = false;
|
||||
}
|
||||
|
|
@ -244,6 +302,9 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
|
|||
}
|
||||
|
||||
if (!result.empty()) {
|
||||
// if (waitHack) {
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -256,9 +317,13 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
|
|||
|
||||
auto waitTimeout = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
timeoutPoint - now);
|
||||
kq->cv.wait(kq->mtx, waitTimeout.count());
|
||||
if (canSleep) {
|
||||
kq->cv.wait(kq->mtx, waitTimeout.count());
|
||||
}
|
||||
} else {
|
||||
kq->cv.wait(kq->mtx);
|
||||
if (canSleep) {
|
||||
kq->cv.wait(kq->mtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
|
|||
return {};
|
||||
}
|
||||
|
||||
if (int_value->encoded_id == 0x29b56169422aa3dd) {
|
||||
int_value->value = 2;
|
||||
return {};
|
||||
}
|
||||
|
||||
// 0x503f69bde385a6ac // allow loading from dev machine?
|
||||
// 0x2d946f62aef8f878
|
||||
|
||||
|
|
@ -162,7 +167,6 @@ orbis::SysResult orbis::sys_dl_notify_event(Thread *thread /* TODO */) {
|
|||
}
|
||||
orbis::SysResult orbis::sys_evf_create(Thread *thread, ptr<const char[32]> name,
|
||||
sint attrs, uint64_t initPattern) {
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, name, attrs, initPattern);
|
||||
if (name == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
|
@ -215,7 +219,9 @@ orbis::SysResult orbis::sys_evf_create(Thread *thread, ptr<const char[32]> name,
|
|||
std::strncpy(eventFlag->name, _name, 32);
|
||||
}
|
||||
|
||||
thread->retval[0] = thread->tproc->evfMap.insert(eventFlag);
|
||||
auto fd = thread->tproc->evfMap.insert(eventFlag);
|
||||
thread->retval[0] = fd;
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, name, attrs, initPattern, fd);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_evf_delete(Thread *thread, sint id) {
|
||||
|
|
@ -229,7 +235,6 @@ orbis::SysResult orbis::sys_evf_delete(Thread *thread, sint id) {
|
|||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr<const char[32]> name) {
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, name);
|
||||
char _name[32];
|
||||
if (auto result = ureadString(_name, sizeof(_name), (const char *)name);
|
||||
result != ErrorCode{}) {
|
||||
|
|
@ -239,10 +244,13 @@ orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr<const char[32]> name) {
|
|||
auto eventFlag = thread->tproc->context->findEventFlag(_name);
|
||||
|
||||
if (eventFlag == nullptr) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, _name, "not exists");
|
||||
return ErrorCode::NOENT;
|
||||
}
|
||||
|
||||
thread->retval[0] = thread->tproc->evfMap.insert(eventFlag);
|
||||
auto fd = thread->tproc->evfMap.insert(eventFlag);
|
||||
thread->retval[0] = fd;
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, name, fd);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_evf_close(Thread *thread, sint id) {
|
||||
|
|
@ -370,8 +378,70 @@ orbis::sys_query_memory_protection(Thread *thread, ptr<void> address,
|
|||
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_batch_map(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
|
||||
namespace orbis {
|
||||
struct BatchMapEntry {
|
||||
ptr<char> start;
|
||||
off_t offset;
|
||||
size_t length;
|
||||
char protection;
|
||||
char type;
|
||||
short reserved;
|
||||
sint operation; // 0 - map direct
|
||||
// 1 - unmap
|
||||
// 2 - protect
|
||||
// 3 - map flexible
|
||||
// 4 - type protect
|
||||
};
|
||||
} // namespace orbis
|
||||
|
||||
orbis::SysResult orbis::sys_batch_map(Thread *thread, sint unk, sint flags,
|
||||
ptr<BatchMapEntry> entries,
|
||||
sint entriesCount,
|
||||
ptr<sint> processedCount) {
|
||||
auto ops = thread->tproc->ops;
|
||||
SysResult result = ErrorCode{};
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, unk, flags, entries, entriesCount,
|
||||
processedCount);
|
||||
|
||||
int processed = 0;
|
||||
for (int i = 0; i < entriesCount; ++i) {
|
||||
BatchMapEntry _entry;
|
||||
ORBIS_RET_ON_ERROR(uread(_entry, entries + i));
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, _entry.operation, ptr<void>(_entry.start),
|
||||
_entry.length, int(_entry.type), int(_entry.protection),
|
||||
_entry.offset);
|
||||
|
||||
switch (_entry.operation) {
|
||||
case 0:
|
||||
result = ops->dmem_mmap(thread, _entry.start, _entry.length, _entry.type,
|
||||
_entry.protection, flags, _entry.offset);
|
||||
break;
|
||||
case 1:
|
||||
result = ops->munmap(thread, _entry.start, _entry.length);
|
||||
break;
|
||||
case 2:
|
||||
result =
|
||||
ops->mprotect(thread, _entry.start, _entry.length, _entry.protection);
|
||||
break;
|
||||
default:
|
||||
result = ErrorCode::INVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, result.value());
|
||||
|
||||
if (result.value()) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, result.value());
|
||||
break;
|
||||
}
|
||||
|
||||
++processed;
|
||||
}
|
||||
|
||||
thread->retval[0] = 0;
|
||||
ORBIS_RET_ON_ERROR(uwrite(processedCount, processed));
|
||||
return result;
|
||||
}
|
||||
orbis::SysResult orbis::sys_osem_create(Thread *thread,
|
||||
ptr<const char[32]> name, uint attrs,
|
||||
|
|
@ -418,6 +488,7 @@ orbis::SysResult orbis::sys_osem_create(Thread *thread,
|
|||
sem = insertedSem;
|
||||
} else {
|
||||
sem = knew<Semaphore>(attrs, initCount, maxCount);
|
||||
std::strncpy(sem->name, _name, 32);
|
||||
}
|
||||
|
||||
thread->retval[0] = thread->tproc->semMap.insert(sem);
|
||||
|
|
@ -1048,8 +1119,26 @@ orbis::SysResult orbis::sys_prepare_to_suspend_process(Thread *thread,
|
|||
orbis::SysResult orbis::sys_get_resident_fmem_count(Thread *thread, pid_t pid) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_thr_get_name(Thread *thread, lwpid_t lwpid) {
|
||||
return ErrorCode::NOSYS;
|
||||
orbis::SysResult orbis::sys_thr_get_name(Thread *thread, lwpid_t lwpid,
|
||||
char *buf, size_t buflen) {
|
||||
Thread *searchThread;
|
||||
if (thread->tid == lwpid) {
|
||||
searchThread = thread;
|
||||
} else {
|
||||
searchThread = thread->tproc->threadsMap.get(lwpid);
|
||||
if (searchThread == nullptr) {
|
||||
return ErrorCode::SRCH;
|
||||
}
|
||||
}
|
||||
|
||||
auto namelen = std::strlen(searchThread->name);
|
||||
|
||||
if (namelen >= buflen) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
ORBIS_RET_ON_ERROR(uwriteRaw(buf, searchThread->name, namelen));
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_set_gpo(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
|
|
@ -1095,10 +1184,16 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid,
|
|||
return sysIpmiSendConnectResult(thread, result, kid, params, paramsSz);
|
||||
case 0x232:
|
||||
return sysIpmiSessionRespondSync(thread, result, kid, params, paramsSz);
|
||||
case 0x251:
|
||||
return sysIpmiClientGetMessage(thread, result, kid, params, paramsSz);
|
||||
case 0x252:
|
||||
return sysIpmiClientTryGetMessage(thread, result, kid, params, paramsSz);
|
||||
case 0x254:
|
||||
return sysIpmiSessionTrySendMessage(thread, result, kid, params, paramsSz);
|
||||
case 0x302:
|
||||
return sysIpmiSessionGetClientPid(thread, result, kid, params, paramsSz);
|
||||
case 0x310:
|
||||
return sysIpmiClientDisconnect(thread, result, kid, params, paramsSz);
|
||||
case 0x320:
|
||||
return sysIpmiClientInvokeSyncMethod(thread, result, kid, params, paramsSz);
|
||||
case 0x400:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
#include "pipe.hpp"
|
||||
#include "sys/sysproto.hpp"
|
||||
#include "uio.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
#include <chrono>
|
||||
#include <sys/socket.h>
|
||||
#include <thread>
|
||||
|
||||
orbis::SysResult orbis::sys_socket(Thread *thread, sint domain, sint type,
|
||||
sint protocol) {
|
||||
|
|
@ -24,37 +21,89 @@ orbis::SysResult orbis::sys_socket(Thread *thread, sint domain, sint type,
|
|||
}
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sys_bind(Thread *thread, sint s, caddr_t name,
|
||||
sint namelen) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, s, name, namelen);
|
||||
return {};
|
||||
// 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);
|
||||
return {};
|
||||
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<struct sockaddr> from,
|
||||
ptr<SocketAddress> from,
|
||||
ptr<uint32_t> fromlenaddr) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, s, from, fromlenaddr);
|
||||
std::this_thread::sleep_for(std::chrono::days(1));
|
||||
return SysResult::notAnError(ErrorCode::WOULDBLOCK);
|
||||
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) {
|
||||
return ErrorCode::NOSYS;
|
||||
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_ERROR(__FUNCTION__, domain, type, protocol, 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);
|
||||
|
||||
auto pipe = createPipe();
|
||||
auto a = thread->tproc->fileDescriptors.insert(pipe);
|
||||
auto b = thread->tproc->fileDescriptors.insert(pipe);
|
||||
if (auto errc = uwrite(rsv, a); errc != ErrorCode{}) {
|
||||
return errc;
|
||||
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 uwrite(rsv + 1, b);
|
||||
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_sendto(Thread *thread, sint s, caddr_t buf,
|
||||
size_t len, sint flags, caddr_t to,
|
||||
|
|
@ -67,54 +116,82 @@ orbis::SysResult orbis::sys_sendmsg(Thread *thread, sint s,
|
|||
}
|
||||
orbis::SysResult orbis::sys_recvfrom(Thread *thread, sint s, caddr_t buf,
|
||||
size_t len, sint flags,
|
||||
ptr<struct sockaddr> from,
|
||||
ptr<SocketAddress> from,
|
||||
ptr<uint32_t> fromlenaddr) {
|
||||
auto pipe = thread->tproc->fileDescriptors.get(s).cast<Pipe>();
|
||||
if (pipe == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
auto file = thread->tproc->fileDescriptors.get(s);
|
||||
if (file == nullptr) {
|
||||
return ErrorCode::BADF;
|
||||
}
|
||||
|
||||
std::lock_guard lock(pipe->mtx);
|
||||
IoVec io = {
|
||||
.base = buf,
|
||||
.len = len,
|
||||
};
|
||||
Uio uio{
|
||||
.iov = &io,
|
||||
.iovcnt = 1,
|
||||
.segflg = UioSeg::UserSpace,
|
||||
.rw = UioRw::Read,
|
||||
.td = thread,
|
||||
};
|
||||
pipe->ops->read(pipe.get(), &uio, thread);
|
||||
thread->retval[0] = uio.offset;
|
||||
return {};
|
||||
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) {
|
||||
return ErrorCode::NOSYS;
|
||||
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) {
|
||||
return ErrorCode::NOSYS;
|
||||
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);
|
||||
return {};
|
||||
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);
|
||||
return {};
|
||||
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<struct sockaddr> asa,
|
||||
ptr<SocketAddress> asa,
|
||||
ptr<uint32_t> alen) {
|
||||
return ErrorCode::NOSYS;
|
||||
// return uwrite<uint32_t>(alen, sizeof(SockAddr));
|
||||
ORBIS_LOG_TODO(__FUNCTION__);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_getpeername(Thread *thread, sint fdes,
|
||||
ptr<struct sockaddr> asa,
|
||||
ptr<SocketAddress> asa,
|
||||
ptr<uint32_t> alen) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,19 +2,52 @@
|
|||
#include "sys/sysproto.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) {
|
||||
return ErrorCode::NOSYS;
|
||||
if (buf == 0) {
|
||||
thread->retval[0] = 1;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::strncpy(buf->f_fstypename, "exfatfs", 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) {
|
||||
return ErrorCode::NOSYS;
|
||||
if (buf == 0) {
|
||||
thread->retval[0] = 1;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::strncpy(buf->f_fstypename, "exfatfs", 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) {
|
||||
|
|
@ -231,7 +264,7 @@ 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 ErrorCode::NOSYS;
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_fchmodat(Thread *thread, sint fd, ptr<char> path,
|
||||
mode_t mode, sint flag) {
|
||||
|
|
@ -353,7 +386,7 @@ orbis::SysResult orbis::sys_getdirentries(Thread *thread, sint fd,
|
|||
auto next = std::min<uint64_t>(file->dirEntries.size(), pos + rmax);
|
||||
file->nextOff = next * sizeof(orbis::Dirent);
|
||||
SysResult result{};
|
||||
result = uwrite((orbis::Dirent *)buf, entries + pos, next - pos);
|
||||
result = uwrite(ptr<orbis::Dirent>(buf), entries + pos, next - pos);
|
||||
if (result.isError())
|
||||
return result;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue