[rpcsx-os] Use orbis::File instead of IoDeviceInstance

This commit is contained in:
DH 2023-07-29 19:53:34 +03:00
parent c29aada46a
commit 84b2419241
43 changed files with 1626 additions and 1161 deletions

View file

@ -4,6 +4,7 @@
#include <deque>
#include <map>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
@ -46,7 +47,9 @@ using kunmap =
std::unordered_map<K, T, Hash, Pred, kallocator<std::pair<const K, T>>>;
} // namespace utils
template <typename T, typename... Args> T *knew(Args &&...args) {
template <typename T, typename... Args>
requires(std::is_constructible_v<T, Args...>)
T *knew(Args &&...args) {
auto loc = static_cast<T *>(utils::kalloc(sizeof(T), alignof(T)));
auto res = std::construct_at(loc, std::forward<Args>(args)...);
if constexpr (requires(T *t) { t->_total_size = sizeof(T); })

View file

@ -1,8 +1,8 @@
#pragma once
#include "KernelAllocator.hpp"
#include "error/ErrorCode.hpp"
#include <atomic>
#include "utils/Rc.hpp"
#include "utils/SharedMutex.hpp"
#include <cstdint>
namespace orbis {
@ -16,10 +16,8 @@ struct FileOps {
std::int32_t flags;
ErrorCode (*ioctl)(File *file, std::uint64_t request, void *argp,
Thread *thread) = nullptr;
ErrorCode (*rdwr)(File *file, Uio *uio, Thread *thread) = nullptr;
ErrorCode (*close)(File *file, Thread *thread) = nullptr;
ErrorCode (*lseek)(File *file, std::uint64_t *offset, std::uint32_t whence,
Thread *thread) = nullptr;
ErrorCode (*read)(File *file, Uio *uio, Thread *thread) = nullptr;
ErrorCode (*write)(File *file, Uio *uio, Thread *thread) = nullptr;
ErrorCode (*truncate)(File *file, std::uint64_t len,
Thread *thread) = nullptr;
@ -40,17 +38,10 @@ struct FileOps {
Thread *thread) = nullptr;
};
struct File final {
FileOps *ops;
struct File : RcBase {
shared_mutex mtx;
const FileOps *ops = nullptr;
Ref<RcBase> device;
std::atomic<unsigned> refs{0};
void incRef() { refs.fetch_add(1, std::memory_order::acquire); }
void decRef() {
if (refs.fetch_sub(1, std::memory_order::release) == 1) {
kdelete(this);
}
}
std::uint64_t nextOff = 0;
};
} // namespace orbis

View file

@ -18,6 +18,7 @@ struct KEvent;
struct timespec;
struct Stat;
struct stack_t;
struct IoVec;
SysResult nosys(Thread *thread);
@ -126,10 +127,8 @@ SysResult sys_gettimeofday(Thread *thread, ptr<orbis::timeval> tp,
SysResult sys_getrusage(Thread *thread, sint who, ptr<struct rusage> rusage);
SysResult sys_getsockopt(Thread *thread, sint s, sint level, sint name,
caddr_t val, ptr<sint> avalsize);
SysResult sys_readv(Thread *thread, sint fd, ptr<struct iovec> iovp,
uint iovcnt);
SysResult sys_writev(Thread *thread, sint fd, ptr<struct iovec> iovp,
uint iovcnt);
SysResult sys_readv(Thread *thread, sint fd, ptr<IoVec> iovp, uint iovcnt);
SysResult sys_writev(Thread *thread, sint fd, ptr<IoVec> iovp, uint iovcnt);
SysResult sys_settimeofday(Thread *thread, ptr<struct timeval> tp,
ptr<orbis::timezone> tzp);
SysResult sys_fchown(Thread *thread, sint fd, sint uid, sint gid);
@ -249,10 +248,10 @@ SysResult sys_lutimes(Thread *thread, ptr<char> path, ptr<struct timeval> tptr);
SysResult sys_nstat(Thread *thread, ptr<char> path, ptr<struct nstat> ub);
SysResult sys_nfstat(Thread *thread, sint fd, ptr<struct nstat> sb);
SysResult sys_nlstat(Thread *thread, ptr<char> path, ptr<struct nstat> ub);
SysResult sys_preadv(Thread *thread, sint fd, ptr<struct iovec> iovp,
uint iovcnt, off_t offset);
SysResult sys_pwritev(Thread *thread, sint fd, ptr<struct iovec> iovp,
uint iovcnt, off_t offset);
SysResult sys_preadv(Thread *thread, sint fd, ptr<IoVec> iovp, uint iovcnt,
off_t offset);
SysResult sys_pwritev(Thread *thread, sint fd, ptr<IoVec> iovp, uint iovcnt,
off_t offset);
SysResult sys_fhopen(Thread *thread, ptr<const struct fhandle> u_fhp,
sint flags);
SysResult sys_fhstat(Thread *thread, ptr<const struct fhandle> u_fhp,
@ -361,8 +360,7 @@ SysResult sys_eaccess(Thread *thread, ptr<char> path, sint flags);
SysResult sys_afs3_syscall(Thread *thread, slong syscall, slong param1,
slong param2, slong param3, slong param4,
slong param5, slong param6);
SysResult sys_nmount(Thread *thread, ptr<struct iovec> iovp, uint iovcnt,
sint flags);
SysResult sys_nmount(Thread *thread, ptr<IoVec> iovp, uint iovcnt, sint flags);
SysResult sys___mac_get_proc(Thread *thread, ptr<struct mac> mac_p);
SysResult sys___mac_set_proc(Thread *thread, ptr<struct mac> mac_p);
SysResult sys___mac_get_fd(Thread *thread, sint fd, ptr<struct mac> mac_p);
@ -494,14 +492,14 @@ SysResult 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);
SysResult sys_sctp_generic_sendmsg_iov(Thread *thread, sint sd,
ptr<struct iovec> iov, sint iovlen,
caddr_t to, __socklen_t tolen,
SysResult 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);
SysResult sys_sctp_generic_recvmsg(Thread *thread, sint sd,
ptr<struct iovec> iov, sint iovlen,
caddr_t from, __socklen_t fromlen,
SysResult 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);
SysResult sys_pread(Thread *thread, sint fd, ptr<void> buf, size_t nbyte,
@ -557,9 +555,9 @@ SysResult sys_symlinkat(Thread *thread, ptr<char> path1, sint fd,
SysResult sys_unlinkat(Thread *thread, sint fd, ptr<char> path, sint flag);
SysResult sys_posix_openpt(Thread *thread, sint flags);
SysResult sys_gssd_syscall(Thread *thread, ptr<char> path);
SysResult sys_jail_get(Thread *thread, ptr<struct iovec> iovp, uint iovcnt,
SysResult sys_jail_get(Thread *thread, ptr<IoVec> iovp, uint iovcnt,
sint flags);
SysResult sys_jail_set(Thread *thread, ptr<struct iovec> iovp, uint iovcnt,
SysResult sys_jail_set(Thread *thread, ptr<IoVec> iovp, uint iovcnt,
sint flags);
SysResult sys_jail_remove(Thread *thread, sint jid);
SysResult sys_closefrom(Thread *thread, sint lowfd);

View file

@ -6,12 +6,11 @@
#include "../thread/Thread.hpp"
#include "../thread/types.hpp"
#include "ProcessState.hpp"
#include "orbis/file.hpp"
#include "orbis/module/Module.hpp"
#include "orbis/utils/IdMap.hpp"
#include "orbis/utils/SharedMutex.hpp"
#include <mutex>
namespace orbis {
class KernelContext;
struct Thread;
@ -61,7 +60,7 @@ struct Process final {
utils::RcIdMap<Semaphore, sint, 4097, 1> semMap;
utils::RcIdMap<Module, ModuleHandle> modulesMap;
utils::OwningIdMap<Thread, lwpid_t> threadsMap;
utils::RcIdMap<utils::RcBase, sint> fileDescriptors;
utils::RcIdMap<orbis::File, sint> fileDescriptors;
// Named objects for debugging
utils::shared_mutex namedObjMutex;

View file

@ -3,11 +3,13 @@
#include "../module/ModuleHandle.hpp"
#include "../thread/types.hpp"
#include "orbis-config.hpp"
#include "orbis/utils/Rc.hpp"
namespace orbis {
struct Thread;
struct Module;
struct timespec;
struct File;
struct ProcessOps {
SysResult (*mmap)(Thread *thread, caddr_t addr, size_t len, sint prot,
@ -28,22 +30,10 @@ struct ProcessOps {
SysResult (*virtual_query)(Thread *thread, ptr<const void> addr, sint flags,
ptr<void> info, ulong infoSize);
SysResult (*open)(Thread *thread, ptr<const char> path, sint flags,
sint mode);
SysResult (*open)(Thread *thread, ptr<const char> path, sint flags, sint mode,
Ref<File> *file);
SysResult (*socket)(Thread *thread, ptr<const char> name, sint domain,
sint type, sint protocol);
SysResult (*close)(Thread *thread, sint fd);
SysResult (*ioctl)(Thread *thread, sint fd, ulong com, caddr_t argp);
SysResult (*write)(Thread *thread, sint fd, ptr<const void> data, ulong size);
SysResult (*read)(Thread *thread, sint fd, ptr<void> data, ulong size);
SysResult (*pread)(Thread *thread, sint fd, ptr<void> data, ulong size,
ulong offset);
SysResult (*pwrite)(Thread *thread, sint fd, ptr<const void> data, ulong size,
ulong offset);
SysResult (*lseek)(Thread *thread, sint fd, ulong offset, sint whence);
SysResult (*ftruncate)(Thread *thread, sint fd, off_t length);
SysResult (*truncate)(Thread *thread, ptr<const char> path, off_t length);
sint type, sint protocol, Ref<File> *file);
SysResult (*dynlib_get_obj_member)(Thread *thread, ModuleHandle handle,
uint64_t index, ptr<ptr<void>> addrp);
SysResult (*dynlib_dlsym)(Thread *thread, ModuleHandle handle,

View file

@ -20,8 +20,8 @@ enum class UioSeg : std::uint8_t {
struct Uio {
std::uint64_t offset;
IoVec *iov;
std::int32_t iovcnt;
std::int32_t resid;
std::uint32_t iovcnt;
std::int64_t resid;
UioSeg segflg;
UioRw rw;
void *td;

View file

@ -1,6 +1,5 @@
#pragma once
#include <atomic>
#include <span>
#include <string>
namespace orbis {

View file

@ -17,53 +17,43 @@ orbis::SysResult orbis::sys_fcntl(Thread *thread, sint fd, sint cmd,
}
orbis::SysResult orbis::sys_close(Thread *thread, sint fd) {
ORBIS_LOG_NOTICE(__FUNCTION__, fd);
if (auto close = thread->tproc->ops->close) {
return close(thread, fd);
if (fd == 0) {
return {}; // FIXME: remove when shm would be implemented
}
return ErrorCode::NOSYS;
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) {
ORBIS_LOG_WARNING(__FUNCTION__, fd, ub);
thread->where();
if (fd == 0) {
return ErrorCode::PERM;
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
auto result = sys_lseek(thread, fd, 0, SEEK_CUR);
auto oldpos = thread->retval[0];
if (result.isError()) {
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 = sys_lseek(thread, fd, 0, SEEK_END);
auto len = thread->retval[0];
if (result.isError()) {
result = stat(file.get(), &_ub, thread);
if (result != ErrorCode{}) {
return result;
}
result = sys_read(thread, fd, ub, 1);
if (result.isError()) {
*ub = {};
ub->mode = 0777 | 0x4000;
} else {
*ub = {};
ub->size = len;
ub->blksize = 1;
ub->blocks = len;
ub->mode = 0777 | 0x8000;
}
result = sys_lseek(thread, fd, oldpos, SEEK_SET);
if (result.isError()) {
return result;
}
thread->retval[0] = 0;
return {};
return uwrite(ub, _ub);
}
orbis::SysResult orbis::sys_nfstat(Thread *thread, sint fd,
ptr<struct nstat> sb) {

View file

@ -3,7 +3,7 @@
#include "thread/Process.hpp"
#include "utils/Logs.hpp"
struct KQueue : orbis::RcBase {};
struct KQueue : orbis::File {};
orbis::SysResult orbis::sys_kqueue(Thread *thread) {
ORBIS_LOG_TODO(__FUNCTION__);

View file

@ -1,74 +1,296 @@
#include "orbis/utils/Logs.hpp"
#include "sys/sysproto.hpp"
#include "uio.hpp"
orbis::SysResult orbis::sys_read(Thread *thread, sint fd, ptr<void> buf,
size_t nbyte) {
ORBIS_LOG_TRACE(__FUNCTION__, fd, buf, nbyte);
if (auto read = thread->tproc->ops->read) {
return read(thread, fd, buf, nbyte);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
return ErrorCode::NOSYS;
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) {
return error;
}
auto cnt = io.offset - file->nextOff;
file->nextOff = io.offset;
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_TRACE(__FUNCTION__, fd, buf, nbyte, offset);
if (auto pread = thread->tproc->ops->pread) {
return pread(thread, fd, buf, nbyte, offset);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
return ErrorCode::NOSYS;
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<struct iovec> iovp, uint iovcnt) {
return ErrorCode::NOSYS;
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<struct iovec> iovp, uint iovcnt,
off_t offset) {
return ErrorCode::NOSYS;
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) {
ORBIS_LOG_NOTICE(__FUNCTION__, fd, buf, nbyte);
if (auto write = thread->tproc->ops->write) {
return write(thread, fd, buf, nbyte);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
return ErrorCode::NOSYS;
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) {
if (auto pwrite = thread->tproc->ops->pwrite) {
return pwrite(thread, fd, buf, nbyte, offset);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
return ErrorCode::NOSYS;
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<struct iovec> iovp, uint iovcnt) {
return ErrorCode::NOSYS;
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<struct iovec> iovp, uint iovcnt,
off_t offset) {
return ErrorCode::NOSYS;
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) {
ORBIS_LOG_WARNING(__FUNCTION__, fd, length);
if (auto ftruncate = thread->tproc->ops->ftruncate) {
return ftruncate(thread, fd, length);
if (fd == 0) {
return {}; // FIXME: remove when shm implemented
}
return ErrorCode::NOSYS;
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;
}
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) {
@ -77,10 +299,18 @@ orbis::SysResult orbis::sys_freebsd6_ftruncate(Thread *thread, sint fd, sint,
orbis::SysResult orbis::sys_ioctl(Thread *thread, sint fd, ulong com,
caddr_t data) {
ORBIS_LOG_WARNING(__FUNCTION__, fd, com);
if (auto ioctl = thread->tproc->ops->ioctl) {
return ioctl(thread, fd, com, data);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
return ErrorCode::NOSYS;
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,
@ -117,12 +347,12 @@ orbis::SysResult orbis::sys_sysarch(Thread *thread, sint op, ptr<char> parms) {
uint64_t fs;
if (auto error = uread(fs, (ptr<uint64_t>)parms); error != ErrorCode{})
return error;
std::printf("sys_sysarch: set FS to 0x%zx\n", (std::size_t)fs);
ORBIS_LOG_WARNING("sys_sysarch: set FS", (std::size_t)fs);
thread->fsBase = fs;
return {};
}
std::printf("sys_sysarch(op = %d, parms = %p): unknown op\n", op, parms);
ORBIS_LOG_WARNING(__FUNCTION__, op, parms);
return {};
}
orbis::SysResult orbis::sys_nnpfs_syscall(Thread *thread, sint operation,

View file

@ -3,11 +3,11 @@
orbis::SysResult orbis::sys_jail(Thread *thread, ptr<struct jail> jail) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_jail_set(Thread *thread, ptr<struct iovec> iovp,
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<struct iovec> iovp,
orbis::SysResult orbis::sys_jail_get(Thread *thread, ptr<IoVec> iovp,
uint iovcnt, sint flags) {
return ErrorCode::NOSYS;
}

View file

@ -8,7 +8,6 @@
#include "osem.hpp"
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <chrono>
orbis::SysResult orbis::sys_netcontrol(Thread *thread, sint fd, uint op,
ptr<void> buf, uint nbuf) {
@ -24,18 +23,28 @@ orbis::SysResult orbis::sys_socketex(Thread *thread, ptr<const char> name,
sint domain, sint type, sint protocol) {
ORBIS_LOG_TODO(__FUNCTION__, name, domain, type, protocol);
if (auto socket = thread->tproc->ops->socket) {
return socket(thread, name, domain, type, protocol);
Ref<File> file;
auto result = socket(thread, name, domain, type, protocol, &file);
if (result.isError()) {
return result;
}
auto fd = thread->tproc->fileDescriptors.insert(file);
ORBIS_LOG_WARNING("Socket opened", name, fd);
thread->retval[0] = fd;
return {};
}
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_socketclose(Thread *thread, sint fd) {
// This syscall is identical to sys_close
ORBIS_LOG_NOTICE(__FUNCTION__, fd);
if (auto close = thread->tproc->ops->close) {
return close(thread, fd);
if (thread->tproc->fileDescriptors.close(fd)) {
return {};
}
return ErrorCode::NOSYS;
return ErrorCode::BADF;
}
orbis::SysResult orbis::sys_netgetiflist(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;

View file

@ -82,12 +82,12 @@ orbis::sys_sctp_generic_sendmsg(Thread *thread, sint sd, caddr_t msg, sint mlen,
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_sctp_generic_sendmsg_iov(
Thread *thread, sint sd, ptr<struct iovec> iov, sint iovlen, caddr_t to,
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<struct iovec> iov,
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

@ -32,7 +32,14 @@ orbis::SysResult orbis::sys_open(Thread *thread, ptr<char> path, sint flags,
sint mode) {
ORBIS_LOG_NOTICE("sys_open", path, flags, mode);
if (auto open = thread->tproc->ops->open) {
return open(thread, path, flags, mode);
Ref<File> file;
auto result = open(thread, path, flags, mode, &file);
if (result.isError()) {
return result;
}
thread->retval[0] = thread->tproc->fileDescriptors.insert(file);
return {};
}
return ErrorCode::NOSYS;
@ -84,10 +91,46 @@ orbis::SysResult orbis::sys_unlinkat(Thread *thread, sint fd, ptr<char> path,
}
orbis::SysResult orbis::sys_lseek(Thread *thread, sint fd, off_t offset,
sint whence) {
if (auto lseek = thread->tproc->ops->lseek) {
return lseek(thread, fd, offset, whence);
Ref<File> file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
return ErrorCode::NOSYS;
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;
}
thread->retval[0] = file->nextOff;
return {};
}
orbis::SysResult orbis::sys_freebsd6_lseek(Thread *thread, sint fd, sint,
off_t offset, sint whence) {
@ -105,35 +148,30 @@ orbis::SysResult orbis::sys_eaccess(Thread *thread, ptr<char> path,
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_stat(Thread *thread, ptr<char> path, ptr<Stat> ub) {
ORBIS_LOG_WARNING(__FUNCTION__, path, ub);
auto result = sys_open(thread, path, 0, 0);
Ref<File> file;
auto result = thread->tproc->ops->open(thread, path, 0, 0, &file);
if (result.isError()) {
return ErrorCode::NOENT;
}
auto fd = thread->retval[0];
result = sys_lseek(thread, fd, 0, SEEK_END);
if (result.isError()) {
sys_close(thread, fd);
return result;
}
auto len = thread->retval[0];
result = sys_pread(thread, fd, ub, 1, 0);
if (result.isError()) {
*ub = {};
ub->mode = 0777 | 0x4000;
} else {
*ub = {};
ub->size = len;
ub->blksize = 1;
ub->blocks = len;
ub->mode = 0777 | 0x8000;
auto stat = file->ops->stat;
if (stat == nullptr) {
return ErrorCode::NOTSUP;
}
sys_close(thread, fd);
thread->retval[0] = 0;
return {};
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) {
@ -226,18 +264,25 @@ orbis::SysResult orbis::sys_futimes(Thread *thread, sint fd,
}
orbis::SysResult orbis::sys_truncate(Thread *thread, ptr<char> path,
off_t length) {
if (auto truncate = thread->tproc->ops->truncate) {
return truncate(thread, path, length);
Ref<File> file;
auto result = thread->tproc->ops->open(thread, path, 0, 0, &file);
if (result.isError()) {
return result;
}
return ErrorCode::NOSYS;
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 ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_fsync(Thread *thread, sint fd) { return {}; }
orbis::SysResult orbis::sys_rename(Thread *thread, ptr<char> from,
ptr<char> to) {
return ErrorCode::NOSYS;

View file

@ -8,7 +8,7 @@ orbis::SysResult orbis::sys_unmount(Thread *thread, ptr<char> path,
sint flags) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_nmount(Thread *thread, ptr<struct iovec> iovp,
uint iovcnt, sint flags) {
orbis::SysResult orbis::sys_nmount(Thread *thread, ptr<IoVec> iovp, uint iovcnt,
sint flags) {
return ErrorCode::NOSYS;
}

View file

@ -1,4 +1,5 @@
#include "utils/Logs.hpp"
#include "error/ErrorCode.hpp"
#include <cstdarg>
#include <cstdint>
#include <sstream>
@ -168,6 +169,298 @@ void log_class_string<bool>::format(std::string &out, const void *arg) {
out += get_object(arg) ? "1" : "0";
}
template <>
void log_class_string<orbis::ErrorCode>::format(std::string &out,
const void *arg) {
auto errorCode = get_object(arg);
switch (errorCode) {
case ErrorCode::PERM:
out += "PERM";
return;
case ErrorCode::NOENT:
out += "NOENT";
return;
case ErrorCode::SRCH:
out += "SRCH";
return;
case ErrorCode::INTR:
out += "INTR";
return;
case ErrorCode::IO:
out += "IO";
return;
case ErrorCode::NXIO:
out += "NXIO";
return;
case ErrorCode::TOOBIG:
out += "TOOBIG";
return;
case ErrorCode::NOEXEC:
out += "NOEXEC";
return;
case ErrorCode::BADF:
out += "BADF";
return;
case ErrorCode::CHILD:
out += "CHILD";
return;
case ErrorCode::DEADLK:
out += "DEADLK";
return;
case ErrorCode::NOMEM:
out += "NOMEM";
return;
case ErrorCode::ACCES:
out += "ACCES";
return;
case ErrorCode::FAULT:
out += "FAULT";
return;
case ErrorCode::NOTBLK:
out += "NOTBLK";
return;
case ErrorCode::BUSY:
out += "BUSY";
return;
case ErrorCode::EXIST:
out += "EXIST";
return;
case ErrorCode::XDEV:
out += "XDEV";
return;
case ErrorCode::NODEV:
out += "NODEV";
return;
case ErrorCode::NOTDIR:
out += "NOTDIR";
return;
case ErrorCode::ISDIR:
out += "ISDIR";
return;
case ErrorCode::INVAL:
out += "INVAL";
return;
case ErrorCode::NFILE:
out += "NFILE";
return;
case ErrorCode::MFILE:
out += "MFILE";
return;
case ErrorCode::NOTTY:
out += "NOTTY";
return;
case ErrorCode::TXTBSY:
out += "TXTBSY";
return;
case ErrorCode::FBIG:
out += "FBIG";
return;
case ErrorCode::NOSPC:
out += "NOSPC";
return;
case ErrorCode::SPIPE:
out += "SPIPE";
return;
case ErrorCode::ROFS:
out += "ROFS";
return;
case ErrorCode::MLINK:
out += "MLINK";
return;
case ErrorCode::PIPE:
out += "PIPE";
return;
case ErrorCode::DOM:
out += "DOM";
return;
case ErrorCode::RANGE:
out += "RANGE";
return;
case ErrorCode::AGAIN:
out += "AGAIN";
return;
case ErrorCode::INPROGRESS:
out += "INPROGRESS";
return;
case ErrorCode::ALREADY:
out += "ALREADY";
return;
case ErrorCode::NOTSOCK:
out += "NOTSOCK";
return;
case ErrorCode::DESTADDRREQ:
out += "DESTADDRREQ";
return;
case ErrorCode::MSGSIZE:
out += "MSGSIZE";
return;
case ErrorCode::PROTOTYPE:
out += "PROTOTYPE";
return;
case ErrorCode::NOPROTOOPT:
out += "NOPROTOOPT";
return;
case ErrorCode::PROTONOSUPPORT:
out += "PROTONOSUPPORT";
return;
case ErrorCode::SOCKTNOSUPPORT:
out += "SOCKTNOSUPPORT";
return;
case ErrorCode::OPNOTSUPP:
out += "OPNOTSUPP";
return;
case ErrorCode::PFNOSUPPORT:
out += "PFNOSUPPORT";
return;
case ErrorCode::AFNOSUPPORT:
out += "AFNOSUPPORT";
return;
case ErrorCode::ADDRINUSE:
out += "ADDRINUSE";
return;
case ErrorCode::ADDRNOTAVAIL:
out += "ADDRNOTAVAIL";
return;
case ErrorCode::NETDOWN:
out += "NETDOWN";
return;
case ErrorCode::NETUNREACH:
out += "NETUNREACH";
return;
case ErrorCode::NETRESET:
out += "NETRESET";
return;
case ErrorCode::CONNABORTED:
out += "CONNABORTED";
return;
case ErrorCode::CONNRESET:
out += "CONNRESET";
return;
case ErrorCode::NOBUFS:
out += "NOBUFS";
return;
case ErrorCode::ISCONN:
out += "ISCONN";
return;
case ErrorCode::NOTCONN:
out += "NOTCONN";
return;
case ErrorCode::SHUTDOWN:
out += "SHUTDOWN";
return;
case ErrorCode::TOOMANYREFS:
out += "TOOMANYREFS";
return;
case ErrorCode::TIMEDOUT:
out += "TIMEDOUT";
return;
case ErrorCode::CONNREFUSED:
out += "CONNREFUSED";
return;
case ErrorCode::LOOP:
out += "LOOP";
return;
case ErrorCode::NAMETOOLONG:
out += "NAMETOOLONG";
return;
case ErrorCode::HOSTDOWN:
out += "HOSTDOWN";
return;
case ErrorCode::HOSTUNREACH:
out += "HOSTUNREACH";
return;
case ErrorCode::NOTEMPTY:
out += "NOTEMPTY";
return;
case ErrorCode::PROCLIM:
out += "PROCLIM";
return;
case ErrorCode::USERS:
out += "USERS";
return;
case ErrorCode::DQUOT:
out += "DQUOT";
return;
case ErrorCode::STALE:
out += "STALE";
return;
case ErrorCode::REMOTE:
out += "REMOTE";
return;
case ErrorCode::BADRPC:
out += "BADRPC";
return;
case ErrorCode::RPCMISMATCH:
out += "RPCMISMATCH";
return;
case ErrorCode::PROGUNAVAIL:
out += "PROGUNAVAIL";
return;
case ErrorCode::PROGMISMATCH:
out += "PROGMISMATCH";
return;
case ErrorCode::PROCUNAVAIL:
out += "PROCUNAVAIL";
return;
case ErrorCode::NOLCK:
out += "NOLCK";
return;
case ErrorCode::NOSYS:
out += "NOSYS";
return;
case ErrorCode::FTYPE:
out += "FTYPE";
return;
case ErrorCode::AUTH:
out += "AUTH";
return;
case ErrorCode::NEEDAUTH:
out += "NEEDAUTH";
return;
case ErrorCode::IDRM:
out += "IDRM";
return;
case ErrorCode::NOMSG:
out += "NOMSG";
return;
case ErrorCode::OVERFLOW:
out += "OVERFLOW";
return;
case ErrorCode::CANCELED:
out += "CANCELED";
return;
case ErrorCode::ILSEQ:
out += "ILSEQ";
return;
case ErrorCode::NOATTR:
out += "NOATTR";
return;
case ErrorCode::DOOFUS:
out += "DOOFUS";
return;
case ErrorCode::BADMSG:
out += "BADMSG";
return;
case ErrorCode::MULTIHOP:
out += "MULTIHOP";
return;
case ErrorCode::NOLINK:
out += "NOLINK";
return;
case ErrorCode::PROTO:
out += "PROTO";
return;
case ErrorCode::NOTCAPABLE:
out += "NOTCAPABLE";
return;
case ErrorCode::CAPMODE:
out += "CAPMODE";
return;
}
out += "<unknown " + std::to_string((int)errorCode) + ">";
}
void _orbis_log_print(LogLevel lvl, std::string_view msg,
std::string_view names, const log_type_info *sup, ...) {
if (lvl > logs_level.load(std::memory_order::relaxed)) {