Make the devoptab code more consistent.

This commit is contained in:
James Benton 2018-10-06 10:41:24 +01:00
parent 63119deb63
commit 069e28acec
22 changed files with 427 additions and 430 deletions

View File

@ -2,32 +2,28 @@
int int
__wut_fs_chdir(struct _reent *r, __wut_fs_chdir(struct _reent *r,
const char *name) const char *path)
{ {
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
if (name == NULL) {
return -1;
}
char *path = __wut_fs_fixpath(r, name);
if (!path) { if (!path) {
r->_errno = ENOMEM; r->_errno = EINVAL;
return -1; return -1;
} }
// Set up command block char *fixedPath = __wut_fs_fixpath(r, path);
FSCmdBlock fsCmd; if (!fixedPath) {
FSInitCmdBlock(&fsCmd); return -1;
rc = FSChangeDir(__wut_devoptab_fs_client, &fsCmd, path, -1);
free(path);
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); FSInitCmdBlock(&cmd);
return -1; status = FSChangeDir(__wut_devoptab_fs_client, &cmd, fixedPath, -1);
free(fixedPath);
if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
} }

View File

@ -5,25 +5,27 @@ __wut_fs_chmod(struct _reent *r,
const char *path, const char *path,
mode_t mode) mode_t mode)
{ {
FSStatus rc; FSStatus status;
char *path_fix = __wut_fs_fixpath(r, path); FSCmdBlock cmd;
if (!path_fix) { if (!path) {
r->_errno = ENOMEM; r->_errno = EINVAL;
return -1; return -1;
} }
// Set up command block char *fixedPath = __wut_fs_fixpath(r, path);
FSCmdBlock fsCmd; if (!fixedPath) {
FSInitCmdBlock(&fsCmd); return -1;
rc = FSChangeMode(__wut_devoptab_fs_client, &fsCmd, path_fix, (FSMode)mode, -1);
free(path_fix);
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); FSInitCmdBlock(&cmd);
return -1; status = FSChangeMode(__wut_devoptab_fs_client, &cmd, fixedPath,
(FSMode)mode, -1);
free(fixedPath);
if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
} }

View File

@ -4,19 +4,22 @@ int
__wut_fs_close(struct _reent *r, __wut_fs_close(struct _reent *r,
void *fd) void *fd)
{ {
FSStatus rc; FSStatus status;
__wut_fs_file_t *file = (__wut_fs_file_t *)fd; FSCmdBlock cmd;
__wut_fs_file_t *file;
// Set up command block if (!fd) {
FSCmdBlock fsCmd; r->_errno = EINVAL;
FSInitCmdBlock(&fsCmd); return -1;
rc = FSCloseFile(__wut_devoptab_fs_client, &fsCmd, file->fd, -1);
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); FSInitCmdBlock(&cmd);
return -1; file = (__wut_fs_file_t *)fd;
status = FSCloseFile(__wut_devoptab_fs_client, &cmd, file->fd, -1);
if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
} }

View File

@ -4,19 +4,22 @@ int
__wut_fs_dirclose(struct _reent *r, __wut_fs_dirclose(struct _reent *r,
DIR_ITER *dirState) DIR_ITER *dirState)
{ {
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
__wut_fs_dir_t *dir;
// Set up command block if (!dirState) {
FSCmdBlock fsCmd; r->_errno = EINVAL;
FSInitCmdBlock(&fsCmd); return -1;
__wut_fs_dir_t *dir = (__wut_fs_dir_t *)(dirState->dirStruct);
rc = FSCloseDir(__wut_devoptab_fs_client, &fsCmd, dir->fd, -1);
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); FSInitCmdBlock(&cmd);
return -1; dir = (__wut_fs_dir_t *)(dirState->dirStruct);
status = FSCloseDir(__wut_devoptab_fs_client, &cmd, dir->fd, -1);
if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
} }

View File

