FS adjustments + fixed fsFsGetFreeSpace/fsFsGetTotalSpace. In fs_dev: fixed cwd handling, unmounting adjustments, use fsFsGetEntryType(), updated fsdev_dirnext(), and properly handle fsdev_statvfs().

This commit is contained in:
yellows8 2017-11-29 01:47:11 -05:00
parent 4f2a16ec34
commit 49959e4e37
3 changed files with 123 additions and 64 deletions

View File

@ -25,13 +25,14 @@ typedef struct
{ {
char name[FS_MAX_PATH]; ///< Entry name. char name[FS_MAX_PATH]; ///< Entry name.
u8 pad[3]; u8 pad[3];
u32 attributes; ///< Attributes. s8 type; ///< See FsEntryType.
u8 pad2[3]; ///< ?
u64 fileSize; ///< File size. u64 fileSize; ///< File size.
} FsDirectoryEntry; } FsDirectoryEntry;
typedef enum { typedef enum {
ENTRYTYPE_FILE=0, ENTRYTYPE_DIR = 0,
ENTRYTYPE_DIR =1 ENTRYTYPE_FILE = 1
} FsEntryType; } FsEntryType;
typedef enum typedef enum
@ -48,12 +49,6 @@ typedef enum
FS_DIROPEN_FILE = BIT(1), ///< Enable reading file entries. FS_DIROPEN_FILE = BIT(1), ///< Enable reading file entries.
} FsDirectoryFlags; } FsDirectoryFlags;
/// Attribute flags.
typedef enum
{
FS_ATTRIBUTE_FILE = BIT(0), ///< File.
} FsAttribute;
Result fsInitialize(); Result fsInitialize();
void fsExit(void); void fsExit(void);
@ -74,8 +69,8 @@ Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsEntryType* out);
Result fsFsOpenFile(FsFileSystem* fs, const char* path, int flags, FsFile* out); Result fsFsOpenFile(FsFileSystem* fs, const char* path, int flags, FsFile* out);
Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, int flags, FsDir* out); Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, int flags, FsDir* out);
Result fsFsCommit(FsFileSystem* fs); Result fsFsCommit(FsFileSystem* fs);
Result fsFsGetFreeSpace(FsFileSystem* fs, u64* out); Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, u64* out);
Result fsFsGetTotalSpace(FsFileSystem* fs, u64* out); Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, u64* out);
void fsFsClose(FsFileSystem* fs); void fsFsClose(FsFileSystem* fs);
// IFile // IFile

View File

