mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-06 16:19:25 +02:00
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:
parent
4f2a16ec34
commit
49959e4e37
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user