@ -6,44 +6,40 @@ __wut_fs_dirnext(struct _reent *r,
char *filename, char *filename,
struct stat *filestat) struct stat *filestat)
{ {
FSStatus rc; FSStatus status;
__wut_fs_dir_t *dir = (__wut_fs_dir_t *)(dirState->dirStruct); FSCmdBlock cmd;
__wut_fs_dir_t *dir;
// Set up command block if (!dirState || !filename || !filestat) {
FSCmdBlock fsCmd; r->_errno = EINVAL;
FSInitCmdBlock(&fsCmd);
// Fetch the next dir
memset(&dir->entry_data, 0, sizeof(dir->entry_data));
rc = FSReadDir(__wut_devoptab_fs_client, &fsCmd, dir->fd, &dir->entry_data, -1);
if (rc < 0) {
// There are no more entries; ENOENT signals end-of-directory
r->_errno = ENOENT;
return -1; return -1;
} }
if (rc >= 0) { FSInitCmdBlock(&cmd);
memset(filestat, 0, sizeof(struct stat)); dir = (__wut_fs_dir_t *)(dirState->dirStruct);
memset(&dir->entry_data, 0, sizeof(dir->entry_data));
// Fill in the stat info status = FSReadDir(__wut_devoptab_fs_client, &cmd, dir->fd, &dir->entry_data,
filestat->st_ino = 0; -1);
if (status < 0) {
if (dir->entry_data.info.flags & FS_STAT_DIRECTORY) { r->_errno = __wut_fs_translate_error(status);
filestat->st_mode = S_IFDIR; return -1;
} else {
filestat->st_mode = S_IFREG;
}
filestat->st_uid = dir->entry_data.info.owner;
filestat->st_gid = dir->entry_data.info.group;
filestat->st_size = dir->entry_data.info.size;
memset(filename, 0, NAME_MAX);
strcpy(filename, dir->entry_data.name);
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); // Fill in the stat info
return -1; memset(filestat, 0, sizeof(struct stat));
filestat->st_ino = 0;
if (dir->entry_data.info.flags & FS_STAT_DIRECTORY) {
filestat->st_mode = S_IFDIR;
} else {
filestat->st_mode = S_IFREG;
}
filestat->st_uid = dir->entry_data.info.owner;
filestat->st_gid = dir->entry_data.info.group;
filestat->st_size = dir->entry_data.info.size;
memset(filename, 0, NAME_MAX);
strcpy(filename, dir->entry_data.name);
return 0;
} }

View File

@ -6,35 +6,31 @@ __wut_fs_diropen(struct _reent *r,
const char *path) const char *path)
{ {
FSDirectoryHandle fd; FSDirectoryHandle fd;
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
__wut_fs_dir_t *dir;
if (path == NULL) { if (!dirState || !path) {
r->_errno = EINVAL;
return NULL; return NULL;
} }
char *path_fixed = __wut_fs_fixpath(r,path); char *fixedPath = __wut_fs_fixpath(r, path);
if (!fixedPath) {
if (!path_fixed) {
r->_errno = ENOMEM;
return NULL; return NULL;
} }
// Set up command block FSInitCmdBlock(&cmd);
FSCmdBlock fsCmd; dir = (__wut_fs_dir_t *)(dirState->dirStruct);
FSInitCmdBlock(&fsCmd); status = FSOpenDir(__wut_devoptab_fs_client, &cmd, fixedPath, &fd, -1);
free(fixedPath);
__wut_fs_dir_t *dir = (__wut_fs_dir_t *)(dirState->dirStruct); if (status < 0) {
rc = FSOpenDir(__wut_devoptab_fs_client, &fsCmd, path_fixed, &fd, -1); r->_errno = __wut_fs_translate_error(status);
return NULL;
if (rc >= 0) {
dir->magic = FS_DIRITER_MAGIC;
dir->fd = fd;
memset(&dir->entry_data, 0, sizeof(dir->entry_data));
free(path_fixed);
return dirState;
} }
free(path_fixed); dir->magic = FS_DIRITER_MAGIC;
r->_errno = __wut_fs_translate_error(rc); dir->fd = fd;
return NULL; memset(&dir->entry_data, 0, sizeof(dir->entry_data));
return dirState;
} }

View File

