From f9fdc1aa49daa7ab63b37523135bc20031f31f61 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 9 Aug 2022 12:53:58 +0200 Subject: [PATCH] wutdevoptab: Implement devoptab using FSA functions --- libraries/wutdevoptab/MutexWrapper.h | 25 +++ libraries/wutdevoptab/devoptab_fsa.cpp | 186 +++++++++--------- libraries/wutdevoptab/devoptab_fsa.h | 170 +++++++++------- libraries/wutdevoptab/devoptab_fsa_chdir.cpp | 22 ++- libraries/wutdevoptab/devoptab_fsa_chmod.cpp | 32 +-- libraries/wutdevoptab/devoptab_fsa_close.cpp | 26 ++- .../wutdevoptab/devoptab_fsa_dirclose.cpp | 26 ++- .../wutdevoptab/devoptab_fsa_dirnext.cpp | 37 ++-- .../wutdevoptab/devoptab_fsa_diropen.cpp | 37 ++-- .../wutdevoptab/devoptab_fsa_dirreset.cpp | 25 ++- libraries/wutdevoptab/devoptab_fsa_fchmod.cpp | 9 +- libraries/wutdevoptab/devoptab_fsa_fstat.cpp | 32 +-- libraries/wutdevoptab/devoptab_fsa_fsync.cpp | 26 ++- libraries/wutdevoptab/devoptab_fsa_link.cpp | 7 +- libraries/wutdevoptab/devoptab_fsa_mkdir.cpp | 29 +-- libraries/wutdevoptab/devoptab_fsa_open.cpp | 98 +++++---- libraries/wutdevoptab/devoptab_fsa_read.cpp | 28 ++- libraries/wutdevoptab/devoptab_fsa_rename.cpp | 31 +-- libraries/wutdevoptab/devoptab_fsa_rmdir.cpp | 24 ++- libraries/wutdevoptab/devoptab_fsa_seek.cpp | 87 ++++---- libraries/wutdevoptab/devoptab_fsa_stat.cpp | 28 +-- .../wutdevoptab/devoptab_fsa_statvfs.cpp | 62 +++++- .../wutdevoptab/devoptab_fsa_truncate.cpp | 32 +-- libraries/wutdevoptab/devoptab_fsa_unlink.cpp | 23 ++- libraries/wutdevoptab/devoptab_fsa_utils.cpp | 142 ++++++++----- libraries/wutdevoptab/devoptab_fsa_utimes.cpp | 7 +- libraries/wutdevoptab/devoptab_fsa_write.cpp | 28 ++- 27 files changed, 766 insertions(+), 513 deletions(-) create mode 100644 libraries/wutdevoptab/MutexWrapper.h diff --git a/libraries/wutdevoptab/MutexWrapper.h b/libraries/wutdevoptab/MutexWrapper.h new file mode 100644 index 000000000..f2f637337 --- /dev/null +++ b/libraries/wutdevoptab/MutexWrapper.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include "coreinit/cache.h" + +class MutexWrapper { +public: + MutexWrapper() = default; + + void init(const char *name) { + OSInitMutexEx(&mutex, name); + } + + void lock() { + OSLockMutex(&mutex); + } + + void unlock() { + OSUnlockMutex(&mutex); + OSMemoryBarrier(); + } + +private: + OSMutex mutex{}; +}; diff --git a/libraries/wutdevoptab/devoptab_fsa.cpp b/libraries/wutdevoptab/devoptab_fsa.cpp index 395ad2f9c..3a8e66b0a 100644 --- a/libraries/wutdevoptab/devoptab_fsa.cpp +++ b/libraries/wutdevoptab/devoptab_fsa.cpp @@ -1,130 +1,120 @@ #include "devoptab_fsa.h" static devoptab_t -__wut_fs_devoptab = -{ - .name = "fs", - .structSize = sizeof(__wut_fs_file_t), - .open_r = __wut_fs_open, - .close_r = __wut_fs_close, - .write_r = __wut_fs_write, - .read_r = __wut_fs_read, - .seek_r = __wut_fs_seek, - .fstat_r = __wut_fs_fstat, - .stat_r = __wut_fs_stat, - .link_r = __wut_fs_link, - .unlink_r = __wut_fs_unlink, - .chdir_r = __wut_fs_chdir, - .rename_r = __wut_fs_rename, - .mkdir_r = __wut_fs_mkdir, - .dirStateSize = sizeof(__wut_fs_dir_t), - .diropen_r = __wut_fs_diropen, - .dirreset_r = __wut_fs_dirreset, - .dirnext_r = __wut_fs_dirnext, - .dirclose_r = __wut_fs_dirclose, - .statvfs_r = __wut_fs_statvfs, - .ftruncate_r = __wut_fs_ftruncate, - .fsync_r = __wut_fs_fsync, - .lstat_r = __wut_fs_stat, - .deviceData = NULL, - .chmod_r = __wut_fs_chmod, - .fchmod_r = __wut_fs_fchmod, - .rmdir_r = __wut_fs_rmdir, - .utimes_r = __wut_fs_utimes, -}; - -FSClient * -__wut_devoptab_fs_client = NULL; - -static BOOL -__wut_fs_initialised = FALSE; - -static BOOL -__wut_sd_mounted = FALSE; - -static char -sMountPath[0x80]; - -FSStatus -__init_wut_devoptab() -{ - FSStatus rc = 0; - - if (__wut_fs_initialised) { + __wut_fsa_devoptab = + { + .name = "fs", + .structSize = sizeof(__wut_fsa_file_t), + .open_r = __wut_fsa_open, + .close_r = __wut_fsa_close, + .write_r = __wut_fsa_write, + .read_r = __wut_fsa_read, + .seek_r = __wut_fsa_seek, + .fstat_r = __wut_fsa_fstat, + .stat_r = __wut_fsa_stat, + .link_r = __wut_fsa_link, + .unlink_r = __wut_fsa_unlink, + .chdir_r = __wut_fsa_chdir, + .rename_r = __wut_fsa_rename, + .mkdir_r = __wut_fsa_mkdir, + .dirStateSize = sizeof(__wut_fsa_dir_t), + .diropen_r = __wut_fsa_diropen, + .dirreset_r = __wut_fsa_dirreset, + .dirnext_r = __wut_fsa_dirnext, + .dirclose_r = __wut_fsa_dirclose, + .statvfs_r = __wut_fsa_statvfs, + .ftruncate_r = __wut_fsa_ftruncate, + .fsync_r = __wut_fsa_fsync, + .lstat_r = __wut_fsa_stat, + .deviceData = nullptr, + .chmod_r = __wut_fsa_chmod, + .fchmod_r = __wut_fsa_fchmod, + .rmdir_r = __wut_fsa_rmdir, + .lstat_r = __wut_fsa_stat, + .utimes_r = __wut_fsa_utimes, + }; + + +__wut_fsa_device_t __wut_fsa_device_data = {}; + +FSError __init_wut_devoptab() { + FSError rc = FS_ERROR_OK; + + if (__wut_fsa_device_data.setup) { return rc; } - __wut_devoptab_fs_client = memalign(0x20, sizeof(FSClient)); - FSCmdBlock fsCmd; - FSMountSource mountSource; - char workDir[0x83]; - - FSInit(); - rc = FSAddClient(__wut_devoptab_fs_client, -1); - - if (rc < 0) { - free(__wut_devoptab_fs_client); + __wut_fsa_device_data = {}; + memcpy(&__wut_fsa_device_data.device, &__wut_fsa_devoptab, sizeof(__wut_fsa_devoptab)); + __wut_fsa_device_data.device.deviceData = &__wut_fsa_device_data; + strncpy(__wut_fsa_device_data.name, "fs", sizeof(__wut_fsa_device_data.name) - 1); + __wut_fsa_device_data.device.name = __wut_fsa_device_data.name; + __wut_fsa_device_data.setup = false; + __wut_fsa_device_data.mounted = false; + __wut_fsa_device_data.isSDCard = false; + + FSAInit(); + __wut_fsa_device_data.clientHandle = FSAAddClient(nullptr); + if (__wut_fsa_device_data.clientHandle == 0) { + OSReport("FSAAddClient() failed: %s", FSAGetStatusStr(static_cast(__wut_fsa_device_data.clientHandle))); return rc; } - FSInitCmdBlock(&fsCmd); - - if (rc >= 0) { - int dev = AddDevice(&__wut_fs_devoptab); + int dev = AddDevice(&__wut_fsa_device_data.device); - if(dev != -1) { - setDefaultDevice(dev); - __wut_fs_initialised = TRUE; + if (dev != -1) { + setDefaultDevice(dev); + __wut_fsa_device_data.setup = true; + strncpy(__wut_fsa_device_data.mountPath, "/vol/external01", sizeof(__wut_fsa_device_data.mountPath) - 1); - // Mount the SD card - rc = FSGetMountSource(__wut_devoptab_fs_client, &fsCmd, FS_MOUNT_SOURCE_SD, &mountSource, -1); + rc = FSAMount(__wut_fsa_device_data.clientHandle, "/dev/sdcard01", __wut_fsa_device_data.mountPath, (FSAMountFlags) 0, nullptr, 0); - if (rc < 0) { - return rc; - } + if (rc < 0 && rc != FS_ERROR_ALREADY_EXISTS) { + OSReport("FSAMount(0x%08X, \"/dev/sdcard01\", %s, %08X, %08X, %08X) failed: %s\n", __wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, 0, 0, 0, FSAGetStatusStr(rc)); + return rc; + } - rc = FSMount(__wut_devoptab_fs_client, &fsCmd, &mountSource, sMountPath, sizeof(sMountPath), FS_ERROR_FLAG_ALL); + __wut_fsa_device_data.isSDCard = true; + __wut_fsa_device_data.mounted = true; + chdir("fs:/vol/external01"); - if (rc >= 0) { - __wut_sd_mounted = TRUE; - // chdir to SD root for general use - strcpy(workDir, "fs:"); - strcat(workDir, sMountPath); - chdir(workDir); - } + FSADeviceInfo deviceInfo; + if ((rc = FSAGetDeviceInfo(__wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, &deviceInfo)) >= 0) { + __wut_fsa_device_data.deviceSizeInSectors = deviceInfo.deviceSizeInSectors; + __wut_fsa_device_data.deviceSectorSize = deviceInfo.deviceSectorSize; } else { - FSDelClient(__wut_devoptab_fs_client, FS_ERROR_FLAG_ALL); - free(__wut_devoptab_fs_client); - return dev; + __wut_fsa_device_data.deviceSizeInSectors = 0xFFFFFFFF; + __wut_fsa_device_data.deviceSectorSize = 512; + OSReport("Failed to get DeviceInfo for %s: %s\n", __wut_fsa_device_data.mountPath, FSAGetStatusStr(rc)); } + + } else { + FSADelClient(__wut_fsa_device_data.clientHandle); + __wut_fsa_device_data.clientHandle = 0; + return FS_ERROR_MAX_CLIENTS; } return rc; } -FSStatus -__fini_wut_devoptab() -{ - FSStatus rc = 0; +FSError +__fini_wut_devoptab() { + FSError rc = FS_ERROR_OK; - if (!__wut_fs_initialised) { + if (!__wut_fsa_device_data.setup) { return rc; } - FSCmdBlock fsCmd; - if(__wut_sd_mounted) { - FSInitCmdBlock(&fsCmd); - FSUnmount(__wut_devoptab_fs_client, &fsCmd, sMountPath, FS_ERROR_FLAG_ALL); - __wut_sd_mounted = FALSE; + if (__wut_fsa_device_data.mounted) { + FSAUnmount(__wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, FSA_UNMOUNT_FLAG_BIND_MOUNT); + __wut_fsa_device_data.mounted = false; } - FSDelClient(__wut_devoptab_fs_client, FS_ERROR_FLAG_ALL); - free(__wut_devoptab_fs_client); + FSADelClient(__wut_fsa_device_data.clientHandle); - RemoveDevice(__wut_fs_devoptab.name); + RemoveDevice(__wut_fsa_device_data.device.name); - __wut_devoptab_fs_client = NULL; - __wut_fs_initialised = FALSE; + __wut_fsa_device_data.setup = false; return rc; } diff --git a/libraries/wutdevoptab/devoptab_fsa.h b/libraries/wutdevoptab/devoptab_fsa.h index 2d4990545..3ae501fa6 100644 --- a/libraries/wutdevoptab/devoptab_fsa.h +++ b/libraries/wutdevoptab/devoptab_fsa.h @@ -1,5 +1,8 @@ #pragma once -#include + +#include +#include +#include #include #include @@ -11,81 +14,114 @@ #include #include #include +#include "MutexWrapper.h" + +typedef struct FSADeviceData { + devoptab_t device; + bool setup; + bool mounted; + bool isSDCard; + char name[32]; + char mountPath[0x80]; + FSAClientHandle clientHandle; + uint64_t deviceSizeInSectors; + uint32_t deviceSectorSize; +} __wut_fsa_device_t; /** * Open file struct */ -typedef struct -{ - //! FS handle - FSFileHandle fd; +typedef struct { + //! FSA file handle + FSAFileHandle fd; - //! Flags used in open(2) - int flags; + //! Flags used in open(2) + int flags; - //! Current file offset - uint32_t offset; + //! Current file offset + uint32_t offset; - //! Current file size (only valid if O_APPEND is set) - uint32_t appendOffset; -} __wut_fs_file_t; + //! Current file path + char fullPath[FS_MAX_PATH + 1]; + //! Guard file access + MutexWrapper mutex; + + //! Current file size (only valid if O_APPEND is set) + uint32_t appendOffset; +} __wut_fsa_file_t; /** * Open directory struct */ -typedef struct -{ - //! Should be set to FS_DIRITER_MAGIC - uint32_t magic; - - //! FS handle - FSDirectoryHandle fd; - - //! Temporary storage for reading entries - FSDirectoryEntry entry_data; -} __wut_fs_dir_t; - -#define FS_DIRITER_MAGIC 0x77696975 - -extern FSClient * -__wut_devoptab_fs_client; - -int __wut_fs_open(struct _reent *r, void *fileStruct, const char *path, - int flags, int mode); -int __wut_fs_close(struct _reent *r, void *fd); -ssize_t __wut_fs_write(struct _reent *r, void *fd, const char *ptr, - size_t len); -ssize_t __wut_fs_read(struct _reent *r, void *fd, char *ptr, size_t len); -off_t __wut_fs_seek(struct _reent *r, void *fd, off_t pos, int dir); -int __wut_fs_fstat(struct _reent *r, void *fd, struct stat *st); -int __wut_fs_stat(struct _reent *r, const char *file, struct stat *st); -int __wut_fs_link(struct _reent *r, const char *existing, - const char *newLink); -int __wut_fs_unlink(struct _reent *r, const char *name); -int __wut_fs_chdir(struct _reent *r, const char *name); -int __wut_fs_rename(struct _reent *r, const char *oldName, - const char *newName); -int __wut_fs_mkdir(struct _reent *r, const char *path, int mode); -DIR_ITER* __wut_fs_diropen(struct _reent *r, DIR_ITER *dirState, - const char *path); -int __wut_fs_dirreset(struct _reent *r, DIR_ITER *dirState); -int __wut_fs_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, - struct stat *filestat); -int __wut_fs_dirclose(struct _reent *r, DIR_ITER *dirState); -int __wut_fs_statvfs(struct _reent *r, const char *path, - struct statvfs *buf); -int __wut_fs_ftruncate(struct _reent *r, void *fd, off_t len); -int __wut_fs_fsync(struct _reent *r, void *fd); -int __wut_fs_chmod(struct _reent *r, const char *path, mode_t mode); -int __wut_fs_fchmod(struct _reent *r, void *fd, mode_t mode); -int __wut_fs_rmdir(struct _reent *r, const char *name); -int __wut_fs_utimes(struct _reent *r, const char *filename, const struct timeval times[2]); - -// devoptab_fs_utils.c -char * __wut_fs_fixpath(struct _reent *r, const char *path); -int __wut_fs_translate_error(FSStatus error); -time_t __wut_fs_translate_time(FSTime timeValue); -mode_t __wut_fs_translate_stat_mode(FSStat *fsStat); -FSMode __wut_fs_translate_permission_mode(mode_t mode); -void __wut_fs_translate_stat(FSStat *fsStat, struct stat* posStat); +typedef struct { + //! Should be set to FS_DIRITER_MAGIC + uint32_t magic; + + //! FS handle + FSADirectoryHandle fd; + + //! Temporary storage for reading entries + FSADirectoryEntry entry_data; + + //! Current file path + char name[FS_MAX_PATH +1]; + + //! Guard dir access + MutexWrapper mutex; +} __wut_fsa_dir_t; + +#define FSA_DIRITER_MAGIC 0x77696975 + +#ifdef __cplusplus +extern "C" { +#endif + +FSError +__init_wut_devoptab(); + +FSError +__fini_wut_devoptab(); + +int __wut_fsa_open(struct _reent *r, void *fileStruct, const char *path, + int flags, int mode); +int __wut_fsa_close(struct _reent *r, void *fd); +ssize_t __wut_fsa_write(struct _reent *r, void *fd, const char *ptr, + size_t len); +ssize_t __wut_fsa_read(struct _reent *r, void *fd, char *ptr, size_t len); +off_t __wut_fsa_seek(struct _reent *r, void *fd, off_t pos, int dir); +int __wut_fsa_fstat(struct _reent *r, void *fd, struct stat *st); +int __wut_fsa_stat(struct _reent *r, const char *file, struct stat *st); +int __wut_fsa_link(struct _reent *r, const char *existing, + const char *newLink); +int __wut_fsa_unlink(struct _reent *r, const char *name); +int __wut_fsa_chdir(struct _reent *r, const char *name); +int __wut_fsa_rename(struct _reent *r, const char *oldName, + const char *newName); +int __wut_fsa_mkdir(struct _reent *r, const char *path, int mode); +DIR_ITER *__wut_fsa_diropen(struct _reent *r, DIR_ITER *dirState, + const char *path); +int __wut_fsa_dirreset(struct _reent *r, DIR_ITER *dirState); +int __wut_fsa_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, + struct stat *filestat); +int __wut_fsa_dirclose(struct _reent *r, DIR_ITER *dirState); +int __wut_fsa_statvfs(struct _reent *r, const char *path, + struct statvfs *buf); +int __wut_fsa_ftruncate(struct _reent *r, void *fd, off_t len); +int __wut_fsa_fsync(struct _reent *r, void *fd); +int __wut_fsa_chmod(struct _reent *r, const char *path, mode_t mode); +int __wut_fsa_fchmod(struct _reent *r, void *fd, mode_t mode); +int __wut_fsa_rmdir(struct _reent *r, const char *name); +int __wut_fsa_utimes(struct _reent *r, const char *filename, const struct timeval times[2]); + +// devoptab_fsa_utils.c +char *__wut_fsa_fixpath(struct _reent *r, const char *path); +int __wut_fsa_translate_error(FSError error); +time_t __wut_fsa_translate_time(FSTime timeValue); +mode_t __wut_fsa_translate_stat_mode(FSStat *fsStat); +FSMode __wut_fsa_translate_permission_mode(mode_t mode); +void __wut_fsa_translate_stat(FSStat *fsStat, struct stat *posStat); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libraries/wutdevoptab/devoptab_fsa_chdir.cpp b/libraries/wutdevoptab/devoptab_fsa_chdir.cpp index 3964a55f1..b3497fc17 100644 --- a/libraries/wutdevoptab/devoptab_fsa_chdir.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_chdir.cpp @@ -1,29 +1,31 @@ #include "devoptab_fsa.h" int -__wut_fs_chdir(struct _reent *r, - const char *path) -{ - FSStatus status; - FSCmdBlock cmd; +__wut_fsa_chdir(struct _reent *r, + const char *path) { + FSError status; + __wut_fsa_device_t *deviceData; if (!path) { r->_errno = EINVAL; return -1; } - char *fixedPath = __wut_fs_fixpath(r, path); + char *fixedPath = __wut_fsa_fixpath(r, path); if (!fixedPath) { + r->_errno = ENOMEM; return -1; } + deviceData = (__wut_fsa_device_t *) r->deviceData; - FSInitCmdBlock(&cmd); - status = FSChangeDir(__wut_devoptab_fs_client, &cmd, fixedPath, FS_ERROR_FLAG_ALL); - free(fixedPath); + status = FSAChangeDir(deviceData->clientHandle, fixedPath); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSAChangeDir(0x%08X, %s) failed: %s\n", deviceData->clientHandle, fixedPath, FSAGetStatusStr(status)); + free(fixedPath); + r->_errno = __wut_fsa_translate_error(status); return -1; } + free(fixedPath); return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_chmod.cpp b/libraries/wutdevoptab/devoptab_fsa_chmod.cpp index 76420083c..14476d0dd 100644 --- a/libraries/wutdevoptab/devoptab_fsa_chmod.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_chmod.cpp @@ -1,34 +1,38 @@ -#include #include "devoptab_fsa.h" +#include +#include int -__wut_fs_chmod(struct _reent *r, - const char *path, - mode_t mode) -{ - FSStatus status; - FSCmdBlock cmd; +__wut_fsa_chmod(struct _reent *r, + const char *path, + mode_t mode) { + FSError status; + __wut_fsa_device_t *deviceData; if (!path) { r->_errno = EINVAL; return -1; } - char *fixedPath = __wut_fs_fixpath(r, path); + char *fixedPath = __wut_fsa_fixpath(r, path); if (!fixedPath) { + r->_errno = ENOMEM; return -1; } - FSMode translatedMode = __wut_fs_translate_permission_mode(mode); + FSMode translatedMode = __wut_fsa_translate_permission_mode(mode); - FSInitCmdBlock(&cmd); - status = FSChangeMode(__wut_devoptab_fs_client, &cmd, fixedPath, - translatedMode, 0x777, FS_ERROR_FLAG_ALL); - free(fixedPath); + deviceData = (__wut_fsa_device_t *) r->deviceData; + + status = FSAChangeMode(deviceData->clientHandle, fixedPath, translatedMode); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSAChangeMode(0x%08X, %s, 0x%X) failed: %s\n", + deviceData->clientHandle, fixedPath, translatedMode, FSAGetStatusStr(status)); + free(fixedPath); + r->_errno = __wut_fsa_translate_error(status); return -1; } + free(fixedPath); return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_close.cpp b/libraries/wutdevoptab/devoptab_fsa_close.cpp index f5740863e..a2984ab28 100644 --- a/libraries/wutdevoptab/devoptab_fsa_close.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_close.cpp @@ -1,23 +1,29 @@ #include "devoptab_fsa.h" +#include int -__wut_fs_close(struct _reent *r, - void *fd) -{ - FSStatus status; - FSCmdBlock cmd; - __wut_fs_file_t *file; +__wut_fsa_close(struct _reent *r, + void *fd) { + FSError status; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; if (!fd) { r->_errno = EINVAL; return -1; } - FSInitCmdBlock(&cmd); - file = (__wut_fs_file_t *)fd; - status = FSCloseFile(__wut_devoptab_fs_client, &cmd, file->fd, FS_ERROR_FLAG_ALL); + file = (__wut_fsa_file_t *) fd; + + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(file->mutex); + + status = FSACloseFile(deviceData->clientHandle, file->fd); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSACloseFile(0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, file->fd, file->fullPath, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_dirclose.cpp b/libraries/wutdevoptab/devoptab_fsa_dirclose.cpp index 494b91d51..d9da25adf 100644 --- a/libraries/wutdevoptab/devoptab_fsa_dirclose.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_dirclose.cpp @@ -1,23 +1,29 @@ #include "devoptab_fsa.h" +#include int -__wut_fs_dirclose(struct _reent *r, - DIR_ITER *dirState) -{ - FSStatus status; - FSCmdBlock cmd; - __wut_fs_dir_t *dir; +__wut_fsa_dirclose(struct _reent *r, + DIR_ITER *dirState) { + FSError status; + __wut_fsa_dir_t *dir; + __wut_fsa_device_t *deviceData; if (!dirState) { r->_errno = EINVAL; return -1; } - FSInitCmdBlock(&cmd); - dir = (__wut_fs_dir_t *)(dirState->dirStruct); - status = FSCloseDir(__wut_devoptab_fs_client, &cmd, dir->fd, FS_ERROR_FLAG_ALL); + dir = (__wut_fsa_dir_t *) (dirState->dirStruct); + + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(dir->mutex); + + status = FSACloseDir(deviceData->clientHandle, dir->fd); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSACloseDir(0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, dir->fd, dir->name, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp b/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp index 22a223cdf..c1e9edb84 100644 --- a/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp @@ -1,33 +1,40 @@ #include "devoptab_fsa.h" +#include int -__wut_fs_dirnext(struct _reent *r, - DIR_ITER *dirState, - char *filename, - struct stat *filestat) -{ - FSStatus status; - FSCmdBlock cmd; - __wut_fs_dir_t *dir; +__wut_fsa_dirnext(struct _reent *r, + DIR_ITER *dirState, + char *filename, + struct stat *filestat) { + FSError status; + __wut_fsa_dir_t *dir; + __wut_fsa_device_t *deviceData; if (!dirState || !filename || !filestat) { r->_errno = EINVAL; return -1; } - FSInitCmdBlock(&cmd); - dir = (__wut_fs_dir_t *)(dirState->dirStruct); + dir = (__wut_fsa_dir_t *) (dirState->dirStruct); memset(&dir->entry_data, 0, sizeof(dir->entry_data)); - status = FSReadDir(__wut_devoptab_fs_client, &cmd, dir->fd, &dir->entry_data, - FS_ERROR_FLAG_ALL); + + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(dir->mutex); + + status = FSAReadDir(deviceData->clientHandle, dir->fd, &dir->entry_data); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + if (status != FS_ERROR_END_OF_DIR) { + OSReport("FSAReadDir(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, dir->fd, &dir->entry_data, dir->name, FSAGetStatusStr(status)); + } + r->_errno = __wut_fsa_translate_error(status); return -1; } - __wut_fs_translate_stat(&dir->entry_data.info, filestat); + __wut_fsa_translate_stat(&dir->entry_data.info, filestat); memset(filename, 0, NAME_MAX); - strcpy(filename, dir->entry_data.name); + strncpy(filename, dir->entry_data.name, NAME_MAX - 1); return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_diropen.cpp b/libraries/wutdevoptab/devoptab_fsa_diropen.cpp index dc48fa73a..d47c793f9 100644 --- a/libraries/wutdevoptab/devoptab_fsa_diropen.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_diropen.cpp @@ -1,36 +1,41 @@ #include "devoptab_fsa.h" +#include DIR_ITER * -__wut_fs_diropen(struct _reent *r, - DIR_ITER *dirState, - const char *path) -{ - FSDirectoryHandle fd; - FSStatus status; - FSCmdBlock cmd; - __wut_fs_dir_t *dir; +__wut_fsa_diropen(struct _reent *r, + DIR_ITER *dirState, + const char *path) { + FSADirectoryHandle fd; + FSError status; + __wut_fsa_dir_t *dir; + __wut_fsa_device_t *deviceData; if (!dirState || !path) { r->_errno = EINVAL; return NULL; } - char *fixedPath = __wut_fs_fixpath(r, path); + char *fixedPath = __wut_fsa_fixpath(r, path); if (!fixedPath) { return NULL; } - - FSInitCmdBlock(&cmd); - dir = (__wut_fs_dir_t *)(dirState->dirStruct); - status = FSOpenDir(__wut_devoptab_fs_client, &cmd, fixedPath, &fd, FS_ERROR_FLAG_ALL); + dir = (__wut_fsa_dir_t *) (dirState->dirStruct); + strncpy(dir->name, fixedPath, sizeof(dir->name) - 1); free(fixedPath); + + dir->mutex.init(dir->name); + std::lock_guard lock(dir->mutex); + + deviceData = (__wut_fsa_device_t *) r->deviceData; + status = FSAOpenDir(deviceData->clientHandle, dir->name, &fd); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSAOpenDir(0x%08X, %s, 0x%08X) failed: %s\n", deviceData->clientHandle, dir->name, &fd, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return NULL; } - dir->magic = FS_DIRITER_MAGIC; - dir->fd = fd; + dir->magic = FSA_DIRITER_MAGIC; + dir->fd = fd; memset(&dir->entry_data, 0, sizeof(dir->entry_data)); return dirState; } diff --git a/libraries/wutdevoptab/devoptab_fsa_dirreset.cpp b/libraries/wutdevoptab/devoptab_fsa_dirreset.cpp index 2a1ffd74b..d67e974b7 100644 --- a/libraries/wutdevoptab/devoptab_fsa_dirreset.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_dirreset.cpp @@ -1,23 +1,28 @@ #include "devoptab_fsa.h" +#include int -__wut_fs_dirreset(struct _reent *r, - DIR_ITER *dirState) -{ - FSStatus status; - FSCmdBlock cmd; - __wut_fs_dir_t *dir; +__wut_fsa_dirreset(struct _reent *r, + DIR_ITER *dirState) { + FSError status; + __wut_fsa_dir_t *dir; + __wut_fsa_device_t *deviceData; if (!dirState) { r->_errno = EINVAL; return -1; } - FSInitCmdBlock(&cmd); - dir = (__wut_fs_dir_t *)(dirState->dirStruct); - status = FSRewindDir(__wut_devoptab_fs_client, &cmd, dir->fd, FS_ERROR_FLAG_ALL); + dir = (__wut_fsa_dir_t *) (dirState->dirStruct); + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(dir->mutex); + + status = FSARewindDir(deviceData->clientHandle, dir->fd); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSARewindDir(0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, dir->fd, dir->name, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_fchmod.cpp b/libraries/wutdevoptab/devoptab_fsa_fchmod.cpp index a6ab414e7..71896cc44 100644 --- a/libraries/wutdevoptab/devoptab_fsa_fchmod.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_fchmod.cpp @@ -1,11 +1,10 @@ #include "devoptab_fsa.h" int -__wut_fs_fchmod(struct _reent *r, - void *fd, - mode_t mode) -{ - // TODO: FSChangeMode and FSStatFile? +__wut_fsa_fchmod(struct _reent *r, + void *fd, + mode_t mode) { + // FSChangeMode on open files is not possible on Cafe OS r->_errno = ENOSYS; return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_fstat.cpp b/libraries/wutdevoptab/devoptab_fsa_fstat.cpp index 9d2e29a73..3f212101d 100644 --- a/libraries/wutdevoptab/devoptab_fsa_fstat.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_fstat.cpp @@ -1,30 +1,34 @@ #include "devoptab_fsa.h" +#include int -__wut_fs_fstat(struct _reent *r, - void *fd, - struct stat *st) -{ - FSStatus status; - FSStat fsStat; - FSCmdBlock cmd; - __wut_fs_file_t *file; +__wut_fsa_fstat(struct _reent *r, + void *fd, + struct stat *st) { + FSError status; + FSAStat fsStat; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; if (!fd || !st) { r->_errno = EINVAL; return -1; } - FSInitCmdBlock(&cmd); - file = (__wut_fs_file_t *)fd; - status = FSGetStatFile(__wut_devoptab_fs_client, &cmd, file->fd, &fsStat, - FS_ERROR_FLAG_ALL); + file = (__wut_fsa_file_t *) fd; + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(file->mutex); + + status = FSAGetStatFile(deviceData->clientHandle, file->fd, &fsStat); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSARewindDir(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, file->fd, &fsStat, file->fullPath, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } - __wut_fs_translate_stat(&fsStat, st); + __wut_fsa_translate_stat(&fsStat, st); return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_fsync.cpp b/libraries/wutdevoptab/devoptab_fsa_fsync.cpp index 69acdc38f..66ef6eb2e 100644 --- a/libraries/wutdevoptab/devoptab_fsa_fsync.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_fsync.cpp @@ -1,23 +1,29 @@ #include "devoptab_fsa.h" +#include int -__wut_fs_fsync(struct _reent *r, - void *fd) -{ - FSStatus status; - FSCmdBlock cmd; - __wut_fs_file_t *file; +__wut_fsa_fsync(struct _reent *r, + void *fd) { + FSError status; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; if (!fd) { r->_errno = EINVAL; return -1; } - FSInitCmdBlock(&cmd); - file = (__wut_fs_file_t *)fd; - status = FSFlushFile(__wut_devoptab_fs_client, &cmd, file->fd, FS_ERROR_FLAG_ALL); + file = (__wut_fsa_file_t *) fd; + + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(file->mutex); + + status = FSAFlushFile(deviceData->clientHandle, file->fd); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSAFlushFile(0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, file->fd, file->fullPath, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_link.cpp b/libraries/wutdevoptab/devoptab_fsa_link.cpp index 7eb7add36..d142bf6d1 100644 --- a/libraries/wutdevoptab/devoptab_fsa_link.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_link.cpp @@ -1,10 +1,9 @@ #include "devoptab_fsa.h" int -__wut_fs_link(struct _reent *r, - const char *existing, - const char *newLink) -{ +__wut_fsa_link(struct _reent *r, + const char *existing, + const char *newLink) { r->_errno = ENOSYS; return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_mkdir.cpp b/libraries/wutdevoptab/devoptab_fsa_mkdir.cpp index e4312bec7..6ecaf80c8 100644 --- a/libraries/wutdevoptab/devoptab_fsa_mkdir.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_mkdir.cpp @@ -1,32 +1,37 @@ #include "devoptab_fsa.h" int -__wut_fs_mkdir(struct _reent *r, - const char *path, - int mode) -{ - FSStatus status; - FSCmdBlock cmd; +__wut_fsa_mkdir(struct _reent *r, + const char *path, + int mode) { + FSError status; char *fixedPath; + __wut_fsa_device_t *deviceData; if (!path) { r->_errno = EINVAL; return -1; } - fixedPath = __wut_fs_fixpath(r, path); + fixedPath = __wut_fsa_fixpath(r, path); if (!fixedPath) { + r->_errno = ENOMEM; return -1; } - // TODO: Use mode to set directory attributes. - FSInitCmdBlock(&cmd); - status = FSMakeDir(__wut_devoptab_fs_client, &cmd, fixedPath, FS_ERROR_FLAG_ALL); - free(fixedPath); + deviceData = (__wut_fsa_device_t *) r->deviceData; + + FSMode translatedMode = __wut_fsa_translate_permission_mode(mode); + + status = FSAMakeDir(deviceData->clientHandle, fixedPath, translatedMode); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSAMakeDir(0x%08X, %s, 0x%X) failed: %s\n", + deviceData->clientHandle, fixedPath, translatedMode, FSAGetStatusStr(status)); + free(fixedPath); + r->_errno = __wut_fsa_translate_error(status); return -1; } + free(fixedPath); return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_open.cpp b/libraries/wutdevoptab/devoptab_fsa_open.cpp index 5abc33adf..c4bf695b1 100644 --- a/libraries/wutdevoptab/devoptab_fsa_open.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_open.cpp @@ -1,19 +1,22 @@ #include "devoptab_fsa.h" +#include // Extended "magic" value that allows opening files with FS_OPEN_FLAG_UNENCRYPTED in underlying FSOpenFileEx() call similar to O_DIRECTORY +#ifndef O_UNENCRYPTED #define O_UNENCRYPTED 0x4000000 +#endif int -__wut_fs_open(struct _reent *r, - void *fileStruct, - const char *path, - int flags, - int mode) { - FSFileHandle fd; - FSStatus status; - FSCmdBlock cmd; +__wut_fsa_open(struct _reent *r, + void *fileStruct, + const char *path, + int flags, + int mode) { + FSAFileHandle fd; + FSError status; const char *fsMode; - __wut_fs_file_t *file; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; if (!fileStruct || !path) { r->_errno = EINVAL; @@ -55,70 +58,91 @@ __wut_fs_open(struct _reent *r, return -1; } - char *fixedPath = __wut_fs_fixpath(r, path); + char *fixedPath = __wut_fsa_fixpath(r, path); if (!fixedPath) { + r->_errno = ENOMEM; return -1; } - // Open the file - FSInitCmdBlock(&cmd); + file = (__wut_fsa_file_t *) fileStruct; + strncpy(file->fullPath, fixedPath, sizeof(file->fullPath) - 1); + free(fixedPath); + + // Prepare flags FSOpenFileFlags openFlags = (flags & O_UNENCRYPTED) ? FS_OPEN_FLAG_UNENCRYPTED : FS_OPEN_FLAG_NONE; - uint32_t preallocSize = 0; + FSMode translatedMode = __wut_fsa_translate_permission_mode(mode); + uint32_t preAllocSize = 0; + + // Init mutex and lock + file->mutex.init(file->fullPath); + std::lock_guard lock(file->mutex); + + deviceData = (__wut_fsa_device_t *) r->deviceData; if (createFileIfNotFound || failIfFileNotFound || (flags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT)) { // Check if file exists - FSStat stat; - status = FSGetStat(__wut_devoptab_fs_client, &cmd, fixedPath, &stat, FS_ERROR_FLAG_ALL); - if (status == FS_STATUS_NOT_FOUND) { + FSAStat stat; + status = FSAGetStat(deviceData->clientHandle, file->fullPath, &stat); + if (status == FS_ERROR_NOT_FOUND) { if (createFileIfNotFound) { // Create new file if needed - status = FSOpenFileEx(__wut_devoptab_fs_client, &cmd, fixedPath, "w", __wut_fs_translate_permission_mode(mode), - openFlags, preallocSize, &fd, FS_ERROR_FLAG_ALL); - if (status == FS_STATUS_OK) { - FSCloseFile(__wut_devoptab_fs_client, &cmd, fd, FS_ERROR_FLAG_ALL); + status = FSAOpenFileEx(deviceData->clientHandle, file->fullPath, "w", translatedMode, + openFlags, preAllocSize, &fd); + if (status == FS_ERROR_OK) { + if (FSACloseFile(deviceData->clientHandle, fd) != FS_ERROR_OK) { + OSReport("FSACloseFile(0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, fd, file->fullPath, FSAGetStatusStr(status)); + } fd = -1; } else { - free(fixedPath); - r->_errno = __wut_fs_translate_error(status); + OSReport("FSAOpenFileEx(0x%08X, %s, %s, 0x%X, 0x%08X, 0x%08X, 0x%08X) failed: %s\n", + deviceData->clientHandle, file->fullPath, "w", translatedMode, openFlags, preAllocSize, &fd, + FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } } else if (failIfFileNotFound) { // Return an error if we don't we create new files - free(fixedPath); - r->_errno = __wut_fs_translate_error(status); + r->_errno = __wut_fsa_translate_error(status); return -1; } - } else if (status == FS_STATUS_OK) { + } else if (status == FS_ERROR_OK) { // If O_CREAT and O_EXCL are set, open() shall fail if the file exists. if ((flags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT)) { - free(fixedPath); r->_errno = EEXIST; return -1; } } } - status = FSOpenFileEx(__wut_devoptab_fs_client, &cmd, fixedPath, fsMode, __wut_fs_translate_permission_mode(mode), - openFlags, preallocSize, &fd, FS_ERROR_FLAG_ALL); - free(fixedPath); + status = FSAOpenFileEx(deviceData->clientHandle, file->fullPath, fsMode, translatedMode, openFlags, preAllocSize, &fd); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + if(status != FS_ERROR_NOT_FOUND) { + OSReport("FSAOpenFileEx(0x%08X, %s, %s, 0x%X, 0x%08X, 0x%08X, 0x%08X) failed: %s\n", + deviceData->clientHandle, file->fullPath, fsMode, translatedMode, openFlags, preAllocSize, &fd, + FSAGetStatusStr(status)); + } + r->_errno = __wut_fsa_translate_error(status); return -1; } - file = (__wut_fs_file_t *) fileStruct; file->fd = fd; file->flags = (flags & (O_ACCMODE | O_APPEND | O_SYNC)); // Is always 0, even if O_APPEND is set. file->offset = 0; + if (flags & O_APPEND) { - FSStat stat; - status = FSGetStatFile(__wut_devoptab_fs_client, &cmd, fd, &stat, FS_ERROR_FLAG_ALL); + FSAStat stat; + status = FSAGetStatFile(deviceData->clientHandle, fd, &stat); if (status < 0) { - FSCloseFile(__wut_devoptab_fs_client, &cmd, fd, FS_ERROR_FLAG_ALL); - r->_errno = __wut_fs_translate_error(status); + OSReport("FSAGetStatFile(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, fd, &stat, file->fullPath, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); + if (FSACloseFile(deviceData->clientHandle, fd) < 0) { + OSReport("FSACloseFile(0x%08X, 0x%08X) (%d) failed: %s\n", + deviceData->clientHandle, fd, file->fullPath, FSAGetStatusStr(status)); + } return -1; } file->appendOffset = stat.size; } - return 0; -} +} \ No newline at end of file diff --git a/libraries/wutdevoptab/devoptab_fsa_read.cpp b/libraries/wutdevoptab/devoptab_fsa_read.cpp index a14b61c7f..8bbf4c8d6 100644 --- a/libraries/wutdevoptab/devoptab_fsa_read.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_read.cpp @@ -1,15 +1,18 @@ #include "devoptab_fsa.h" - +#include #include -ssize_t __wut_fs_read(struct _reent *r, void *fd, char *ptr, size_t len) { +ssize_t __wut_fsa_read(struct _reent *r, void *fd, char *ptr, size_t len) { + FSError status; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; if (!fd || !ptr) { r->_errno = EINVAL; return -1; } // Check that the file was opened with read access - __wut_fs_file_t *file = (__wut_fs_file_t *) fd; + file = (__wut_fsa_file_t *) fd; if ((file->flags & O_ACCMODE) == O_WRONLY) { r->_errno = EBADF; return -1; @@ -18,8 +21,9 @@ ssize_t __wut_fs_read(struct _reent *r, void *fd, char *ptr, size_t len) { // cache-aligned, cache-line-sized __attribute__((aligned(0x40))) uint8_t alignedBuffer[0x40]; - FSCmdBlock cmd; - FSInitCmdBlock(&cmd); + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(file->mutex); size_t bytesRead = 0; while (bytesRead < len) { @@ -40,15 +44,21 @@ ssize_t __wut_fs_read(struct _reent *r, void *fd, char *ptr, size_t len) { size &= ~0x3F; } - FSStatus status = FSReadFile(__wut_devoptab_fs_client, &cmd, tmp, 1, size, - file->fd, 0, FS_ERROR_FLAG_ALL); + // Limit each request to 1 MiB + if (size > 0x100000) { + size = 0x100000; + } + + status = FSAReadFile(deviceData->clientHandle, tmp, 1, size, file->fd, 0); if (status < 0) { + OSReport("FSAReadFile(0x%08X, 0x%08X, 1, 0x%08X, 0x%08X, 0) (%s) failed: %s\n", + deviceData->clientHandle, tmp, size, file->fd, file->fullPath, FSAGetStatusStr(status)); if (bytesRead != 0) { return bytesRead; // error after partial read } - r->_errno = __wut_fs_translate_error(status); + r->_errno = __wut_fsa_translate_error(status); return -1; } @@ -60,7 +70,7 @@ ssize_t __wut_fs_read(struct _reent *r, void *fd, char *ptr, size_t len) { bytesRead += status; ptr += status; - if (status != size) { + if ((size_t) status != size) { return bytesRead; // partial read } } diff --git a/libraries/wutdevoptab/devoptab_fsa_rename.cpp b/libraries/wutdevoptab/devoptab_fsa_rename.cpp index 2b89f0373..b3ee1444a 100644 --- a/libraries/wutdevoptab/devoptab_fsa_rename.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_rename.cpp @@ -1,40 +1,43 @@ #include "devoptab_fsa.h" int -__wut_fs_rename(struct _reent *r, - const char *oldName, - const char *newName) -{ - FSStatus status; - FSCmdBlock cmd; +__wut_fsa_rename(struct _reent *r, + const char *oldName, + const char *newName) { + FSError status; char *fixedOldPath, *fixedNewPath; + __wut_fsa_device_t *deviceData; if (!oldName || !newName) { r->_errno = EINVAL; return -1; } - fixedOldPath = __wut_fs_fixpath(r, oldName); + fixedOldPath = __wut_fsa_fixpath(r, oldName); if (!fixedOldPath) { + r->_errno = ENOMEM; return -1; } - fixedNewPath = __wut_fs_fixpath(r, newName); + fixedNewPath = __wut_fsa_fixpath(r, newName); if (!fixedNewPath) { free(fixedOldPath); + r->_errno = ENOMEM; return -1; } - FSInitCmdBlock(&cmd); - status = FSRename(__wut_devoptab_fs_client, &cmd, fixedOldPath, fixedNewPath, - FS_ERROR_FLAG_ALL); - free(fixedOldPath); - free(fixedNewPath); + deviceData = (__wut_fsa_device_t *) r->deviceData; + status = FSARename(deviceData->clientHandle, fixedOldPath, fixedNewPath); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSARename(0x%08X, %s, %s) failed: %s\n", deviceData->clientHandle, fixedOldPath, fixedNewPath, FSAGetStatusStr(status)); + free(fixedOldPath); + free(fixedNewPath); + r->_errno = __wut_fsa_translate_error(status); return -1; } + free(fixedOldPath); + free(fixedNewPath); return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_rmdir.cpp b/libraries/wutdevoptab/devoptab_fsa_rmdir.cpp index 8200f0c67..13fecc4b2 100644 --- a/libraries/wutdevoptab/devoptab_fsa_rmdir.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_rmdir.cpp @@ -1,29 +1,33 @@ #include "devoptab_fsa.h" int -__wut_fs_rmdir(struct _reent *r, - const char *name) -{ - FSStatus status; - FSCmdBlock cmd; +__wut_fsa_rmdir(struct _reent *r, + const char *name) { + FSError status; + __wut_fsa_device_t *deviceData; if (!name) { r->_errno = EINVAL; return -1; } - char *fixedPath = __wut_fs_fixpath(r, name); + char *fixedPath = __wut_fsa_fixpath(r, name); if (!fixedPath) { + r->_errno = ENOMEM; return -1; } - FSInitCmdBlock(&cmd); - status = FSRemove(__wut_devoptab_fs_client, &cmd, fixedPath, FS_ERROR_FLAG_ALL); - free(fixedPath); + deviceData = (__wut_fsa_device_t *) r->deviceData; + + status = FSARemove(deviceData->clientHandle, fixedPath); if (status < 0) { - r->_errno = status == FS_STATUS_EXISTS ? ENOTEMPTY : __wut_fs_translate_error(status); + OSReport("FSARemove(0x%08X, %s) failed: %s\n", deviceData->clientHandle, fixedPath, FSAGetStatusStr(status)); + free(fixedPath); + r->_errno = status == FS_ERROR_ALREADY_EXISTS ? ENOTEMPTY : __wut_fsa_translate_error(status); return -1; } + free(fixedPath); + return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_seek.cpp b/libraries/wutdevoptab/devoptab_fsa_seek.cpp index 8e6b1bf73..75218e503 100644 --- a/libraries/wutdevoptab/devoptab_fsa_seek.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_seek.cpp @@ -1,55 +1,56 @@ #include "devoptab_fsa.h" +#include off_t -__wut_fs_seek(struct _reent *r, - void *fd, - off_t pos, - int whence) -{ - FSStatus status; - FSCmdBlock cmd; - FSStat fsStat; +__wut_fsa_seek(struct _reent *r, + void *fd, + off_t pos, + int whence) { + FSError status; + FSAStat fsStat; uint64_t offset; - __wut_fs_file_t *file; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; if (!fd) { r->_errno = EINVAL; return -1; } - FSInitCmdBlock(&cmd); - file = (__wut_fs_file_t *)fd; + file = (__wut_fsa_file_t *) fd; - // Find the offset to see from - switch(whence) { - // Set absolute position; start offset is 0 - case SEEK_SET: - offset = 0; - break; + deviceData = (__wut_fsa_device_t *) r->deviceData; - // Set position relative to the current position - case SEEK_CUR: - offset = file->offset; - break; + std::lock_guard lock(file->mutex); - // Set position relative to the end of the file - case SEEK_END: { - status = FSGetStatFile(__wut_devoptab_fs_client, &cmd, file->fd, &fsStat, - FS_ERROR_FLAG_ALL); - if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + // Find the offset to see from + switch (whence) { + case SEEK_SET: { // Set absolute position; start offset is 0 + offset = 0; + break; + } + case SEEK_CUR: { // Set position relative to the current position + offset = file->offset; + break; + } + case SEEK_END: { // Set position relative to the end of the file + status = FSAGetStatFile(deviceData->clientHandle, file->fd, &fsStat); + if (status < 0) { + OSReport("FSAGetStatFile(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, file->fd, &fsStat, file->fullPath, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); + return -1; + } + offset = fsStat.size; + break; + } + default: { // An invalid option was provided + r->_errno = EINVAL; return -1; } - offset = fsStat.size; - break; - } - // An invalid option was provided - default: - r->_errno = EINVAL; - return -1; } - if(pos < 0 && offset < -pos) { + if (pos < 0 && (off_t) offset < -pos) { // Don't allow seek to before the beginning of the file r->_errno = EINVAL; return -1; @@ -58,20 +59,20 @@ __wut_fs_seek(struct _reent *r, r->_errno = EINVAL; return -1; } - - if((uint32_t) (offset + pos) == file->offset) { + + if ((uint32_t) (offset + pos) == file->offset) { return file->offset; } - uint32_t old_offset = file->offset; + uint32_t old_pos = file->offset; file->offset = offset + pos; - status = FSSetPosFile(__wut_devoptab_fs_client, &cmd, file->fd, file->offset, - FS_ERROR_FLAG_ALL); + status = FSASetPosFile(deviceData->clientHandle, file->fd, file->offset); if (status < 0) { - // revert offset update on error. - file->offset = old_offset; - r->_errno = __wut_fs_translate_error(status); + OSReport("FSASetPosFile(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + deviceData->clientHandle, file->fd, file->offset, file->fullPath, FSAGetStatusStr(status)); + file->offset = old_pos; + r->_errno = __wut_fsa_translate_error(status); return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_stat.cpp b/libraries/wutdevoptab/devoptab_fsa_stat.cpp index 7b2a8dcb0..000cbc91d 100644 --- a/libraries/wutdevoptab/devoptab_fsa_stat.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_stat.cpp @@ -1,34 +1,38 @@ #include "devoptab_fsa.h" int -__wut_fs_stat(struct _reent *r, - const char *path, - struct stat *st) { - FSStatus status; - FSCmdBlock cmd; - FSStat fsStat; +__wut_fsa_stat(struct _reent *r, + const char *path, + struct stat *st) { + FSError status; + FSAStat fsStat; + __wut_fsa_device_t *deviceData; if (!path || !st) { r->_errno = EINVAL; return -1; } - char *fixedPath = __wut_fs_fixpath(r, path); + char *fixedPath = __wut_fsa_fixpath(r, path); if (!fixedPath) { + r->_errno = ENOMEM; return -1; } - FSInitCmdBlock(&cmd); + deviceData = (__wut_fsa_device_t *) r->deviceData; - status = FSGetStat(__wut_devoptab_fs_client, &cmd, fixedPath, &fsStat, FS_ERROR_FLAG_ALL); + status = FSAGetStat(deviceData->clientHandle, fixedPath, &fsStat); if (status < 0) { + if(status != FS_ERROR_NOT_FOUND) { + OSReport("FSAGetStat(0x%08X, %s, 0x%08X) failed: %s\n", + deviceData->clientHandle, fixedPath, &fsStat, FSAGetStatusStr(status)); + } free(fixedPath); - r->_errno = __wut_fs_translate_error(status); + r->_errno = __wut_fsa_translate_error(status); return -1; } free(fixedPath); - __wut_fs_translate_stat(&fsStat, st); - + __wut_fsa_translate_stat(&fsStat, st); return 0; } \ No newline at end of file diff --git a/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp b/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp index e2fb2dcf5..f333895cd 100644 --- a/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp @@ -1,11 +1,57 @@ #include "devoptab_fsa.h" int -__wut_fs_statvfs(struct _reent *r, - const char *path, - struct statvfs *buf) -{ - //TODO: FSGetFileSystemInfo - r->_errno = ENOSYS; - return -1; -} +__wut_fsa_statvfs(struct _reent *r, + const char *path, + struct statvfs *buf) { + FSError status; + uint64_t freeSpace; + __wut_fsa_device_t *deviceData; + + deviceData = (__wut_fsa_device_t *) r->deviceData; + if (deviceData->isSDCard) { + r->_errno = ENOSYS; + return -1; + } + + + memset(buf, 0, sizeof(struct statvfs)); + + char *fixedPath = __wut_fsa_fixpath(r, path); + if (!fixedPath) { + r->_errno = ENOMEM; + return -1; + } + + + status = FSAGetFreeSpaceSize(deviceData->clientHandle, fixedPath, &freeSpace); + if (status < 0) { + OSReport("FSAGetFreeSpaceSize(0x%08X, %s, 0x%08X) failed: %s\n", + deviceData->clientHandle, fixedPath, &freeSpace, FSAGetStatusStr(status)); + free(fixedPath); + r->_errno = __wut_fsa_translate_error(status); + return -1; + } + free(fixedPath); + + // File system block size + buf->f_bsize = deviceData->deviceSectorSize; + // Fundamental file system block size + buf->f_frsize = deviceData->deviceSectorSize; + // Total number of blocks on file system in units of f_frsize + buf->f_blocks = deviceData->deviceSizeInSectors; + // Free blocks available for all and for non-privileged processes + buf->f_bfree = buf->f_bavail = (uint32_t) (freeSpace / buf->f_frsize); + // Number of inodes at this point in time + buf->f_files = 0xFFFFFFFF; + // Free inodes available for all and for non-privileged processes + buf->f_ffree = 0xFFFFFFFF; + // File system id + buf->f_fsid = (unsigned long) deviceData->clientHandle; + // Bit mask of f_flag values. + buf->f_flag = 0; + // Maximum length of filenames + buf->f_namemax = 255; + + return 0; +} \ No newline at end of file diff --git a/libraries/wutdevoptab/devoptab_fsa_truncate.cpp b/libraries/wutdevoptab/devoptab_fsa_truncate.cpp index 13ca9fb24..f84812b30 100644 --- a/libraries/wutdevoptab/devoptab_fsa_truncate.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_truncate.cpp @@ -1,13 +1,13 @@ #include "devoptab_fsa.h" +#include int -__wut_fs_ftruncate(struct _reent *r, - void *fd, - off_t len) -{ - FSStatus status; - FSCmdBlock cmd; - __wut_fs_file_t *file; +__wut_fsa_ftruncate(struct _reent *r, + void *fd, + off_t len) { + FSError status; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; // Make sure length is non-negative if (!fd || len < 0) { @@ -15,18 +15,24 @@ __wut_fs_ftruncate(struct _reent *r, return -1; } + file = (__wut_fsa_file_t *) fd; + + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(file->mutex); + // Set the new file size - FSInitCmdBlock(&cmd); - file = (__wut_fs_file_t *)fd; - status = FSSetPosFile(__wut_devoptab_fs_client, &cmd, file->fd, len, FS_ERROR_FLAG_ALL); + status = FSASetPosFile(deviceData->clientHandle, file->fd, len); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSASetPosFile(0x%08X, 0x%08X, 0x%08X) failed: %s\n", deviceData->clientHandle, file->fd, len, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } - status = FSTruncateFile(__wut_devoptab_fs_client, &cmd, file->fd, FS_ERROR_FLAG_ALL); + status = FSATruncateFile(deviceData->clientHandle, file->fd); if (status < 0) { - r->_errno = __wut_fs_translate_error(status); + OSReport("FSATruncateFile(0x%08X, 0x%08X) failed: %s\n", deviceData->clientHandle, file->fd, FSAGetStatusStr(status)); + r->_errno = __wut_fsa_translate_error(status); return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_unlink.cpp b/libraries/wutdevoptab/devoptab_fsa_unlink.cpp index e5f6b6fd4..c94a88890 100644 --- a/libraries/wutdevoptab/devoptab_fsa_unlink.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_unlink.cpp @@ -1,30 +1,33 @@ #include "devoptab_fsa.h" int -__wut_fs_unlink(struct _reent *r, - const char *name) -{ - FSStatus status; - FSCmdBlock cmd; +__wut_fsa_unlink(struct _reent *r, + const char *name) { + FSError status; char *fixedPath; + __wut_fsa_device_t *deviceData; if (!name) { r->_errno = EINVAL; return -1; } - fixedPath = __wut_fs_fixpath(r, name); + fixedPath = __wut_fsa_fixpath(r, name); if (!fixedPath) { + r->_errno = ENOMEM; return -1; } + deviceData = (__wut_fsa_device_t *) r->deviceData; - FSInitCmdBlock(&cmd); - status = FSRemove(__wut_devoptab_fs_client, &cmd, fixedPath, FS_ERROR_FLAG_ALL); - free(fixedPath); + status = FSARemove(deviceData->clientHandle, fixedPath); if (status < 0) { - r->_errno = status == FS_STATUS_EXISTS ? EISDIR : __wut_fs_translate_error(status); + OSReport("FSARemove(0x%08X, %s) failed: %s\n", deviceData->clientHandle, fixedPath, FSAGetStatusStr(status)); + free(fixedPath); + r->_errno = __wut_fsa_translate_error(status); return -1; } + free(fixedPath); + return 0; } diff --git a/libraries/wutdevoptab/devoptab_fsa_utils.cpp b/libraries/wutdevoptab/devoptab_fsa_utils.cpp index bacc51665..774bd0ddc 100644 --- a/libraries/wutdevoptab/devoptab_fsa_utils.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_utils.cpp @@ -2,7 +2,7 @@ #include "../wutnewlib/wut_clock.h" char * -__wut_fs_fixpath(struct _reent *r, +__wut_fsa_fixpath(struct _reent *r, const char *path) { char *p; char *fixedPath; @@ -29,7 +29,7 @@ __wut_fs_fixpath(struct _reent *r, return NULL; } - fixedPath = memalign(0x40, FS_MAX_PATH + 1); + fixedPath = static_cast(memalign(0x40, FS_MAX_PATH + 1)); if (!fixedPath) { r->_errno = ENOMEM; return NULL; @@ -40,7 +40,7 @@ __wut_fs_fixpath(struct _reent *r, return fixedPath; } -mode_t __wut_fs_translate_stat_mode(FSStat* fsStat) { +mode_t __wut_fsa_translate_stat_mode(FSStat* fsStat) { mode_t retMode = 0; if ((fsStat->flags & FS_STAT_LINK) == FS_STAT_LINK) { @@ -64,69 +64,111 @@ mode_t __wut_fs_translate_stat_mode(FSStat* fsStat) { return retMode | permissionMode; } -FSMode __wut_fs_translate_permission_mode(mode_t mode) { +FSMode __wut_fsa_translate_permission_mode(mode_t mode) { // Convert normal Unix octal permission bits into CafeOS hexadecimal permission bits return (FSMode) (((mode & S_IRWXU) << 2) | ((mode & S_IRWXG) << 1) | (mode & S_IRWXO)); } -time_t __wut_fs_translate_time(FSTime timeValue) { +time_t __wut_fsa_translate_time(FSTime timeValue) { return (timeValue /1000000) + EPOCH_DIFF_SECS(WIIU_FSTIME_EPOCH_YEAR); } -void __wut_fs_translate_stat(FSStat* fsStat, struct stat* posStat) { +void __wut_fsa_translate_stat(FSStat* fsStat, struct stat* posStat) { memset(posStat, 0, sizeof(struct stat)); - posStat->st_dev = (dev_t)__wut_devoptab_fs_client; + posStat->st_dev = (dev_t) nullptr; posStat->st_ino = fsStat->entryId; - posStat->st_mode = __wut_fs_translate_stat_mode(fsStat); + posStat->st_mode = __wut_fsa_translate_stat_mode(fsStat); posStat->st_nlink = 1; posStat->st_uid = fsStat->owner; posStat->st_gid = fsStat->group; posStat->st_rdev = posStat->st_dev; posStat->st_size = fsStat->size; - posStat->st_atime = __wut_fs_translate_time(fsStat->modified); - posStat->st_ctime = __wut_fs_translate_time(fsStat->created); - posStat->st_mtime = __wut_fs_translate_time(fsStat->modified); + posStat->st_atime = __wut_fsa_translate_time(fsStat->modified); + posStat->st_ctime = __wut_fsa_translate_time(fsStat->created); + posStat->st_mtime = __wut_fsa_translate_time(fsStat->modified); posStat->st_blksize = 512; posStat->st_blocks = (posStat->st_size + posStat->st_blksize - 1) / posStat->st_size; } -int -__wut_fs_translate_error(FSStatus error) { - switch ((int) error) { - case FS_STATUS_END: - return ENOENT; - case FS_STATUS_CANCELLED: - return ECANCELED; - case FS_STATUS_EXISTS: - return EEXIST; - case FS_STATUS_MEDIA_ERROR: - return EIO; - case FS_STATUS_NOT_FOUND: - return ENOENT; - case FS_STATUS_PERMISSION_ERROR: - return EPERM; - case FS_STATUS_STORAGE_FULL: - return ENOSPC; - case FS_STATUS_FILE_TOO_BIG: - return EFBIG; - case FS_STATUS_NOT_DIR: - return ENOTDIR; - case FS_STATUS_NOT_FILE: - return EISDIR; - case FS_STATUS_MAX: - return ENFILE; - case FS_STATUS_ACCESS_ERROR: - return EACCES; - case FS_STATUS_JOURNAL_FULL: - return ENOSPC; - case FS_STATUS_UNSUPPORTED_CMD: - return ENOTSUP; - case FS_STATUS_MEDIA_NOT_READY: - return EOWNERDEAD; - case FS_STATUS_ALREADY_OPEN: - case FS_STATUS_CORRUPTED: - case FS_STATUS_FATAL_ERROR: - return EIO; - } - return (int) error; + +int __wut_fsa_translate_error(FSError error) { + switch (error) { + case FS_ERROR_END_OF_DIR: + case FS_ERROR_END_OF_FILE: + return ENOENT; + case FS_ERROR_ALREADY_EXISTS: + return EEXIST; + case FS_ERROR_MEDIA_ERROR: + return EIO; + case FS_ERROR_NOT_FOUND: + return ENOENT; + case FS_ERROR_PERMISSION_ERROR: + return EPERM; + case FS_ERROR_STORAGE_FULL: + return ENOSPC; + case FS_ERROR_BUSY: + return EBUSY; + case FS_ERROR_CANCELLED: + return ECANCELED; + case FS_ERROR_FILE_TOO_BIG: + return EFBIG; + case FS_ERROR_INVALID_PATH: + return ENAMETOOLONG; + case FS_ERROR_NOT_DIR: + return ENOTDIR; + case FS_ERROR_NOT_FILE: + return EISDIR; + case FS_ERROR_OUT_OF_RANGE: + return ESPIPE; + case FS_ERROR_UNSUPPORTED_COMMAND: + return ENOTSUP; + case FS_ERROR_WRITE_PROTECTED: + return EROFS; + case FS_ERROR_NOT_INIT: + return ENODEV; + // TODO + case FS_ERROR_MAX_MOUNT_POINTS: + break; + case FS_ERROR_MAX_VOLUMES: + break; + case FS_ERROR_MAX_CLIENTS: + break; + case FS_ERROR_MAX_FILES: + break; + case FS_ERROR_MAX_DIRS: + break; + case FS_ERROR_ALREADY_OPEN: + break; + case FS_ERROR_NOT_EMPTY: + break; + case FS_ERROR_ACCESS_ERROR: + break; + case FS_ERROR_DATA_CORRUPTED: + break; + case FS_ERROR_JOURNAL_FULL: + break; + case FS_ERROR_UNAVAILABLE_COMMAND: + break; + case FS_ERROR_INVALID_PARAM: + break; + case FS_ERROR_INVALID_BUFFER: + break; + case FS_ERROR_INVALID_ALIGNMENT: + break; + case FS_ERROR_INVALID_CLIENTHANDLE: + break; + case FS_ERROR_INVALID_FILEHANDLE: + break; + case FS_ERROR_INVALID_DIRHANDLE: + break; + case FS_ERROR_OUT_OF_RESOURCES: + break; + case FS_ERROR_MEDIA_NOT_READY: + break; + case FS_ERROR_INVALID_MEDIA: + break; + default: + break; + } + return (int) EIO; } diff --git a/libraries/wutdevoptab/devoptab_fsa_utimes.cpp b/libraries/wutdevoptab/devoptab_fsa_utimes.cpp index 2f07f5eac..9d0a727db 100644 --- a/libraries/wutdevoptab/devoptab_fsa_utimes.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_utimes.cpp @@ -1,10 +1,9 @@ #include "devoptab_fsa.h" int -__wut_fs_utimes(struct _reent *r, - const char *filename, - const struct timeval times[2]) -{ +__wut_fsa_utimes(struct _reent *r, + const char *filename, + const struct timeval times[2]) { r->_errno = ENOSYS; return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_write.cpp b/libraries/wutdevoptab/devoptab_fsa_write.cpp index e9b18fce5..b08a8726c 100644 --- a/libraries/wutdevoptab/devoptab_fsa_write.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_write.cpp @@ -1,13 +1,18 @@ #include "devoptab_fsa.h" +#include + +ssize_t __wut_fsa_write(struct _reent *r, void *fd, const char *ptr, size_t len) { + FSError status; + __wut_fsa_file_t *file; + __wut_fsa_device_t *deviceData; -ssize_t __wut_fs_write(struct _reent *r, void *fd, const char *ptr, size_t len) { if (!fd || !ptr) { r->_errno = EINVAL; return -1; } // Check that the file was opened with write access - __wut_fs_file_t *file = (__wut_fs_file_t *) fd; + file = (__wut_fsa_file_t *) fd; if ((file->flags & O_ACCMODE) == O_RDONLY) { r->_errno = EBADF; return -1; @@ -16,8 +21,9 @@ ssize_t __wut_fs_write(struct _reent *r, void *fd, const char *ptr, size_t len) // cache-aligned, cache-line-sized __attribute__((aligned(0x40))) uint8_t alignedBuffer[0x40]; - FSCmdBlock cmd; - FSInitCmdBlock(&cmd); + deviceData = (__wut_fsa_device_t *) r->deviceData; + + std::lock_guard lock(file->mutex); // If O_APPEND is set, we always write to the end of the file. // When writing we file->offset to the file size to keep in sync. @@ -44,18 +50,24 @@ ssize_t __wut_fs_write(struct _reent *r, void *fd, const char *ptr, size_t len) size &= ~0x3F; } + // Limit each request to 256 KiB + if (size > 0x40000) { + size = 0x40000; + } + if (tmp == alignedBuffer) { memcpy(tmp, ptr, size); } - FSStatus status = FSWriteFile(__wut_devoptab_fs_client, &cmd, tmp, 1, size, - file->fd, 0, FS_ERROR_FLAG_ALL); + status = FSAWriteFile(deviceData->clientHandle, tmp, 1, size, file->fd, 0); if (status < 0) { + OSReport("FSAWriteFile(0x%08X, 0x%08X, 1, 0x%08X, 0x%08X, 0) (%s) failed: %s\n", + deviceData->clientHandle, tmp, size, file->fd, file->fullPath, FSAGetStatusStr(status)); if (bytesWritten != 0) { return bytesWritten; // error after partial write } - r->_errno = __wut_fs_translate_error(status); + r->_errno = __wut_fsa_translate_error(status); return -1; } @@ -64,7 +76,7 @@ ssize_t __wut_fs_write(struct _reent *r, void *fd, const char *ptr, size_t len) bytesWritten += status; ptr += status; - if (status != size) { + if ((size_t) status != size) { return bytesWritten; // partial write } }