Initial commit
This commit is contained in:
129
channel/channelapp/source/isfs.c
Normal file
129
channel/channelapp/source/isfs.c
Normal file
@@ -0,0 +1,129 @@
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "blob.h"
|
||||
#include "panic.h"
|
||||
#include "isfs.h"
|
||||
|
||||
#define ROUNDUP32B(x) ((x + 32 - 1) & ~(32 - 1))
|
||||
|
||||
static fstats __st ATTRIBUTE_ALIGN(32);
|
||||
|
||||
s32 isfs_get(const char *path, u8 **buf, u32 expected, u32 maxsize, bool use_blob) {
|
||||
s32 ret;
|
||||
s32 fd;
|
||||
u8 *__buf;
|
||||
|
||||
gprintf("reading %s (expecting %lu bytes)\n", path, expected);
|
||||
ret = ISFS_Open(path, ISFS_OPEN_READ);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_Open failed (%ld)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd = ret;
|
||||
|
||||
ret = ISFS_GetFileStats(fd, &__st);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_GetFileStats failed (%ld)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
DCInvalidateRange(&__st, sizeof(__st));
|
||||
|
||||
if ((__st.file_length == 0) ||
|
||||
(maxsize && (__st.file_length > maxsize)) ||
|
||||
(expected && (__st.file_length != expected))) {
|
||||
gprintf("invalid size: %lu\n", __st.file_length);
|
||||
ISFS_Close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (use_blob) {
|
||||
__buf = blob_alloc(ROUNDUP32B(__st.file_length + 1));
|
||||
if (!__buf)
|
||||
panic();
|
||||
} else {
|
||||
__buf = pmemalign(32, ROUNDUP32B(__st.file_length + 1));
|
||||
}
|
||||
|
||||
gprintf("reading %lu bytes\n", __st.file_length);
|
||||
ret = ISFS_Read(fd, __buf, __st.file_length);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_Read failed (%ld)\n", ret);
|
||||
free(__buf);
|
||||
ISFS_Close(fd);
|
||||
return ret;
|
||||
}
|
||||
DCInvalidateRange(__buf, __st.file_length + 1);
|
||||
__buf[__st.file_length] = 0;
|
||||
|
||||
if (ret != __st.file_length) {
|
||||
gprintf("ISFS_Read short read (%ld)\n", ret);
|
||||
free(__buf);
|
||||
ISFS_Close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ISFS_Close(fd);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_Close failed (%ld)\n", ret);
|
||||
free(__buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*buf = __buf;
|
||||
return __st.file_length;
|
||||
}
|
||||
|
||||
s32 isfs_put(const char *path, const void *buf, u32 len) {
|
||||
s32 fd, ret;
|
||||
|
||||
ISFS_Delete(path);
|
||||
|
||||
gprintf("writing %s (%lu bytes)\n", path, len);
|
||||
ret = ISFS_CreateFile(path, 0, 3, 3, 0);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_CreateFile failed (%ld)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ISFS_Open(path, 3);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_Open failed (%ld)\n", ret);
|
||||
ISFS_Delete(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd = ret;
|
||||
|
||||
DCFlushRange((void *) buf, len);
|
||||
|
||||
ret = ISFS_Write(fd, buf, len);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_Write failed (%ld)\n", ret);
|
||||
ISFS_Close(fd);
|
||||
ISFS_Delete(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret != len) {
|
||||
gprintf("ISFS_Write short write (%ld)\n", ret);
|
||||
ISFS_Close(fd);
|
||||
ISFS_Delete(path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ISFS_Close(fd);
|
||||
if (ret < 0) {
|
||||
gprintf("ISFS_Close failed (%ld)\n", ret);
|
||||
ISFS_Delete(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user