#include "stat.hpp" #include "sys/sysproto.hpp" #include "thread/ProcessOps.hpp" #include "thread/Thread.hpp" #include "thread/Process.hpp" #include "utils/Logs.hpp" #include #include orbis::SysResult orbis::sys_sync(Thread *thread) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_quotactl(Thread *thread, ptr 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 path, ptr 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 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 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 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 path) { ORBIS_LOG_WARNING(__FUNCTION__, path); thread->tproc->root = path; return {}; } // volatile bool debuggerPresent = false; orbis::SysResult orbis::sys_open(Thread *thread, ptr path, sint flags, sint mode) { if (auto open = thread->tproc->ops->open) { Ref 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 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 = thread->tproc->fileDescriptors.get(fd); if (file == nullptr) { return ErrorCode::BADF; } return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_mknod(Thread *thread, ptr path, sint mode, sint dev) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_mknodat(Thread *thread, sint fd, ptr path, mode_t mode, dev_t dev) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_mkfifo(Thread *thread, ptr path, sint mode) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_mkfifoat(Thread *thread, sint fd, ptr path, mode_t mode) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_link(Thread *thread, ptr path, ptr link) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_linkat(Thread *thread, sint fd1, ptr path1, sint fd2, ptr path2, sint flag) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_symlink(Thread *thread, ptr path, ptr link) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_symlinkat(Thread *thread, ptr path1, sint fd, ptr path2) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_undelete(Thread *thread, ptr path) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_unlink(Thread *thread, ptr 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 path, sint flag) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_lseek(Thread *thread, sint fd, off_t offset, sint whence) { Ref 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 path, sint flags) { if (auto open = thread->tproc->ops->open) { Ref file; return open(thread, path, flags, 0, &file); } return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_faccessat(Thread *thread, sint fd, ptr path, sint mode, sint flag) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_eaccess(Thread *thread, ptr path, sint flags) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_stat(Thread *thread, ptr path, ptr ub) { ORBIS_LOG_WARNING(__FUNCTION__, path); Ref 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 path, ptr buf, sint flag) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_lstat(Thread *thread, ptr path, ptr ub) { return sys_stat(thread, path, ub); } orbis::SysResult orbis::sys_nstat(Thread *thread, ptr path, ptr ub) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_nlstat(Thread *thread, ptr path, ptr ub) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_pathconf(Thread *thread, ptr path, sint name) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_lpathconf(Thread *thread, ptr path, sint name) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_readlink(Thread *thread, ptr path, ptr 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; 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 path, ptr buf, size_t bufsize) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_chflags(Thread *thread, ptr path, sint flags) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_lchflags(Thread *thread, ptr 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 path, sint mode) { return {}; } orbis::SysResult orbis::sys_fchmodat(Thread *thread, sint fd, ptr path, mode_t mode, sint flag) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_lchmod(Thread *thread, ptr 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 path, sint uid, sint gid) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_fchownat(Thread *thread, sint fd, ptr path, uid_t uid, gid_t gid, sint flag) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_lchown(Thread *thread, ptr 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 path, ptr tptr) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_futimesat(Thread *thread, sint fd, ptr path, ptr times) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_lutimes(Thread *thread, ptr path, ptr tptr) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_futimes(Thread *thread, sint fd, ptr tptr) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_truncate(Thread *thread, ptr path, off_t length) { Ref 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 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 from, ptr 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 old, sint newfd, ptr new_) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_mkdir(Thread *thread, ptr 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 path, mode_t mode) { Ref 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 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 buf, uint count, ptr basep) { ORBIS_LOG_WARNING(__FUNCTION__, fd, (void *)buf, count, basep); Ref 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(file->dirEntries.size(), pos + rmax); file->nextOff = next * sizeof(orbis::Dirent); SysResult result{}; result = uwrite(ptr(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 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 path) { ORBIS_LOG_WARNING(__FUNCTION__); return {}; } orbis::SysResult orbis::sys_lgetfh(Thread *thread, ptr fname, ptr fhp) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_getfh(Thread *thread, ptr fname, ptr fhp) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_fhopen(Thread *thread, ptr u_fhp, sint flags) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_fhstat(Thread *thread, ptr u_fhp, ptr sb) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_fhstatfs(Thread *thread, ptr u_fhp, ptr 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; }