@ -4,20 +4,22 @@ int
__wut_fs_dirreset(struct _reent *r, __wut_fs_dirreset(struct _reent *r,
DIR_ITER *dirState) DIR_ITER *dirState)
{ {
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
__wut_fs_dir_t *dir;
// Set up command block if (!dirState) {
FSCmdBlock fsCmd; r->_errno = EINVAL;
FSInitCmdBlock(&fsCmd); return -1;
__wut_fs_dir_t *dir = (__wut_fs_dir_t *)(dirState->dirStruct);
rc = FSRewindDir(__wut_devoptab_fs_client, &fsCmd, dir->fd, -1);
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); FSInitCmdBlock(&cmd);
return -1; dir = (__wut_fs_dir_t *)(dirState->dirStruct);
} status = FSRewindDir(__wut_devoptab_fs_client, &cmd, dir->fd, -1);
if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
}

View File

@ -5,7 +5,7 @@ __wut_fs_fchmod(struct _reent *r,
void *fd, void *fd,
mode_t mode) mode_t mode)
{ {
//TODO: FSChangeMode and FSStatFile? // TODO: FSChangeMode and FSStatFile?
r->_errno = ENOSYS; r->_errno = ENOSYS;
return -1; return -1;
} }

View File

@ -5,26 +5,30 @@ __wut_fs_fstat(struct _reent *r,
void *fd, void *fd,
struct stat *st) struct stat *st)
{ {
FSStatus rc; FSStatus status;
FSStat fsstat; FSStat fsStat;
__wut_fs_file_t *file = (__wut_fs_file_t *)fd; FSCmdBlock cmd;
__wut_fs_file_t *file;
// Set up command block if (!fd || !st) {
FSCmdBlock fsCmd; r->_errno = EINVAL;
FSInitCmdBlock(&fsCmd); return -1;
rc = FSGetStatFile(__wut_devoptab_fs_client, &fsCmd, file->fd, &fsstat, -1);
if (rc >= 0) {
memset(st, 0, sizeof(struct stat));
st->st_size = fsstat.size;
st->st_uid = fsstat.owner;
st->st_gid = fsstat.group;
st->st_nlink = 1;
st->st_mode = fsstat.mode;
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); FSInitCmdBlock(&cmd);
return -1; file = (__wut_fs_file_t *)fd;
status = FSGetStatFile(__wut_devoptab_fs_client, &cmd, file->fd, &fsStat,
-1);
if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
}
memset(st, 0, sizeof(struct stat));
st->st_size = fsStat.size;
st->st_uid = fsStat.owner;
st->st_gid = fsStat.group;
st->st_nlink = 1;
st->st_mode = fsStat.mode;
return 0;
} }

View File

@ -4,19 +4,22 @@ int
__wut_fs_fsync(struct _reent *r, __wut_fs_fsync(struct _reent *r,
void *fd) void *fd)
{ {
FSStatus rc; FSStatus status;
__wut_fs_file_t *file = (__wut_fs_file_t *)fd; FSCmdBlock cmd;
__wut_fs_file_t *file;
// Set up command block if (!fd) {
FSCmdBlock fsCmd; r->_errno = EINVAL;
FSInitCmdBlock(&fsCmd); return -1;
rc = FSFlushFile(__wut_devoptab_fs_client, &fsCmd, file->fd, -1);
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); FSInitCmdBlock(&cmd);
return -1; file = (__wut_fs_file_t *)fd;
status = FSFlushFile(__wut_devoptab_fs_client, &cmd, file->fd, -1);
if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
} }

View File