@ -107,6 +107,7 @@ typedef struct
} fsdev_fsdevice; } fsdev_fsdevice;
static s32 fsdev_fsdevice_default = -1; static s32 fsdev_fsdevice_default = -1;
static s32 fsdev_fsdevice_cwd = -1;
static fsdev_fsdevice fsdev_fsdevices[32]; static fsdev_fsdevice fsdev_fsdevices[32];
/*! @endcond */ /*! @endcond */
@ -160,16 +161,7 @@ fsdev_fixpath(struct _reent *r,
ssize_t units; ssize_t units;
uint32_t code; uint32_t code;
const uint8_t *p = (const uint8_t*)path; const uint8_t *p = (const uint8_t*)path;
const char *device_path = path;
if(device)
{
*device = fsdevFindDevice(path);
if(*device == NULL)
{
r->_errno = ENODEV;
return NULL;
}
}
// Move the path pointer to the start of the actual path // Move the path pointer to the start of the actual path
do do
@ -224,6 +216,25 @@ fsdev_fixpath(struct _reent *r,
return NULL; return NULL;
} }
if(device)
{
if(path[0] == '/')
{
*device = fsdevFindDevice(device_path);
}
else
{
*device = NULL;
if(fsdev_fsdevice_cwd != -1)
*device = &fsdev_fsdevices[fsdev_fsdevice_cwd];
}
if(*device == NULL)
{
r->_errno = ENODEV;
return NULL;
}
}
return __fixedpath; return __fixedpath;
} }
@ -342,6 +353,12 @@ static int _fsdevUnmountDeviceStruct(fsdev_fsdevice *device)
memset(device, 0, sizeof(fsdev_fsdevice)); memset(device, 0, sizeof(fsdev_fsdevice));
if(device->id == fsdev_fsdevice_default)
fsdev_fsdevice_default = -1;
if(device->id == fsdev_fsdevice_cwd)
fsdev_fsdevice_cwd = fsdev_fsdevice_default;
return 0; return 0;
} }
@ -384,7 +401,10 @@ Result fsdevInit(void)
{ {
setDefaultDevice(dev); setDefaultDevice(dev);
if(device) if(device)
{
fsdev_fsdevice_default = device->id; fsdev_fsdevice_default = device->id;
fsdev_fsdevice_cwd = fsdev_fsdevice_default;
}
//TODO: Re-enable this once __system_argc/__system_argv are actually defined. //TODO: Re-enable this once __system_argc/__system_argv are actually defined.
/*if(__system_argc != 0 && __system_argv[0] != NULL) /*if(__system_argc != 0 && __system_argv[0] != NULL)
@ -460,7 +480,6 @@ Result fsdevExit(void)
_fsdevUnmountDeviceStruct(&fsdev_fsdevices[i]); _fsdevUnmountDeviceStruct(&fsdev_fsdevices[i]);
} }
fsdev_fsdevice_default = -1;
fsdevInitialised = false; fsdevInitialised = false;
return 0; return 0;
@ -885,25 +904,41 @@ fsdev_stat(struct _reent *r,
Result rc; Result rc;
char fs_path[FS_MAX_PATH]; char fs_path[FS_MAX_PATH];
fsdev_fsdevice *device = NULL; fsdev_fsdevice *device = NULL;
FsEntryType type;
if(fsdev_getfspath(r, file, &device, fs_path)==-1) if(fsdev_getfspath(r, file, &device, fs_path)==-1)
return -1; return -1;
if(R_SUCCEEDED(rc = fsFsOpenFile(&device->fs, fs_path, FS_OPEN_READ, &fd))) rc = fsFsGetEntryType(&device->fs, fs_path, &type);
if(R_SUCCEEDED(rc))
{ {
fsdev_file_t tmpfd = { .fd = fd }; if(type == ENTRYTYPE_DIR)
rc = fsdev_fstat(r, &tmpfd, st); {
fsFileClose(&fd); if(R_SUCCEEDED(rc = fsFsOpenDirectory(&device->fs, fs_path, FS_DIROPEN_DIRECTORY | FS_DIROPEN_FILE, &fdir)))
{
memset(st, 0, sizeof(struct stat));
st->st_nlink = 1;
st->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO;
fsDirClose(&fdir);
return 0;
}
}
else if(type == ENTRYTYPE_FILE)
{
if(R_SUCCEEDED(rc = fsFsOpenFile(&device->fs, fs_path, FS_OPEN_READ, &fd)))
{
fsdev_file_t tmpfd = { .fd = fd };
rc = fsdev_fstat(r, &tmpfd, st);
fsFileClose(&fd);
return rc; return rc;
} }
else if(R_SUCCEEDED(rc = fsFsOpenDirectory(&device->fs, fs_path, FS_DIROPEN_DIRECTORY | FS_DIROPEN_FILE, &fdir))) }
{ else
memset(st, 0, sizeof(struct stat)); {
st->st_nlink = 1; r->_errno = EINVAL;
st->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO; return -1;
fsDirClose(&fdir); }
return 0;
} }
r->_errno = fsdev_translate_error(rc); r->_errno = fsdev_translate_error(rc);
@ -980,6 +1015,7 @@ fsdev_chdir(struct _reent *r,
{ {
fsDirClose(&fd); fsDirClose(&fd);
strncpy(__cwd, __fixedpath, PATH_MAX); strncpy(__cwd, __fixedpath, PATH_MAX);
fsdev_fsdevice_cwd = device->id;
return 0; return 0;
} }
@ -1002,6 +1038,7 @@ fsdev_rename(struct _reent *r,
const char *newName) const char *newName)
{ {
Result rc; Result rc;
FsEntryType type;
fsdev_fsdevice *device_old = NULL, *device_new = NULL; fsdev_fsdevice *device_old = NULL, *device_new = NULL;
char fs_path_old[FS_MAX_PATH]; char fs_path_old[FS_MAX_PATH];
char fs_path_new[FS_MAX_PATH]; char fs_path_new[FS_MAX_PATH];
@ -1018,13 +1055,27 @@ fsdev_rename(struct _reent *r,
return -1; return -1;
} }
rc = fsFsRenameFile(&device_old->fs, fs_path_old, fs_path_new); rc = fsFsGetEntryType(&device_old->fs, fs_path_old, &type);
if(R_SUCCEEDED(rc)) if(R_SUCCEEDED(rc))
return 0; {
if(type == ENTRYTYPE_DIR)
rc = fsFsRenameDirectory(&device_old->fs, fs_path_old, fs_path_new); {
if(R_SUCCEEDED(rc)) rc = fsFsRenameDirectory(&device_old->fs, fs_path_old, fs_path_new);
return 0; if(R_SUCCEEDED(rc))
return 0;
}
else if(type == ENTRYTYPE_FILE)
{
rc = fsFsRenameFile(&device_old->fs, fs_path_old, fs_path_new);
if(R_SUCCEEDED(rc))
return 0;
}
else
{
r->_errno = EINVAL;
return -1;
}
}
r->_errno = fsdev_translate_error(rc); r->_errno = fsdev_translate_error(rc);
return -1; return -1;
@ -1176,12 +1227,20 @@ fsdev_dirnext(struct _reent *r,
/* fill in the stat info */ /* fill in the stat info */
filestat->st_ino = 0; filestat->st_ino = 0;
if(entry->attributes & FS_ATTRIBUTE_FILE) if(entry->type == ENTRYTYPE_DIR)
filestat->st_mode = S_IFREG;
else
filestat->st_mode = S_IFDIR; filestat->st_mode = S_IFDIR;
else if(entry->type == ENTRYTYPE_FILE)
{
filestat->st_mode = S_IFREG;
filestat->st_size = entry->fileSize;
}
else
{
r->_errno = EINVAL;
return -1;
}
/* convert name from UTF-16 to UTF-8 */ /* convert name from fs-path to UTF-8 */
memset(filename, 0, NAME_MAX); memset(filename, 0, NAME_MAX);
units = fsdev_convertfromfspath((uint8_t*)filename, (uint8_t*)entry->name, NAME_MAX); units = fsdev_convertfromfspath((uint8_t*)filename, (uint8_t*)entry->name, NAME_MAX);
if(units < 0) if(units < 0)
@ -1244,28 +1303,31 @@ fsdev_statvfs(struct _reent *r,
struct statvfs *buf) struct statvfs *buf)
{ {
Result rc=0; Result rc=0;
//FS_ArchiveResource resource; char fs_path[FS_MAX_PATH];
//bool writable = false; fsdev_fsdevice *device = NULL;
u64 freespace = 0, total_space = 0;
//rc = FSUSER_GetSdmcArchiveResource(&resource); if(fsdev_getfspath(r, path, &device, fs_path)==-1)
return -1;
rc = fsFsGetFreeSpace(&device->fs, fs_path, &freespace);
if(R_SUCCEEDED(rc))
rc = fsFsGetTotalSpace(&device->fs, fs_path, &total_space);
if(R_SUCCEEDED(rc)) if(R_SUCCEEDED(rc))
{ {
buf->f_bsize = 0;//resource.clusterSize; buf->f_bsize = 1;
buf->f_frsize = 0;//resource.clusterSize; buf->f_frsize = 1;
buf->f_blocks = 0;//resource.totalClusters; buf->f_blocks = total_space;
buf->f_bfree = 0;//resource.freeClusters; buf->f_bfree = freespace;
buf->f_bavail = 0;//resource.freeClusters; buf->f_bavail = freespace;
buf->f_files = 0; //??? how to get buf->f_files = 0;
buf->f_ffree = 0;//resource.freeClusters; buf->f_ffree = 0;
buf->f_favail = 0;//resource.freeClusters; buf->f_favail = 0;
buf->f_fsid = 0; //??? how to get buf->f_fsid = 0;
buf->f_flag = ST_NOSUID; buf->f_flag = ST_NOSUID;
buf->f_namemax = 0; //??? how to get buf->f_namemax = 0;
/*rc = FSUSER_IsSdmcWritable(&writable);
if(R_FAILED(rc) || !writable)
buf->f_flag |= ST_RDONLY;*/
return 0; return 0;
} }

View File

@ -464,9 +464,10 @@ Result fsFsCommit(FsFileSystem* fs) {
return rc; return rc;
} }
Result fsFsGetFreeSpace(FsFileSystem* fs, u64* out) { Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, u64* out) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
struct { struct {
u64 magic; u64 magic;
@ -500,9 +501,10 @@ Result fsFsGetFreeSpace(FsFileSystem* fs, u64* out) {
return rc; return rc;
} }
Result fsFsGetTotalSpace(FsFileSystem* fs, u64* out) { Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, u64* out) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
struct { struct {
u64 magic; u64 magic;