mirror of
https://github.com/devkitPro/wut.git
synced 2026-04-26 01:48:30 -05:00
wutdevoptab: Add support for more open() flags (and flag combinations)
This commit is contained in:
parent
42292fadc6
commit
733d5000fc
|
|
@ -8,8 +8,7 @@ __wut_fs_open(struct _reent *r,
|
||||||
void *fileStruct,
|
void *fileStruct,
|
||||||
const char *path,
|
const char *path,
|
||||||
int flags,
|
int flags,
|
||||||
int mode)
|
int mode) {
|
||||||
{
|
|
||||||
FSFileHandle fd;
|
FSFileHandle fd;
|
||||||
FSStatus status;
|
FSStatus status;
|
||||||
FSCmdBlock cmd;
|
FSCmdBlock cmd;
|
||||||
|
|
@ -21,6 +20,8 @@ __wut_fs_open(struct _reent *r,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool createFileIfNotFound = false;
|
||||||
|
bool failIfFileNotFound = false;
|
||||||
// Map flags to open modes
|
// Map flags to open modes
|
||||||
int commonFlagMask = O_CREAT | O_TRUNC | O_APPEND;
|
int commonFlagMask = O_CREAT | O_TRUNC | O_APPEND;
|
||||||
if (((flags & O_ACCMODE) == O_RDONLY) && !(flags & commonFlagMask)) {
|
if (((flags & O_ACCMODE) == O_RDONLY) && !(flags & commonFlagMask)) {
|
||||||
|
|
@ -35,6 +36,20 @@ __wut_fs_open(struct _reent *r,
|
||||||
fsMode = "a";
|
fsMode = "a";
|
||||||
} else if (((flags & O_ACCMODE) == O_RDWR) && ((flags & commonFlagMask) == (O_CREAT | O_APPEND))) {
|
} else if (((flags & O_ACCMODE) == O_RDWR) && ((flags & commonFlagMask) == (O_CREAT | O_APPEND))) {
|
||||||
fsMode = "a+";
|
fsMode = "a+";
|
||||||
|
} else if (((flags & O_ACCMODE) == O_WRONLY) && ((flags & commonFlagMask) == (O_CREAT))) {
|
||||||
|
// Cafe OS doesn't have a matching mode for this, so we have to be creative and create the file.
|
||||||
|
createFileIfNotFound = true;
|
||||||
|
// It's not possible to open a file with write only mode which doesn't truncate the file
|
||||||
|
// Technically we could read from the file, but our read implementation is blocking this.
|
||||||
|
fsMode = "r+";
|
||||||
|
} else if (((flags & O_ACCMODE) == O_WRONLY) && ((flags & commonFlagMask) == (O_APPEND))) {
|
||||||
|
// Cafe OS doesn't have a matching mode for this, so we have to check if the file exists.
|
||||||
|
failIfFileNotFound = true;
|
||||||
|
fsMode = "a";
|
||||||
|
} else if (((flags & O_ACCMODE) == O_WRONLY) && ((flags & commonFlagMask) == (O_TRUNC))) {
|
||||||
|
// As above
|
||||||
|
failIfFileNotFound = true;
|
||||||
|
fsMode = "w";
|
||||||
} else {
|
} else {
|
||||||
r->_errno = EINVAL;
|
r->_errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -49,16 +64,47 @@ __wut_fs_open(struct _reent *r,
|
||||||
FSInitCmdBlock(&cmd);
|
FSInitCmdBlock(&cmd);
|
||||||
FSOpenFileFlags openFlags = (flags & O_UNENCRYPTED) ? FS_OPEN_FLAG_UNENCRYPTED : FS_OPEN_FLAG_NONE;
|
FSOpenFileFlags openFlags = (flags & O_UNENCRYPTED) ? FS_OPEN_FLAG_UNENCRYPTED : FS_OPEN_FLAG_NONE;
|
||||||
uint32_t preallocSize = 0;
|
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);
|
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
fd = -1;
|
||||||
|
} else {
|
||||||
|
free(fixedPath);
|
||||||
|
r->_errno = __wut_fs_translate_error(status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (failIfFileNotFound) { // Return an error if we don't we create new files
|
||||||
|
r->_errno = __wut_fs_translate_error(status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (status == FS_STATUS_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)) {
|
||||||
|
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);
|
free(fixedPath);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
r->_errno = __wut_fs_translate_error(status);
|
r->_errno = __wut_fs_translate_error(status);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = (__wut_fs_file_t *)fileStruct;
|
file = (__wut_fs_file_t *) fileStruct;
|
||||||
file->fd = fd;
|
file->fd = fd;
|
||||||
file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC));
|
file->flags = (flags & (O_ACCMODE | O_APPEND | O_SYNC));
|
||||||
// Is always 0, even if O_APPEND is set.
|
// Is always 0, even if O_APPEND is set.
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
if (flags & O_APPEND) {
|
if (flags & O_APPEND) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user