@ -5,34 +5,28 @@ __wut_fs_mkdir(struct _reent *r,
const char *path, const char *path,
int mode) int mode)
{ {
FSError rc; FSError status;
FSCmdBlock cmd;
char *fixedPath;
if (path == NULL) { if (!path) {
r->_errno = EINVAL;
return -1; return -1;
} }
char *path_fix = __wut_fs_fixpath(r, path); fixedPath = __wut_fs_fixpath(r, path);
if (!fixedPath) {
if (!path_fix) {
r->_errno = ENOMEM;
return -1; return -1;
} }
// Set up command block
FSCmdBlock fsCmd;
FSInitCmdBlock(&fsCmd);
// TODO: Use mode to set directory attributes. // TODO: Use mode to set directory attributes.
rc = FSMakeDir(__wut_devoptab_fs_client, &fsCmd, path_fix, -1); FSInitCmdBlock(&cmd);
free(path_fix); status = FSMakeDir(__wut_devoptab_fs_client, &cmd, fixedPath, -1);
free(fixedPath);
if (rc == FS_ERROR_ALREADY_EXISTS) { if (status < 0) {
r->_errno = EEXIST; r->_errno = __wut_fs_translate_error(status);
return -1; return -1;
} else if(rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); return 0;
return -1;
} }

View File

@ -8,57 +8,52 @@ __wut_fs_open(struct _reent *r,
int mode) int mode)
{ {
FSFileHandle fd; FSFileHandle fd;
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
const char *fsMode;
__wut_fs_file_t *file;
if (path == NULL) { if (!fileStruct || !path) {
return -1;
}
char *path_fixed = __wut_fs_fixpath(r,path);
if (!path_fixed) {
r->_errno = ENOMEM;
return -1;
}
// Get pointer to our data
__wut_fs_file_t *file = (__wut_fs_file_t *)fileStruct;
const char *fs_mode;
// Map flags to open modes
if (flags == 0) {
fs_mode = "r";
} else if (flags == 2) {
fs_mode = "r+";
} else if (flags == 0x601) {
fs_mode = "w";
} else if(flags == 0x602) {
fs_mode = "w+";
} else if(flags == 0x209) {
fs_mode = "a";
} else if(flags == 0x20A) {
fs_mode = "a+";
} else {
free(path_fixed);
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
// Set up command block // Map flags to open modes
FSCmdBlock fsCmd; if (flags == 0) {
FSInitCmdBlock(&fsCmd); fsMode = "r";
} else if (flags == 2) {
// Open the file fsMode = "r+";
rc = FSOpenFile(__wut_devoptab_fs_client, &fsCmd, path_fixed, fs_mode, &fd, -1); } else if (flags == 0x601) {
fsMode = "w";
if (rc >= 0) { } else if(flags == 0x602) {
file->fd = fd; fsMode = "w+";
file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC)); } else if(flags == 0x209) {
FSGetPosFile(__wut_devoptab_fs_client, &fsCmd, fd, &file->offset, -1); fsMode = "a";
free(path_fixed); } else if(flags == 0x20A) {
return 0; fsMode = "a+";
} else {
r->_errno = EINVAL;
return -1;
} }
free(path_fixed); char *fixedPath = __wut_fs_fixpath(r,path);
r->_errno = __wut_fs_translate_error(rc); if (!fixedPath) {
return -1; return -1;
}
// Open the file
FSInitCmdBlock(&cmd);
status = FSOpenFile(__wut_devoptab_fs_client, &cmd, fixedPath, fsMode, &fd,
-1);
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));
FSGetPosFile(__wut_devoptab_fs_client, &cmd, fd, &file->offset, -1);
return 0;
} }

View File

