mirror of
https://github.com/devkitPro/wut.git
synced 2026-08-09 11:17:56 -05:00
- Improved error codes for unlink and rmdir regarding non-empty directories. - Return ENOENT on empty strings since it softlocks the Wii U. Since the devoptab relies on the cwd it's pretty easy to run into with stuff like recursive path creation for example. - Clean up open_r mode_t->string conversion - Improved FSStat->mode_t conversion - Add FSOpenFileEx and flags
73 lines
2.3 KiB
C
73 lines
2.3 KiB
C
#include "devoptab_fs.h"
|
|
|
|
// Extended "magic" value that allows opening files with FS_OPEN_FLAG_UNENCRYPTED in underlying FSOpenFileEx() call similar to O_DIRECTORY
|
|
#define O_UNENCRYPTED 0x4000000
|
|
|
|
int
|
|
__wut_fs_open(struct _reent *r,
|
|
void *fileStruct,
|
|
const char *path,
|
|
int flags,
|
|
int mode)
|
|
{
|
|
FSFileHandle fd;
|
|
FSStatus status;
|
|
FSCmdBlock cmd;
|
|
const char *fsMode;
|
|
__wut_fs_file_t *file;
|
|
|
|
if (!fileStruct || !path) {
|
|
r->_errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
// Map flags to open modes
|
|
int commonFlagMask = O_CREAT | O_TRUNC | O_APPEND;
|
|
if (((flags & O_ACCMODE) == O_RDONLY) && !(flags & commonFlagMask)) {
|
|
fsMode = "r";
|
|
} else if (((flags & O_ACCMODE) == O_RDWR) && !(flags & commonFlagMask)) {
|
|
fsMode = "r+";
|
|
} else if (((flags & O_ACCMODE) == O_WRONLY) && ((flags & commonFlagMask) == (O_CREAT | O_TRUNC))) {
|
|
fsMode = "w";
|
|
} else if (((flags & O_ACCMODE) == O_RDWR) && ((flags & commonFlagMask) == (O_CREAT | O_TRUNC))) {
|
|
fsMode = "w+";
|
|
} else if (((flags & O_ACCMODE) == O_WRONLY) && ((flags & commonFlagMask) == (O_CREAT | O_APPEND))) {
|
|
fsMode = "a";
|
|
} else if (((flags & O_ACCMODE) == O_RDWR) && ((flags & commonFlagMask) == (O_CREAT | O_APPEND))) {
|
|
fsMode = "a+";
|
|
} else {
|
|
r->_errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
char *fixedPath = __wut_fs_fixpath(r, path);
|
|
if (!fixedPath) {
|
|
return -1;
|
|
}
|
|
|
|
// Open the file
|
|
FSInitCmdBlock(&cmd);
|
|
FSOpenFileFlags openFlags = (mode & O_UNENCRYPTED) ? FS_OPEN_FLAG_UNENCRYPTED : FS_OPEN_FLAG_NONE;
|
|
uint32_t preallocSize = 0;
|
|
status = FSOpenFileEx(__wut_devoptab_fs_client, &cmd, fixedPath, fsMode, __wut_fs_translate_permission_mode(mode), openFlags, preallocSize, &fd, FS_ERROR_FLAG_ALL);
|
|
free(fixedPath);
|
|
if (status < 0) {
|
|
r->_errno = __wut_fs_translate_error(status);
|
|
return -1;
|
|
}
|
|
|
|
file = (__wut_fs_file_t *)fileStruct;
|
|
file->fd = fd;
|
|
file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC));
|
|
if (flags & O_APPEND) {
|
|
status = FSGetPosFile(__wut_devoptab_fs_client, &cmd, fd, &file->offset, FS_ERROR_FLAG_ALL);
|
|
if (status < 0) {
|
|
FSCloseFile(__wut_devoptab_fs_client, &cmd, fd, FS_ERROR_FLAG_ALL);
|
|
r->_errno = __wut_fs_translate_error(status);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|