@ -6,9 +6,20 @@ __wut_fs_read(struct _reent *r,
char *ptr, char *ptr,
size_t len) size_t len)
{ {
FSStatus rc; FSStatus status;
uint32_t bytes, bytesRead = 0; FSCmdBlock cmd;
__wut_fs_file_t *file = (__wut_fs_file_t *)fd; uint8_t *alignedReadBuffer;
uint32_t bytes, bytesRead;
__wut_fs_file_t *file;
if (!fd || !ptr) {
r->_errno = EINVAL;
return -1;
}
FSInitCmdBlock(&cmd);
file = (__wut_fs_file_t *)fd;
bytesRead = 0;
// Check that the file was opened with read access // Check that the file was opened with read access
if ((file->flags & O_ACCMODE) == O_WRONLY) { if ((file->flags & O_ACCMODE) == O_WRONLY) {
@ -16,55 +27,44 @@ __wut_fs_read(struct _reent *r,
return -1; return -1;
} }
// Set up command block // Copy to internal buffer due to alignment requirement and read in chunks.
FSCmdBlock fsCmd; alignedReadBuffer = memalign(0x40, 8192);
FSInitCmdBlock(&fsCmd); while (len > 0) {
size_t toRead = len > 8192 ? 8192 : len;
FSStat fsstat;
rc = FSGetStatFile(__wut_devoptab_fs_client, &fsCmd, file->fd, &fsstat, -1);
if(rc < 0) {
r->_errno = __wut_fs_translate_error(rc);
return -1;
}
// Copy to internal buffer and read in chunks.
uint8_t *tmp_buffer = memalign(0x40, 8192);
while(len > 0) {
size_t toRead = len;
if (toRead > 8192) {
toRead = 8192;
}
// Write the data // Write the data
rc = FSReadFile(__wut_devoptab_fs_client, &fsCmd, tmp_buffer, 1, toRead, file->fd, 0, -1); status = FSReadFile(__wut_devoptab_fs_client, &cmd, alignedReadBuffer, 1,
toRead, file->fd, 0, -1);
if(rc <= 0) if (status <= 0) {
{ break;
free(tmp_buffer);
// Return partial transfer
if (bytesRead > 0) {
return bytesRead;
}
r->_errno = __wut_fs_translate_error(rc);
return -1;
} else {
bytes = rc;
} }
// Copy to internal buffer // Copy to internal buffer
memcpy(ptr, tmp_buffer, bytes); bytes = (uint32_t)status;
memcpy(ptr, alignedReadBuffer, bytes);
file->offset += bytes; file->offset += bytes;
bytesRead += bytes; bytesRead += bytes;
ptr += bytes; ptr += bytes;
len -= bytes; len -= bytes;
if (bytes < toRead) {
// If we did not read the full requested toRead bytes then we reached
// the end of the file.
break;
}
}
free(alignedReadBuffer);
// Return partial read
if (bytesRead > 0) {
return bytesRead;
} }
free(tmp_buffer); if (status < 0) {
return bytesRead; r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
} }

View File

@ -5,42 +5,36 @@ __wut_fs_rename(struct _reent *r,
const char *oldName, const char *oldName,
const char *newName) const char *newName)
{ {
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
char *fixedOldPath, *fixedNewPath;
if (oldName == NULL) { if (!oldName || !newName) {
r->_errno = EINVAL;
return -1; return -1;
} }
if (newName == NULL) { fixedOldPath = __wut_fs_fixpath(r, oldName);
if (!fixedOldPath) {
return -1; return -1;
} }
char *path_old = __wut_fs_fixpath(r, oldName); fixedNewPath = __wut_fs_fixpath(r, newName);
if (!fixedNewPath) {
if (!path_old) { free(fixedOldPath);
r->_errno = ENOMEM;
return -1; return -1;
} }
char *path_new = __wut_fs_fixpath(r, newName); FSInitCmdBlock(&cmd);
status = FSRename(__wut_devoptab_fs_client, &cmd, fixedOldPath, fixedNewPath,
-1);
free(fixedOldPath);
free(fixedNewPath);
if (!path_new) { if (status < 0) {
r->_errno = ENOMEM; r->_errno = __wut_fs_translate_error(status);
return -1; return -1;
} }
// Set up command block return 0;
FSCmdBlock fsCmd;
FSInitCmdBlock(&fsCmd);
rc = FSRename(__wut_devoptab_fs_client, &fsCmd, path_old, path_new, -1);
free(path_old);
free(path_new);
if (rc >= 0) {
return 0;
}
r->_errno = __wut_fs_translate_error(rc);
return -1;
} }

View File

@ -4,30 +4,26 @@ int
__wut_fs_rmdir(struct _reent *r, __wut_fs_rmdir(struct _reent *r,
const char *name) const char *name)
{ {
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
if (name == NULL) { if (!name) {
r->_errno = EINVAL;
return -1; return -1;
} }
char *path_fix = __wut_fs_fixpath(r, name); char *fixedPath = __wut_fs_fixpath(r, name);
if (!fixedPath) {
if (!path_fix) {
r->_errno = ENOMEM;
return -1; return -1;
} }
// Set up command block FSInitCmdBlock(&cmd);
FSCmdBlock fsCmd; status = FSRemove(__wut_devoptab_fs_client, &cmd, fixedPath, -1);
FSInitCmdBlock(&fsCmd); free(fixedPath);
if (status < 0) {
rc = FSRemove(__wut_devoptab_fs_client, &fsCmd, path_fix, -1); r->_errno = __wut_fs_translate_error(status);
free(path_fix); return -1;
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); return 0;
return -1;
} }

View File

@ -6,19 +6,23 @@ __wut_fs_seek(struct _reent *r,
off_t pos, off_t pos,
int whence) int whence)
{ {
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
FSStat fsStat;
uint64_t offset; uint64_t offset;
__wut_fs_file_t *file = (__wut_fs_file_t *)fd; __wut_fs_file_t *file;
// Set up command block if (!fd) {
FSCmdBlock fsCmd; r->_errno = EINVAL;
FSInitCmdBlock(&fsCmd); return -1;
}
FSStat fsstat; FSInitCmdBlock(&cmd);
rc = FSGetStatFile(__wut_devoptab_fs_client, &fsCmd, file->fd, &fsstat, -1); file = (__wut_fs_file_t *)fd;
status = FSGetStatFile(__wut_devoptab_fs_client, &cmd, file->fd, &fsStat,
if (rc < 0) { -1);
r->_errno = __wut_fs_translate_error(rc); if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1; return -1;
} }
@ -36,7 +40,7 @@ __wut_fs_seek(struct _reent *r,
// Set position relative to the end of the file // Set position relative to the end of the file
case SEEK_END: case SEEK_END:
offset = fsstat.size; offset = fsStat.size;
break; break;
// An invalid option was provided // An invalid option was provided
@ -54,10 +58,11 @@ __wut_fs_seek(struct _reent *r,
// Update the current offset // Update the current offset
file->offset = offset + pos; file->offset = offset + pos;
FSStatus result = FSSetPosFile(__wut_devoptab_fs_client, &fsCmd, file->fd, file->offset, -1); status = FSSetPosFile(__wut_devoptab_fs_client, &cmd, file->fd, file->offset,
-1);
if (result < 0) { if (status < 0) {
return result; r->_errno = __wut_fs_translate_error(status);
return -1;
} }
return file->offset; return file->offset;

View File

@ -2,41 +2,49 @@
int int
__wut_fs_stat(struct _reent *r, __wut_fs_stat(struct _reent *r,
const char *file, const char *path,
struct stat *st) struct stat *st)
{ {
int fd; int fd;
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
if (file == NULL) { if (!path || !st) {
r->_errno = EINVAL;
return -1; return -1;
} }
// Set up command block char *fixedPath = __wut_fs_fixpath(r, path);
FSCmdBlock fsCmd; if (!fixedPath) {
FSInitCmdBlock(&fsCmd); return -1;
}
FSInitCmdBlock(&cmd);
// First try open as file // First try open as file
rc = FSOpenFile(__wut_devoptab_fs_client, &fsCmd, file, "r", (FSFileHandle*)&fd, -1); status = FSOpenFile(__wut_devoptab_fs_client, &cmd, fixedPath, "r",
(FSFileHandle*)&fd, -1);
if (rc >= 0) { if (status >= 0) {
__wut_fs_file_t tmpfd = { .fd = fd }; __wut_fs_file_t tmpfd = { .fd = fd };
rc = __wut_fs_fstat(r, &tmpfd, st); status = __wut_fs_fstat(r, &tmpfd, st);
FSCloseFile(__wut_devoptab_fs_client, &fsCmd, fd, -1); FSCloseFile(__wut_devoptab_fs_client, &cmd, fd, -1);
return rc; free(fixedPath);
return status;
} }
// File failed, so lets try open as directory // File failed, so lets try open as directory
rc = FSOpenDir(__wut_devoptab_fs_client, &fsCmd, file, (FSDirectoryHandle*)&fd, -1); status = FSOpenDir(__wut_devoptab_fs_client, &cmd, fixedPath,
(FSDirectoryHandle*)&fd, -1);
if (rc >= 0) { free(fixedPath);
memset(st, 0, sizeof(struct stat)); if (status < 0) {
st->st_nlink = 1; r->_errno = __wut_fs_translate_error(status);
st->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO; return -1;
FSCloseDir(__wut_devoptab_fs_client, &fsCmd, fd, -1);
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); memset(st, 0, sizeof(struct stat));
return -1; st->st_nlink = 1;
st->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO;
FSCloseDir(__wut_devoptab_fs_client, &cmd, fd, -1);
free(fixedPath);
return 0;
} }

View File

@ -5,17 +5,7 @@ __wut_fs_statvfs(struct _reent *r,
const char *path, const char *path,
struct statvfs *buf) struct statvfs *buf)
{ {
FSStatus rc;
char *path_fix = __wut_fs_fixpath(r, path);
if (!path_fix) {
r->_errno = ENOMEM;
return -1;
}
//TODO: FSGetFileSystemInfo //TODO: FSGetFileSystemInfo
free(path_fix);
r->_errno = ENOSYS; r->_errno = ENOSYS;
return -1; return -1;
} }

View File

@ -5,32 +5,30 @@ __wut_fs_ftruncate(struct _reent *r,
void *fd, void *fd,
off_t len) off_t len)
{ {
FSStatus rc; FSStatus status;
__wut_fs_file_t *file = (__wut_fs_file_t *)fd; FSCmdBlock cmd;
__wut_fs_file_t *file;
// Make sure length is non-negative // Make sure length is non-negative
if (len < 0) { if (!fd || len < 0) {
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
// Set up command block
FSCmdBlock fsCmd;
FSInitCmdBlock(&fsCmd);
// Set the new file size // Set the new file size
rc = FSSetPosFile(__wut_devoptab_fs_client, &fsCmd, file->fd, len, -1); FSInitCmdBlock(&cmd);
file = (__wut_fs_file_t *)fd;
if (rc >= 0) { status = FSSetPosFile(__wut_devoptab_fs_client, &cmd, file->fd, len, -1);
return 0; if (status < 0) {
r->_errno = __wut_fs_translate_error(status);
return -1;
} }
rc = FSTruncateFile(__wut_devoptab_fs_client, &fsCmd, file->fd, -1); status = FSTruncateFile(__wut_devoptab_fs_client, &cmd, file->fd, -1);
if (status < 0) {
if (rc >= 0) { r->_errno = __wut_fs_translate_error(status);
return 0; return -1;
} }
r->_errno = __wut_fs_translate_error(rc); return 0;
return -1;
} }

View File

@ -4,30 +4,27 @@ int
__wut_fs_unlink(struct _reent *r, __wut_fs_unlink(struct _reent *r,
const char *name) const char *name)
{ {
FSStatus rc; FSStatus status;
FSCmdBlock cmd;
char *fixedPath;
if (name == NULL) { if (!name) {
r->_errno = EINVAL;
return -1; return -1;
} }
char *path_fix = __wut_fs_fixpath(r, name); fixedPath = __wut_fs_fixpath(r, name);
if (!fixedPath) {
if (!path_fix) {
r->_errno = ENOMEM;
return -1; return -1;
} }
// Set up command block FSInitCmdBlock(&cmd);
FSCmdBlock fsCmd; status = FSRemove(__wut_devoptab_fs_client, &cmd, fixedPath, -1);
FSInitCmdBlock(&fsCmd); free(fixedPath);
if (status < 0) {
rc = FSRemove(__wut_devoptab_fs_client, &fsCmd, path_fix, -1); r->_errno = __wut_fs_translate_error(status);
free(path_fix); return -1;
if (rc >= 0) {
return 0;
} }
r->_errno = __wut_fs_translate_error(rc); return 0;
return -1;
} }

View File

@ -4,8 +4,15 @@ char *
__wut_fs_fixpath(struct _reent *r, __wut_fs_fixpath(struct _reent *r,
const char *path) const char *path)
{ {
char *p = strchr(path, ':') + 1; char *p;
char *fixedPath;
if (!path) {
r->_errno = EINVAL;
return NULL;
}
p = strchr(path, ':') + 1;
if (!strchr(path, ':')) { if (!strchr(path, ':')) {
p = (char*)path; p = (char*)path;
} }
@ -15,21 +22,23 @@ __wut_fs_fixpath(struct _reent *r,
return NULL; return NULL;
} }
char *__fixedpath = memalign(0x40, PATH_MAX + 1); fixedPath = memalign(0x40, PATH_MAX + 1);
if (!fixedPath) {
if (__fixedpath == NULL) { r->_errno = ENOMEM;
return NULL; return NULL;
} }
// cwd is handled by coreinit, so just strip the 'device:' if it exists // cwd is handled by coreinit, so just strip the 'device:' if it exists
strcpy(__fixedpath, p); strcpy(fixedPath, p);
return __fixedpath; return fixedPath;
} }
int int
__wut_fs_translate_error(FSStatus error) __wut_fs_translate_error(FSStatus error)
{ {
switch (error) { switch (error) {
case FS_STATUS_END:
return ENOENT;
case FS_STATUS_CANCELLED: case FS_STATUS_CANCELLED:
return EINVAL; return EINVAL;
case FS_STATUS_EXISTS: case FS_STATUS_EXISTS:
@ -44,4 +53,3 @@ __wut_fs_translate_error(FSStatus error)
return (int)error; return (int)error;
} }
} }

View File

@ -6,9 +6,20 @@ __wut_fs_write(struct _reent *r,
const char *ptr, const char *ptr,
size_t len) size_t len)
{ {
FSStatus rc; FSStatus status;
uint32_t bytes, bytesWritten = 0; FSCmdBlock cmd;
__wut_fs_file_t *file = (__wut_fs_file_t *)fd; uint8_t *alignedWriteBuffer;
uint32_t bytes, bytesWritten;
__wut_fs_file_t *file;
if (!fd || !ptr) {
r->_errno = EINVAL;
return -1;
}
FSInitCmdBlock(&cmd);
file = (__wut_fs_file_t *)fd;
bytesWritten = 0;
// Check that the file was opened with write access // Check that the file was opened with write access
if ((file->flags & O_ACCMODE) == O_RDONLY) { if ((file->flags & O_ACCMODE) == O_RDONLY) {
@ -16,46 +27,42 @@ __wut_fs_write(struct _reent *r,
return -1; return -1;
} }
// Copy to internal buffer and write in chunks. // Copy to internal buffer due to alignment requirement and write in chunks.
uint8_t *tmp_buffer = memalign(0x40, 8192); alignedWriteBuffer = memalign(0x40, 8192);
while (len > 0) {
while(len > 0) { size_t toWrite = len > 8192 ? 8192 : len;
size_t toWrite = len;
if (toWrite > 8192) {
toWrite = 8192;
}
// Copy to internal buffer // Copy to internal buffer
memcpy(tmp_buffer, ptr, toWrite); memcpy(alignedWriteBuffer, ptr, toWrite);
// Set up command block
FSCmdBlock fsCmd;
FSInitCmdBlock(&fsCmd);
// Write the data // Write the data
rc = FSWriteFile(__wut_devoptab_fs_client, &fsCmd, tmp_buffer, 1, toWrite, file->fd, 0, -1); status = FSWriteFile(__wut_devoptab_fs_client, &cmd, alignedWriteBuffer,
1, toWrite, file->fd, 0, -1);
if (rc < 0) { if (status <= 0) {
free(tmp_buffer); break;
// Return partial transfer
if (bytesWritten > 0) {
return bytesWritten;
}
r->_errno = __wut_fs_translate_error(rc);
return -1;
} else {
bytes = rc;
} }
bytes = (uint32_t)status;
file->offset += bytes; file->offset += bytes;
bytesWritten += bytes; bytesWritten += bytes;
ptr += bytes; ptr += bytes;
len -= bytes; len -= bytes;
if (bytes < toWrite) {
break;
}
}
free(alignedWriteBuffer);
// Return partial write
if (bytesWritten > 0) {
return bytesWritten;
} }
free(tmp_buffer); if (status < 0) {
return bytesWritten; r->_errno = __wut_fs_translate_error(status);
return -1;
}
return 0;
} }