mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 23:39:17 +02:00
fygue: (untested) complete re-architecture + syncfs() support
This commit is contained in:
parent
c99a18d748
commit
69d59cd4d2
32 changed files with 753 additions and 600 deletions
|
@ -264,31 +264,38 @@ set(SOURCES
|
|||
src/fs/fygue/fygue_open.c
|
||||
src/fs/fygue/fygue_syncfs.c
|
||||
src/fs/fygue/fygue_stat.c
|
||||
src/fs/fygue/fygue_mount.c
|
||||
src/fs/fygue/fygue_dir_open.c
|
||||
src/fs/fygue/fygue_dir_read.c
|
||||
src/fs/fygue/fygue_dir_lseek.c
|
||||
src/fs/fygue/fygue_dir_write.c
|
||||
src/fs/fygue/fygue_dir_lseek.c
|
||||
src/fs/fygue/fygue_dir_close.c
|
||||
src/fs/fygue/fygue_file_lseek.c
|
||||
src/fs/fygue/fygue_file_write.c
|
||||
src/fs/fygue/fygue_file_close.c
|
||||
src/fs/fygue/fygue_dir_sync.c
|
||||
src/fs/fygue/fygue_file_open.c
|
||||
src/fs/fygue/fygue_file_read.c
|
||||
src/fs/fygue/fat/cluster.c
|
||||
src/fs/fygue/fygue_file_write.c
|
||||
src/fs/fygue/fygue_file_lseek.c
|
||||
src/fs/fygue/fygue_file_close.c
|
||||
src/fs/fygue/fygue_file_sync.c
|
||||
src/fs/fygue/fat/fat.c
|
||||
src/fs/fygue/fat/cluster.c
|
||||
src/fs/fygue/fat/sector.c
|
||||
src/fs/fygue/fat/fat_dir_open.c
|
||||
src/fs/fygue/fat/fat_dir_read.c
|
||||
src/fs/fygue/fat/fat_dir_close.c
|
||||
src/fs/fygue/fat/fat_dir_stat.c
|
||||
src/fs/fygue/fat/fat_dir_close.c
|
||||
src/fs/fygue/fat/fat_dir_sync.c
|
||||
src/fs/fygue/fat/fat_file_open.c
|
||||
src/fs/fygue/fat/fat_file_stat.c
|
||||
src/fs/fygue/fat/fat_file_close.c
|
||||
src/fs/fygue/fat/fat_file_read.c
|
||||
src/fs/fygue/fat/fat_file_seek.c
|
||||
src/fs/fygue/fat/resolve.c
|
||||
src/fs/fygue/fat/sector.c
|
||||
src/fs/fygue/flash/cluster.c
|
||||
src/fs/fygue/flash/cmap.c
|
||||
src/fs/fygue/flash/flash.c
|
||||
src/fs/fygue/flash/sector.c
|
||||
src/fs/fygue/fat/fat_file_stat.c
|
||||
src/fs/fygue/fat/fat_file_close.c
|
||||
src/fs/fygue/fat/fat_file_sync.c
|
||||
src/fs/fygue/fat/fat_open.c
|
||||
src/fs/fygue/fat/flash/cluster.c
|
||||
src/fs/fygue/fat/flash/cmap.c
|
||||
src/fs/fygue/fat/flash/flash.c
|
||||
src/fs/fygue/fat/flash/sector.c
|
||||
)
|
||||
|
||||
set(ASSETS_FX src/font5x7.png src/gdb/icons-i1msb.png)
|
||||
|
|
|
@ -60,7 +60,7 @@ bool fs_descriptor_is_fygue(fs_descriptor_t const *desc)
|
|||
{
|
||||
return (
|
||||
(desc->type == &fygue_dir_descriptor_type) ||
|
||||
(desc->type == &fygue_descriptor_type)
|
||||
(desc->type == &fygue_file_descriptor_type)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
** fygue/fat/cluster - FAT cluster handling
|
||||
*/
|
||||
#include "fat.h"
|
||||
#include "../flash/flash.h"
|
||||
#include "flash/flash.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
#include <gint/defs/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../flash/flash.h"
|
||||
#include "flash/flash.h"
|
||||
|
||||
/* _FAT_WORD() : helper for 16bit value */
|
||||
#define FAT_WORD(x) \
|
||||
(((x & 0xff00) >> 8) | ((x & 0x00ff) << 8))
|
||||
|
||||
/* _FAT_DWORD() : helper for 32bit value */
|
||||
#define FAT_DWORD(x) ( \
|
||||
#define FAT_DWORD(x) ( \
|
||||
(((x) & 0xff000000) >> 24) \
|
||||
| (((x) & 0x00ff0000) >> 8) \
|
||||
| (((x) & 0x0000ff00) << 8) \
|
||||
|
@ -94,12 +94,12 @@ struct fygue_fat_file
|
|||
int chunk_rd_offset;
|
||||
};
|
||||
|
||||
/* fygue_fat_resolve: internal resolve information */
|
||||
struct fygue_fat_resolve
|
||||
/* fygue_fat_descriptor: FAT descriptor information */
|
||||
struct fygue_fat_descriptor
|
||||
{
|
||||
enum {
|
||||
FYGUE_FAT_FILE_TYPE_FILE,
|
||||
FYGUE_FAT_FILE_TYPE_DIR,
|
||||
FYGUE_FAT_DESC_TYPE_FILE,
|
||||
FYGUE_FAT_DESC_TYPE_DIR,
|
||||
} type;
|
||||
union {
|
||||
struct fygue_fat_file file;
|
||||
|
@ -107,17 +107,21 @@ struct fygue_fat_resolve
|
|||
};
|
||||
};
|
||||
|
||||
//---
|
||||
// Public interface
|
||||
//---
|
||||
|
||||
/* fygue_fat_initialize() - fully initialize the FAT information */
|
||||
extern int fygue_fat_initialize(struct fygue_fat *fat);
|
||||
|
||||
/* fygue_fat_sync() - re-initialize the FAT information */
|
||||
extern int fygue_fat_sync(struct fygue_fat *fat);
|
||||
|
||||
/* fygue_fat_resolve() - resolve the path and set the dirent information */
|
||||
extern int fygue_fat_resolve(
|
||||
/* fygue_fat_open() - resolve the path and set the dirent information */
|
||||
extern int fygue_fat_open(
|
||||
struct fygue_fat *fat,
|
||||
char const * const path,
|
||||
struct fygue_fat_resolve *resolve
|
||||
struct fygue_fat_descriptor *desc
|
||||
);
|
||||
|
||||
//---
|
||||
|
@ -154,7 +158,8 @@ extern int fygue_fat_dir_stat(
|
|||
/* fygue_fat_dir_sync(): sync directory information */
|
||||
extern int fygue_fat_dir_sync(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_dir *dir
|
||||
struct fygue_fat_dir *dir,
|
||||
int cluster_id
|
||||
);
|
||||
|
||||
//---
|
||||
|
@ -199,7 +204,8 @@ extern int fygue_fat_file_close(
|
|||
/* fygue_fat_file_sync(): sync internal information */
|
||||
extern int fygue_fat_file_sync(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_file *file
|
||||
struct fygue_fat_file *file,
|
||||
int cluster_id
|
||||
);
|
||||
|
||||
//---
|
||||
|
|
|
@ -7,38 +7,17 @@ int fygue_fat_dir_open(
|
|||
struct fygue_fat_dir *dir,
|
||||
struct fygue_fat_dirent *dirent
|
||||
) {
|
||||
int rc;
|
||||
|
||||
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
|
||||
if (dirent == NULL) {
|
||||
dir->cluster_entry = 0;
|
||||
dir->root_dirent_count = fat->RootEntCount;
|
||||
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
|
||||
dir->attribute = FYGUE_FAT_DESC_TYPE_DIR;
|
||||
} else {
|
||||
if ((dirent->attribute & FYGUE_FAT_FILE_TYPE_DIR) == 0x00)
|
||||
if ((dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY) == 0x00)
|
||||
return -1;
|
||||
dir->cluster_entry = dirent->cluster_id;
|
||||
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
|
||||
dir->attribute = FYGUE_FAT_DESC_TYPE_DIR;
|
||||
dir->root_dirent_count = 0;
|
||||
}
|
||||
dir->dirty = false;
|
||||
dir->sector_count = 0;
|
||||
dir->dirent_cursor = 0;
|
||||
dir->end_of_dirent = false;
|
||||
dir->cluster_current = dir->cluster_entry;
|
||||
rc = fygue_fat_cluster_get_sector(
|
||||
fat,
|
||||
dir->cluster_current,
|
||||
&dir->sector_id
|
||||
);
|
||||
if (rc != 0)
|
||||
return -2;
|
||||
rc = fygue_fat_sector_get_addr(
|
||||
fat,
|
||||
&dir->dirent_current_addr,
|
||||
dir->sector_id
|
||||
);
|
||||
if (rc != 0)
|
||||
return -3;
|
||||
return 0;
|
||||
return fygue_fat_dir_sync(fat, dir, dir->cluster_entry);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,32 @@
|
|||
/* fygue_fat_dir_sync(): sync directory information */
|
||||
int fygue_fat_dir_sync(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_dir *dir
|
||||
struct fygue_fat_dir *dir,
|
||||
int cluster_id
|
||||
) {
|
||||
int rc;
|
||||
|
||||
if (fat == NULL || dir == NULL)
|
||||
return -1;
|
||||
// nothing to do (?)
|
||||
dir->dirty = false;
|
||||
dir->sector_count = 0;
|
||||
dir->dirent_cursor = 0;
|
||||
dir->end_of_dirent = false;
|
||||
dir->cluster_entry = cluster_id;
|
||||
dir->cluster_current = dir->cluster_entry;
|
||||
rc = fygue_fat_cluster_get_sector(
|
||||
fat,
|
||||
dir->cluster_current,
|
||||
&dir->sector_id
|
||||
);
|
||||
if (rc != 0)
|
||||
return -2;
|
||||
rc = fygue_fat_sector_get_addr(
|
||||
fat,
|
||||
&dir->dirent_current_addr,
|
||||
dir->sector_id
|
||||
);
|
||||
if (rc != 0)
|
||||
return -3;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ int fygue_fat_file_open(
|
|||
file->chunk = NULL;
|
||||
file->chunk_count = 0;
|
||||
file->chunk_table_max_index = 0;
|
||||
if (fygue_fat_file_sync(fat, file) != 0)
|
||||
if (fygue_fat_file_sync(fat, file, dirent->cluster_id) != 0)
|
||||
return -1;
|
||||
if (fygue_fat_file_seek(fat, file, 0) != 0)
|
||||
return -2;
|
||||
|
|
|
@ -60,15 +60,15 @@ static int _fygue_chunk_error(struct fygue_fat_file *file)
|
|||
/* fygue_fat_file_sync(): sync internal information */
|
||||
int fygue_fat_file_sync(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_file *file
|
||||
struct fygue_fat_file *file,
|
||||
int cluster_id
|
||||
) {
|
||||
uintptr_t cluster_addr;
|
||||
int cluster_id;
|
||||
|
||||
if (fat == NULL || file == NULL)
|
||||
return -1;
|
||||
file->chunk_count = 0;
|
||||
cluster_id = file->cluster_entry;
|
||||
file->cluster_entry = cluster_id;
|
||||
while (true)
|
||||
{
|
||||
if (fygue_fat_cluster_get_addr(fat, &cluster_addr, cluster_id) != 0)
|
||||
|
|
|
@ -52,15 +52,16 @@ static int _fygue_dirent_find(
|
|||
/* _fygue_resolve_set(): setup the resolve response */
|
||||
static int _fygue_resolve_set(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_resolve *resolve,
|
||||
struct fygue_fat_descriptor *desc,
|
||||
struct fygue_fat_dirent *dirent
|
||||
) {
|
||||
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
|
||||
resolve->type = FYGUE_FAT_FILE_TYPE_DIR;
|
||||
return fygue_fat_dir_open(fat, &(resolve->dir), dirent);
|
||||
desc->type = FYGUE_FAT_DESC_TYPE_DIR;
|
||||
return fygue_fat_dir_open(fat, &(desc->dir), dirent);
|
||||
} else {
|
||||
desc->type = FYGUE_FAT_DESC_TYPE_FILE;
|
||||
return fygue_fat_file_open(fat, &(desc->file), dirent);
|
||||
}
|
||||
resolve->type = FYGUE_FAT_FILE_TYPE_FILE;
|
||||
return fygue_fat_file_open(fat, &(resolve->file), dirent);
|
||||
}
|
||||
|
||||
//---
|
||||
|
@ -71,10 +72,10 @@ static int _fygue_resolve_set(
|
|||
*
|
||||
* notes
|
||||
* - assume that the path is clean */
|
||||
int fygue_fat_resolve(
|
||||
int fygue_fat_open(
|
||||
struct fygue_fat *fat,
|
||||
char const * const path,
|
||||
struct fygue_fat_resolve *resolve
|
||||
struct fygue_fat_descriptor *desc
|
||||
) {
|
||||
struct fygue_fat_dirent dirent;
|
||||
struct fygue_fat_dir dir;
|
||||
|
@ -83,7 +84,7 @@ int fygue_fat_resolve(
|
|||
size_t len;
|
||||
bool is_root;
|
||||
|
||||
if (fat == NULL || path == NULL || resolve == NULL)
|
||||
if (fat == NULL || path == NULL || desc == NULL)
|
||||
return -1;
|
||||
if (path[0] != '/')
|
||||
return -1;
|
||||
|
@ -107,6 +108,6 @@ int fygue_fat_resolve(
|
|||
return -5;
|
||||
}
|
||||
if (is_root)
|
||||
return _fygue_resolve_set(fat, resolve, NULL);
|
||||
return _fygue_resolve_set(fat, resolve, &dirent);
|
||||
return _fygue_resolve_set(fat, desc, NULL);
|
||||
return _fygue_resolve_set(fat, desc, &dirent);
|
||||
}
|
|
@ -1,129 +1,171 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gint/hardware.h>
|
||||
#include "fygue.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* __fygue_fsinfo: internal filesystem information */
|
||||
static struct fygue_fsinfo *__fygue_fsinfo = NULL;
|
||||
/* FYGUE_GFDI_CHEK - shorthand for all GFDI prologue */
|
||||
#define FYGUE_GFDI_CHEK(type) \
|
||||
_fygue_gfdi_ensure_valid(&fsinfo, desc, type)
|
||||
|
||||
//---
|
||||
// Primitives
|
||||
//---
|
||||
|
||||
/* fygue_mount() - mount (if needed) and return the filesystem information
|
||||
/* _fygue_gfdi_ensure_valid(): ensure GFDI validity
|
||||
*
|
||||
* notes
|
||||
* - assume that this global is const after initialisation */
|
||||
int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh)
|
||||
{
|
||||
if (fsinfo == NULL)
|
||||
return -1;
|
||||
*fsinfo = NULL;
|
||||
if (__fygue_fsinfo == NULL)
|
||||
{
|
||||
__fygue_fsinfo = calloc(1, sizeof(struct fygue_fsinfo));
|
||||
if (__fygue_fsinfo == NULL)
|
||||
return -2;
|
||||
if (fygue_fat_initialize(&(__fygue_fsinfo->fat)) != 0) {
|
||||
free(__fygue_fsinfo);
|
||||
__fygue_fsinfo = NULL;
|
||||
return -3;
|
||||
}
|
||||
__fygue_fsinfo->dirty = false;
|
||||
}
|
||||
if (refresh && __fygue_fsinfo->dirty) {
|
||||
if (fygue_fat_sync(&(__fygue_fsinfo->fat)) != 0)
|
||||
return -4;
|
||||
__fygue_fsinfo->dirty = false;
|
||||
}
|
||||
*fsinfo = __fygue_fsinfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fygue_resolve() - try to resolve path
|
||||
*
|
||||
* notes
|
||||
* - assume that path is clean
|
||||
* - automatically mount the filesystem if needed
|
||||
* - the saved pathname will not be saved in stat */
|
||||
int fygue_resolve(char const * const path, struct fygue_resolve *resolve)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
struct fygue_fat_resolve fat_resolve;
|
||||
|
||||
if (path == NULL || path[0] != '/' || resolve == NULL)
|
||||
return -1;
|
||||
if (fygue_mount(&fsinfo, true) != 0)
|
||||
return -2;
|
||||
if (fygue_fat_resolve(&(fsinfo->fat), path, &fat_resolve) != 0)
|
||||
return -3;
|
||||
memset(resolve, 0x00, sizeof(struct fygue_resolve));
|
||||
if (fat_resolve.type == FYGUE_FAT_FILE_TYPE_FILE)
|
||||
{
|
||||
resolve->type = FYGUE_FILE_TYPE_DIR;
|
||||
resolve->file.cursor = 0;
|
||||
memcpy(
|
||||
&(resolve->file.fat),
|
||||
&(fat_resolve.file),
|
||||
sizeof(struct fygue_fat_file)
|
||||
);
|
||||
} else {
|
||||
resolve->type = FYGUE_FILE_TYPE_DIR;
|
||||
resolve->dir.dirent = NULL;
|
||||
memcpy(
|
||||
&(resolve->dir.fat),
|
||||
&(fat_resolve.dir),
|
||||
sizeof(struct fygue_fat_dir)
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Syncronization
|
||||
//---
|
||||
|
||||
/* fygue_descriptor_sync(): sync internal descriptor information */
|
||||
int fygue_descriptor_sync(
|
||||
* notes:
|
||||
* - assume info is not NULL
|
||||
* - auto mount the FS (if needed) and get information
|
||||
* - ensure file sync if needed */
|
||||
static int _fygue_gfdi_ensure_valid(
|
||||
struct fygue_fsinfo **fsinfo,
|
||||
struct fygue_descriptor *desc
|
||||
struct fygue_descriptor *desc,
|
||||
unsigned int type
|
||||
) {
|
||||
int (*sync)(struct fygue_descriptor*);
|
||||
struct fygue_fsinfo *ffsinfo;
|
||||
int rc;
|
||||
|
||||
if (fygue_mount(&ffsinfo, true) != 0)
|
||||
return -2;
|
||||
if (fsinfo != NULL)
|
||||
*fsinfo = ffsinfo;
|
||||
if (desc != NULL && desc->dirty)
|
||||
if(gint[HWFS] != HWFS_FUGUE)
|
||||
FYGUE_RET_ERRNO(ENOTSUP);
|
||||
if (fsinfo == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (desc == NULL || desc->type == type)
|
||||
FYGUE_RET_ERRNO(EBADF);
|
||||
if (fygue_mount(fsinfo) != 0)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (desc->dirty)
|
||||
{
|
||||
sync = &fygue_file_sync;
|
||||
if (desc->resolve.type == FYGUE_FILE_TYPE_DIR)
|
||||
sync = &fygue_dir_sync;
|
||||
if (sync(desc) != 0)
|
||||
return -1;
|
||||
if (desc->type == FYGUE_DESC_TYPE_DIR)
|
||||
rc = fygue_dir_sync(*fsinfo, &(desc->dir));
|
||||
if (desc->type == FYGUE_DESC_TYPE_FILE)
|
||||
rc = fygue_file_sync(*fsinfo, &(desc->file));
|
||||
if (rc != 0)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
desc->dirty = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Gint File Descriptor Interface (gfdi) for file
|
||||
//---
|
||||
|
||||
/* fygue_gfdi_file_write(): write file */
|
||||
static ssize_t fygue_gfdi_file_write(
|
||||
struct fygue_descriptor *desc,
|
||||
void *buffer,
|
||||
size_t size
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
|
||||
return fygue_file_write(fsinfo, &(desc->file), buffer, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fygue_gfdi_file_read(): write directory (EISDIR) */
|
||||
static ssize_t fygue_gfdi_file_read(
|
||||
struct fygue_descriptor *desc,
|
||||
void *buffer,
|
||||
size_t size
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
|
||||
return fygue_file_read(fsinfo, &(desc->file), buffer, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fygue_file_lseek(): seek file */
|
||||
static off_t fygue_gfdi_file_lseek(
|
||||
struct fygue_descriptor *desc,
|
||||
off_t offset,
|
||||
int whence
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
|
||||
return fygue_file_lseek(fsinfo, &(desc->file), offset, whence);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fygue_file_close(): close directory */
|
||||
static int fygue_gfdi_file_close(struct fygue_descriptor *desc)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
|
||||
return fygue_file_close(fsinfo, &(desc->file));
|
||||
return -1;
|
||||
}
|
||||
|
||||
//---
|
||||
// Gint File Descriptor Interface (gfdi) for file
|
||||
//---
|
||||
|
||||
/* fygue_dir_write(): write directory (EISDIR) */
|
||||
ssize_t fygue_gfdi_dir_write(
|
||||
struct fygue_descriptor *desc,
|
||||
void *buffer,
|
||||
size_t size
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
|
||||
return fygue_dir_write(fsinfo, &(desc->dir), buffer, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fygue_gfdi_dir_read(): readdir */
|
||||
ssize_t fygue_gfdi_dir_read(
|
||||
struct fygue_descriptor *desc,
|
||||
struct dirent **dirent,
|
||||
size_t size
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
|
||||
return fygue_dir_read(fsinfo, &(desc->dir), dirent, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fygue_gfdi_dir_lseek(): seek directory */
|
||||
off_t fygue_gfdi_dir_lseek(
|
||||
struct fygue_descriptor *desc,
|
||||
off_t offset,
|
||||
int whence
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
|
||||
return fygue_dir_lseek(fsinfo, &(desc->dir), offset, whence);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fygue_gfdi_dir_close(): close directory */
|
||||
int fygue_gfdi_dir_close(struct fygue_descriptor *desc)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
|
||||
return fygue_dir_close(fsinfo, &(desc->dir));
|
||||
return -1;
|
||||
}
|
||||
|
||||
//---
|
||||
// Descriptor
|
||||
//---
|
||||
|
||||
const fs_descriptor_type_t fygue_descriptor_type = {
|
||||
.read = (void*)&fygue_file_read,
|
||||
.write = (void*)&fygue_file_write,
|
||||
.lseek = (void*)&fygue_file_lseek,
|
||||
.close = (void*)&fygue_file_close,
|
||||
/* fygue_file_descriptor_type - fygue file descriptor */
|
||||
const fs_descriptor_type_t fygue_file_descriptor_type = {
|
||||
.read = (void*)&fygue_gfdi_file_read,
|
||||
.write = (void*)&fygue_gfdi_file_write,
|
||||
.lseek = (void*)&fygue_gfdi_file_lseek,
|
||||
.close = (void*)&fygue_gfdi_file_close,
|
||||
};
|
||||
|
||||
const fs_descriptor_type_t fygue_dir_descriptor_type = {
|
||||
.read = (void*)&fygue_dir_read,
|
||||
.write = (void*)&fygue_dir_write,
|
||||
.lseek = (void*)&fygue_dir_lseek,
|
||||
.close = (void*)&fygue_dir_close,
|
||||
.read = (void*)&fygue_gfdi_dir_read,
|
||||
.write = (void*)&fygue_gfdi_dir_write,
|
||||
.lseek = (void*)&fygue_gfdi_dir_lseek,
|
||||
.close = (void*)&fygue_gfdi_dir_close,
|
||||
};
|
||||
|
|
|
@ -10,13 +10,15 @@ extern "C" {
|
|||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <gint/fs.h>
|
||||
#include <errno.h>
|
||||
#include "fat/fat.h"
|
||||
|
||||
//---
|
||||
// Public global
|
||||
//---
|
||||
|
||||
/* File descriptor type */
|
||||
extern const fs_descriptor_type_t fygue_descriptor_type;
|
||||
extern const fs_descriptor_type_t fygue_file_descriptor_type;
|
||||
/* Directory descriptor type */
|
||||
extern const fs_descriptor_type_t fygue_dir_descriptor_type;
|
||||
|
||||
|
@ -24,29 +26,9 @@ extern const fs_descriptor_type_t fygue_dir_descriptor_type;
|
|||
// Public (low-level) API
|
||||
//---
|
||||
|
||||
/* fygue_open() - open file or directory */
|
||||
extern int fygue_open(char const *path, int flags, mode_t mode);
|
||||
|
||||
/* fygue_stat() - get file or directory information */
|
||||
extern int fygue_stat(char const *path, struct stat *statbuf);
|
||||
|
||||
/* fygue_syncfs() - request filesystem re-synchronisation */
|
||||
extern int fygue_syncfs(void *desc);
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
#include <gint/hardware.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define ENOTSUP_IF_NOT_FYGUE(rc) \
|
||||
if(gint[HWFS] != HWFS_FUGUE) { \
|
||||
errno = ENOTSUP; \
|
||||
return (rc); \
|
||||
}
|
||||
|
||||
#include "fat/fat.h"
|
||||
/* helper to set errno and return -1 */
|
||||
#define FYGUE_RET_ERRNO(error) \
|
||||
do { errno = error; return -1; } while(0);
|
||||
|
||||
/* fygue_fsinfo: internal fygue FS information */
|
||||
struct fygue_fsinfo
|
||||
|
@ -55,111 +37,162 @@ struct fygue_fsinfo
|
|||
bool dirty;
|
||||
};
|
||||
|
||||
/* fygue_resolve: internals file information */
|
||||
struct fygue_resolve {
|
||||
enum {
|
||||
FYGUE_FILE_TYPE_FILE,
|
||||
FYGUE_FILE_TYPE_DIR,
|
||||
} type;
|
||||
union {
|
||||
struct {
|
||||
off_t cursor;
|
||||
struct fygue_fat_file fat;
|
||||
} file;
|
||||
struct {
|
||||
struct fygue_fat_dir fat;
|
||||
struct dirent **dirent;
|
||||
int count;
|
||||
int pos;
|
||||
} dir;
|
||||
};
|
||||
/* fygue_open() - open file or directory */
|
||||
extern int fygue_open(char const *path, int flags, mode_t mode);
|
||||
|
||||
|
||||
/* fygue_stat() - get file or directory information */
|
||||
extern int fygue_stat(char const *path, struct stat *statbuf);
|
||||
|
||||
/* fygue_syncfs() - request filesystem re-synchronisation */
|
||||
extern int fygue_syncfs(void *data);
|
||||
|
||||
/* fygue_mount() - mount the filesystem */
|
||||
extern int fygue_mount(struct fygue_fsinfo **fsinfo);
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* fygue_file - file information */
|
||||
struct fygue_file
|
||||
{
|
||||
struct fygue_fat_file fat;
|
||||
off_t cursor;
|
||||
size_t size;
|
||||
char *path;
|
||||
};
|
||||
|
||||
/* fygue_descriptor: internal file descriptor information */
|
||||
/* fygue_dir - directory information */
|
||||
struct fygue_dir
|
||||
{
|
||||
struct fygue_fat_dir fat;
|
||||
struct dirent **dirent;
|
||||
int dirent_idx_max;
|
||||
int count;
|
||||
int pos;
|
||||
char *path;
|
||||
};
|
||||
|
||||
/* fygue_descriptor - fygue file descriptor */
|
||||
struct fygue_descriptor
|
||||
{
|
||||
struct fygue_resolve resolve;
|
||||
char const *path;
|
||||
int flags;
|
||||
enum {
|
||||
FYGUE_DESC_TYPE_FILE,
|
||||
FYGUE_DESC_TYPE_DIR,
|
||||
} type;
|
||||
union {
|
||||
struct fygue_file file;
|
||||
struct fygue_dir dir;
|
||||
};
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
/* fygue_mount(): mount and return the filesystem info */
|
||||
extern int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh);
|
||||
//---
|
||||
// Helper
|
||||
//---
|
||||
|
||||
/* fygue_descriptor_sync(): sync internal descriptor information */
|
||||
extern int fygue_descriptor_sync(
|
||||
struct fygue_fsinfo **fsinfo,
|
||||
/* fygue_open_resolve() - open file or directory */
|
||||
extern int fygue_open_resolve(
|
||||
char const *path,
|
||||
struct fygue_descriptor *desc
|
||||
);
|
||||
|
||||
/* fygue_resolve() - try to resolve path */
|
||||
extern int fygue_resolve(
|
||||
char const * const path,
|
||||
struct fygue_resolve *resolve
|
||||
);
|
||||
|
||||
//---
|
||||
// Directory interface
|
||||
//---
|
||||
|
||||
/* fygue_dir_open(): directory-specific open */
|
||||
extern int fygue_dir_open(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
char const * const path,
|
||||
struct fygue_fat_dir *fat_dir
|
||||
);
|
||||
|
||||
/* fygue_dir_read(): directory read implementation */
|
||||
extern int fygue_dir_read(
|
||||
struct fygue_descriptor *desc,
|
||||
extern ssize_t fygue_dir_read(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
struct dirent **dirent,
|
||||
size_t size
|
||||
);
|
||||
|
||||
/* fygue_dir_lseek(): seek directory */
|
||||
extern off_t fygue_dir_lseek(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
off_t offset,
|
||||
int whence
|
||||
);
|
||||
|
||||
/* fygue_dir_write(): write directory (EISDIR) */
|
||||
extern ssize_t fygue_dir_write(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
void *buffer,
|
||||
size_t size
|
||||
);
|
||||
|
||||
/* fygue_dir_close(): close directory */
|
||||
extern int fygue_dir_close(struct fygue_descriptor *desc);
|
||||
extern int fygue_dir_close(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir
|
||||
);
|
||||
|
||||
/* fygue_dir_sync(): directory-specific sync */
|
||||
extern int fygue_dir_sync(struct fygue_descriptor *desc);
|
||||
extern int fygue_dir_sync(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir
|
||||
);
|
||||
|
||||
//---
|
||||
// File interface
|
||||
//---
|
||||
|
||||
/* fygue_file_open(): file open */
|
||||
extern int fygue_file_open(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
char const * const path,
|
||||
struct fygue_fat_file *fat_file
|
||||
);
|
||||
|
||||
/* fygue_file_read(): read primitive */
|
||||
extern ssize_t fygue_file_read(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
void *buffer,
|
||||
size_t size
|
||||
);
|
||||
|
||||
/* fygue_file_lseek(): seek directory */
|
||||
extern off_t fygue_file_lseek(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
off_t offset,
|
||||
int whence
|
||||
);
|
||||
|
||||
/* fygue_file_write(): write directory (EROFS) */
|
||||
extern ssize_t fygue_file_write(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
void *buffer,
|
||||
size_t size
|
||||
);
|
||||
|
||||
/* fygue_file_close(): close directory */
|
||||
extern int fygue_file_close(struct fygue_descriptor *desc);
|
||||
extern int fygue_file_close(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file
|
||||
);
|
||||
|
||||
/* fygue_file_sync(): file-specific sync */
|
||||
extern int fygue_file_sync(struct fygue_descriptor *desc);
|
||||
extern int fygue_file_sync(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,31 +1,29 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gint/hardware.h>
|
||||
#include "fygue.h"
|
||||
#include "fat/fat.h"
|
||||
|
||||
/* fygue_dir_close(): close directory */
|
||||
int fygue_dir_close(struct fygue_descriptor *desc)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
fygue_fat_dir_close(&(fsinfo->fat), &desc->resolve.dir.fat);
|
||||
if (desc->resolve.dir.dirent != NULL)
|
||||
int fygue_dir_close(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir
|
||||
) {
|
||||
if(gint[HWFS] != HWFS_FUGUE)
|
||||
FYGUE_RET_ERRNO(ENOTSUP);
|
||||
if (fsinfo == NULL || dir == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
fygue_fat_dir_close(&(fsinfo->fat), &(dir->fat));
|
||||
if (dir->dirent != NULL)
|
||||
{
|
||||
for (int i = 0 ; i < desc->resolve.dir.count ; i++) {
|
||||
if (desc->resolve.dir.dirent[i] != NULL)
|
||||
free(desc->resolve.dir.dirent[i]);
|
||||
for (int i = 0 ; i < dir->count ; i++) {
|
||||
if (dir->dirent[i] != NULL)
|
||||
free(dir->dirent[i]);
|
||||
}
|
||||
free(desc->resolve.dir.dirent);
|
||||
free(dir->dirent);
|
||||
}
|
||||
memset(desc, 0x00, sizeof(struct fygue_descriptor));
|
||||
if (dir->path != NULL)
|
||||
free(dir->path);
|
||||
memset(dir, 0x00, sizeof(struct fygue_dir));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,54 +1,24 @@
|
|||
#include "fygue.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* _fygue_dir_discover(): force discover all directory */
|
||||
static void _fygue_dir_discover(struct fygue_descriptor *desc)
|
||||
{
|
||||
struct dirent *ent = NULL;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (fygue_dir_read(desc, &ent, sizeof(ent)) != sizeof(ent))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_dir_lseek(): seek directory */
|
||||
off_t fygue_dir_lseek(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
off_t offset,
|
||||
int whence
|
||||
) {
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_descriptor_sync(NULL, desc) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
if (fsinfo == NULL || dir == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
|
||||
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END)
|
||||
FYGUE_RET_ERRNO(EINVAL);
|
||||
if(whence == SEEK_CUR)
|
||||
offset += desc->resolve.dir.pos;
|
||||
if(whence == SEEK_END) {
|
||||
_fygue_dir_discover(desc);
|
||||
offset += desc->resolve.dir.count;
|
||||
}
|
||||
if(offset < 0 || offset >= desc->resolve.dir.count + 1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
desc->resolve.dir.pos = offset;
|
||||
return desc->resolve.dir.pos;
|
||||
offset += dir->pos;
|
||||
if(whence == SEEK_END)
|
||||
offset += dir->count;
|
||||
if(offset < 0 || offset >= dir->count + 1)
|
||||
FYGUE_RET_ERRNO(EINVAL);
|
||||
|
||||
dir->pos = offset;
|
||||
return dir->pos;
|
||||
}
|
||||
|
|
115
src/fs/fygue/fygue_dir_open.c
Normal file
115
src/fs/fygue/fygue_dir_open.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "fygue.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* realloc a prepare the internal table */
|
||||
static int _fygue_dir_open_table_realloc(struct fygue_dir *dir)
|
||||
{
|
||||
void *tmp;
|
||||
|
||||
tmp = reallocarray(
|
||||
dir->dirent,
|
||||
dir->dirent_idx_max + 16,
|
||||
sizeof(struct dirent)
|
||||
);
|
||||
if (tmp == NULL)
|
||||
FYGUE_RET_ERRNO(ENOMEM);
|
||||
dir->dirent = tmp;
|
||||
dir->dirent_idx_max += 16;
|
||||
for (int i = dir->count ; i < dir->dirent_idx_max ; i++)
|
||||
dir->dirent[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* free internal table */
|
||||
static void _fygue_dir_open_table_free(struct fygue_dir *dir)
|
||||
{
|
||||
if (dir->dirent == NULL)
|
||||
return;
|
||||
for (int i = 0 ; i < dir->dirent_idx_max ; i++) {
|
||||
if (dir->dirent[i] != NULL)
|
||||
free(dir->dirent[i]);
|
||||
}
|
||||
free(dir->dirent);
|
||||
dir->dirent = NULL;
|
||||
}
|
||||
|
||||
/* convert FAT dirent to dirent */
|
||||
static int _fygue_dir_open_convert(
|
||||
struct dirent **dirent,
|
||||
struct fygue_fat_dirent *fat_dirent
|
||||
) {
|
||||
size_t len;
|
||||
|
||||
len = strlen(fat_dirent->name);
|
||||
*dirent = calloc(1, sizeof(struct dirent) + len + 2);
|
||||
if (*dirent == NULL)
|
||||
FYGUE_RET_ERRNO(ENOMEM);
|
||||
(*dirent)->d_ino = fat_dirent->cluster_id;
|
||||
(*dirent)->d_type = DT_REG;
|
||||
memcpy((*dirent)->d_name, fat_dirent->name, len + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* _fygue_dir_open_discover(): discover all dirent */
|
||||
static int _fygue_dir_open_discover(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir
|
||||
) {
|
||||
struct fygue_fat_dirent dirent;
|
||||
int rc;
|
||||
|
||||
while (true)
|
||||
{
|
||||
rc = fygue_fat_dir_read(&(fsinfo->fat), &(dir->fat), &dirent);
|
||||
if (rc == -1)
|
||||
return 0;
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (dir->count >= dir->dirent_idx_max) {
|
||||
if (_fygue_dir_open_table_realloc(dir) != 0)
|
||||
break;
|
||||
}
|
||||
rc = _fygue_dir_open_convert(&(dir->dirent[dir->pos]), &dirent);
|
||||
if (rc != 0)
|
||||
break;
|
||||
dir->count += 1;
|
||||
}
|
||||
_fygue_dir_open_table_free(dir);
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_dir_open(): directory-specific open */
|
||||
int fygue_dir_open(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
char const * const path,
|
||||
struct fygue_fat_dir *fat_dir
|
||||
) {
|
||||
if (fsinfo == NULL || dir == NULL || path == NULL || fat_dir == NULL)
|
||||
return 1;
|
||||
|
||||
memset(dir, 0x00, sizeof(struct fygue_dir));
|
||||
dir->path = strdup(path);
|
||||
if (dir->path == NULL)
|
||||
FYGUE_RET_ERRNO(ENOMEM);
|
||||
dir->dirent_idx_max = 0;
|
||||
dir->dirent = NULL;
|
||||
dir->count = 0;
|
||||
dir->pos = 0;
|
||||
memcpy(&(dir->fat), fat_dir, sizeof(struct fygue_fat_dir));
|
||||
|
||||
if (_fygue_dir_open_discover(fsinfo, dir) != 0) {
|
||||
free(dir->path);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -2,106 +2,25 @@
|
|||
#include <string.h>
|
||||
#include "fygue.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* _fygue_dir_fat_read(): read and update internal cache
|
||||
*
|
||||
* return
|
||||
* -2 no directory found
|
||||
* -1 internal error
|
||||
* 0 success */
|
||||
static int _fygue_dir_fat_read(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_descriptor *desc
|
||||
) {
|
||||
struct fygue_fat_dirent fat_dirent;
|
||||
struct dirent **dirent;
|
||||
void *tmp;
|
||||
size_t len;
|
||||
int rc;
|
||||
|
||||
rc = fygue_fat_dir_read(
|
||||
&(fsinfo->fat),
|
||||
&(desc->resolve.dir.fat),
|
||||
&fat_dirent
|
||||
);
|
||||
if (rc <= -3)
|
||||
return -2;
|
||||
if (rc < 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
tmp = reallocarray(
|
||||
desc->resolve.dir.dirent,
|
||||
desc->resolve.dir.count + 1,
|
||||
sizeof(struct dirent *)
|
||||
);
|
||||
if (tmp == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
desc->resolve.dir.dirent = tmp;
|
||||
desc->resolve.dir.count += 1;
|
||||
//FIXME: ensure UTF-8/SHIFT-JS
|
||||
len = strlen(fat_dirent.name);
|
||||
dirent = &(desc->resolve.dir.dirent[desc->resolve.dir.pos]);
|
||||
*dirent = calloc(1, sizeof(struct dirent) + len + 2);
|
||||
if (*dirent == NULL) {
|
||||
desc->resolve.dir.count -= 1;
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
//FIXME: ensure UTF-8/SHIFT-JS
|
||||
(*dirent)->d_ino = fat_dirent.cluster_id;
|
||||
(*dirent)->d_type = DT_REG;
|
||||
memcpy((*dirent)->d_name, fat_dirent.name, len + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_dir_read(): directory read implementation
|
||||
*
|
||||
* notes
|
||||
* - assume that the directory have read permission */
|
||||
int fygue_dir_read(
|
||||
struct fygue_descriptor *desc,
|
||||
ssize_t fygue_dir_read(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
struct dirent **dirent,
|
||||
size_t size
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
int rc;
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (dirent == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (size < sizeof *dirent) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
if (desc->resolve.dir.pos >= desc->resolve.dir.count)
|
||||
{
|
||||
rc = _fygue_dir_fat_read(fsinfo, desc);
|
||||
if (rc == -2)
|
||||
return 0;
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
*dirent = desc->resolve.dir.dirent[desc->resolve.dir.pos];
|
||||
desc->resolve.dir.pos += 1;
|
||||
if (fsinfo == NULL || dir == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (dirent == NULL)
|
||||
FYGUE_RET_ERRNO(EFAULT);
|
||||
if (size < sizeof *dirent)
|
||||
FYGUE_RET_ERRNO(EINVAL);
|
||||
if (dir->pos >= dir->count)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
*dirent = dir->dirent[dir->pos];
|
||||
dir->pos += 1;
|
||||
return sizeof *dirent;
|
||||
}
|
||||
|
|
|
@ -1,33 +1,58 @@
|
|||
#include <stdlib.h>
|
||||
#include <gint/hardware.h>
|
||||
#include "fygue.h"
|
||||
|
||||
/* fygue_dir_sync(): directory-specific sync */
|
||||
int fygue_dir_sync(struct fygue_descriptor *desc)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
int fygue_dir_sync(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir
|
||||
) {
|
||||
struct fygue_fat_descriptor desc;
|
||||
int saved_pos;
|
||||
int rc;
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
//if (desc->)
|
||||
if (fygue_mount(&fsinfo, true)) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0 ; i < desc->resolve.dir.count ; i++) {
|
||||
if (desc->resolve.dir.dirent[i] == NULL)
|
||||
continue;
|
||||
free(desc->resolve.dir.dirent[i]);
|
||||
desc->resolve.dir.dirent[i] = NULL;
|
||||
}
|
||||
/* preliminary check */
|
||||
if(gint[HWFS] != HWFS_FUGUE)
|
||||
FYGUE_RET_ERRNO(ENOTSUP);
|
||||
if (fsinfo == NULL || dir == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
|
||||
/* update FAT-specific information */
|
||||
//TODO: assume that the first cluster will remain the same ?
|
||||
if (fygue_fat_open(&(fsinfo->fat), dir->path, &desc) != 0)
|
||||
FYGUE_RET_ERRNO(ENOENT);
|
||||
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
rc = fygue_fat_dir_sync(
|
||||
&(fsinfo->fat),
|
||||
&(desc->resolve.dir.fat)
|
||||
&(desc.dir),
|
||||
desc.file.cluster_entry
|
||||
);
|
||||
if (rc != 0)
|
||||
return -2;
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
|
||||
/* refresh internal information */
|
||||
//TODO: re-use realloc
|
||||
if (dir->dirent != NULL)
|
||||
{
|
||||
for (int i = 0 ; i < dir->count ; i++)
|
||||
{
|
||||
if (dir->dirent[i] == NULL)
|
||||
continue;
|
||||
free(dir->dirent[i]);
|
||||
dir->dirent[i] = NULL;
|
||||
}
|
||||
free(dir->dirent);
|
||||
dir->dirent = NULL;
|
||||
dir->count = 0;
|
||||
}
|
||||
/* hack to force regenerate the dirent cache */
|
||||
saved_pos = dir->pos;
|
||||
if (
|
||||
fygue_dir_lseek(fsinfo, dir, 0, SEEK_SET) != 0 ||
|
||||
fygue_dir_lseek(fsinfo, dir, saved_pos, SEEK_SET) != 0
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,21 +2,16 @@
|
|||
|
||||
/* fygue_dir_write(): write directory (EISDIR) */
|
||||
ssize_t fygue_dir_write(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_dir *dir,
|
||||
void *buffer,
|
||||
size_t size
|
||||
) {
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (buffer == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (size == 0)
|
||||
return 0;
|
||||
errno = EISDIR;
|
||||
return -1;
|
||||
if (fsinfo == NULL || dir == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (buffer == NULL)
|
||||
FYGUE_RET_ERRNO(EFAULT);
|
||||
if (size != 0)
|
||||
FYGUE_RET_ERRNO(EISDIR);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fygue.h"
|
||||
#include "fat/fat.h"
|
||||
|
||||
/* fygue_file_close(): close directory */
|
||||
int fygue_file_close(struct fygue_descriptor *desc)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
fygue_fat_file_close(&(fsinfo->fat), &desc->resolve.file.fat);
|
||||
memset(desc, 0x00, sizeof(struct fygue_descriptor));
|
||||
int fygue_file_close(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file
|
||||
) {
|
||||
if (fsinfo == NULL || file == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
fygue_fat_file_close(&(fsinfo->fat), &(file->fat));
|
||||
free(file);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,38 +2,26 @@
|
|||
|
||||
/* fygue_file_lseek(): seek file */
|
||||
off_t fygue_file_lseek(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
off_t offset,
|
||||
int whence
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
if (fsinfo == NULL || file == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END)
|
||||
FYGUE_RET_ERRNO(EINVAL);
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
if(whence == SEEK_CUR)
|
||||
offset += desc->resolve.dir.pos;
|
||||
offset += file->cursor;
|
||||
if(whence == SEEK_END)
|
||||
offset += desc->resolve.file.size;
|
||||
if(offset < 0 || offset >= desc->resolve.file.size + 1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
desc->resolve.file.cursor = offset;
|
||||
fygue_fat_file_seek(
|
||||
&(fsinfo->fat),
|
||||
&(desc->resolve.file.fat),
|
||||
offset
|
||||
);
|
||||
return desc->resolve.file.cursor;
|
||||
offset += file->size;
|
||||
if(offset < 0 || (unsigned)offset >= file->size + 1)
|
||||
FYGUE_RET_ERRNO(EINVAL);
|
||||
|
||||
if (fygue_fat_file_seek(&(fsinfo->fat), &(file->fat), offset) != 0)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
|
||||
file->cursor = offset;
|
||||
return file->cursor;
|
||||
}
|
||||
|
|
21
src/fs/fygue/fygue_file_open.c
Normal file
21
src/fs/fygue/fygue_file_open.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <string.h>
|
||||
#include "fygue.h"
|
||||
|
||||
/* fygue_file_open(): file open */
|
||||
int fygue_file_open(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
char const * const path,
|
||||
struct fygue_fat_file *fat_file
|
||||
) {
|
||||
if (fsinfo == NULL || file == NULL || path == NULL || fat_file == NULL)
|
||||
return -1;
|
||||
|
||||
memset(file, 0x00, sizeof(struct fygue_file));
|
||||
file->path = strdup(path);
|
||||
if (file->path == NULL)
|
||||
FYGUE_RET_ERRNO(ENOMEM);
|
||||
file->cursor = 0;
|
||||
memcpy(&(file->fat), fat_file, sizeof(struct fygue_fat_file));
|
||||
return 0;
|
||||
}
|
|
@ -1,35 +1,19 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fygue.h"
|
||||
|
||||
/* fygue_file_read(): write directory (EISDIR) */
|
||||
/* fygue_file_read(): read file data */
|
||||
ssize_t fygue_file_read(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
void *buffer,
|
||||
size_t size
|
||||
) {
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (buffer == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_file_sync(desc) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_mount(&fsinfo, true) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
if (fsinfo == NULL || file == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (buffer == NULL)
|
||||
FYGUE_RET_ERRNO(EFAULT);
|
||||
return fygue_fat_file_read(
|
||||
&(fsinfo->fat),
|
||||
&(desc->resolve.file.fat),
|
||||
&(file->fat),
|
||||
buffer,
|
||||
size
|
||||
);
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
#include <gint/hardware.h>
|
||||
#include "fygue.h"
|
||||
|
||||
/* fygue_file_sync(): file-specific sync */
|
||||
int fygue_file_sync(struct fygue_descriptor *desc)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
int fygue_file_sync(
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file
|
||||
) {
|
||||
struct fygue_fat_descriptor desc;
|
||||
int rc;
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_mount(&fsinfo, true)) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
// nothing to sync in high-level
|
||||
if(gint[HWFS] != HWFS_FUGUE)
|
||||
FYGUE_RET_ERRNO(ENOTSUP);
|
||||
if (fsinfo == NULL || file == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
|
||||
//TODO: assume that the first cluster will remain the same ?
|
||||
if (fygue_fat_open(&(fsinfo->fat), file->path, &desc) != 0)
|
||||
FYGUE_RET_ERRNO(ENOENT);
|
||||
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
rc = fygue_fat_file_sync(
|
||||
&(fsinfo->fat),
|
||||
&(desc->resolve.file.fat)
|
||||
&(desc.file),
|
||||
desc.file.cluster_entry
|
||||
);
|
||||
if (rc != 0)
|
||||
return -1;
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,21 +2,16 @@
|
|||
|
||||
/* fygue_file_write(): write directory (EISDIR) */
|
||||
ssize_t fygue_file_write(
|
||||
struct fygue_descriptor *desc,
|
||||
struct fygue_fsinfo *fsinfo,
|
||||
struct fygue_file *file,
|
||||
void *buffer,
|
||||
size_t size
|
||||
) {
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (buffer == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (size == 0)
|
||||
return 0;
|
||||
errno = EROFS;
|
||||
return -1;
|
||||
if (fsinfo == NULL || file == NULL)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (buffer == NULL)
|
||||
FYGUE_RET_ERRNO(EFAULT);
|
||||
if (size != 0)
|
||||
FYGUE_RET_ERRNO(EROFS);
|
||||
return 0;
|
||||
}
|
||||
|
|
45
src/fs/fygue/fygue_mount.c
Normal file
45
src/fs/fygue/fygue_mount.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <stdlib.h>
|
||||
#include "fygue.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* __fygue_fsinfo: internal filesystem information */
|
||||
static struct fygue_fsinfo *__fygue_fsinfo = NULL;
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_mount() - mount (if needed) and return the filesystem information
|
||||
*
|
||||
* notes
|
||||
* - assume that this global is const after initialisation */
|
||||
int fygue_mount(struct fygue_fsinfo **fsinfo)
|
||||
{
|
||||
if (fsinfo == NULL)
|
||||
return -1;
|
||||
*fsinfo = NULL;
|
||||
if (__fygue_fsinfo == NULL)
|
||||
{
|
||||
__fygue_fsinfo = calloc(1, sizeof(struct fygue_fsinfo));
|
||||
if (__fygue_fsinfo == NULL)
|
||||
return -2;
|
||||
if (fygue_fat_initialize(&(__fygue_fsinfo->fat)) != 0)
|
||||
{
|
||||
free(__fygue_fsinfo);
|
||||
__fygue_fsinfo = NULL;
|
||||
return -3;
|
||||
}
|
||||
__fygue_fsinfo->dirty = false;
|
||||
}
|
||||
if (__fygue_fsinfo->dirty)
|
||||
{
|
||||
if (fygue_fat_sync(&(__fygue_fsinfo->fat)) != 0)
|
||||
return -4;
|
||||
__fygue_fsinfo->dirty = false;
|
||||
}
|
||||
*fsinfo = __fygue_fsinfo;
|
||||
return 0;
|
||||
}
|
|
@ -2,65 +2,86 @@
|
|||
#include <stdlib.h>
|
||||
#include <gint/gint.h>
|
||||
#include <gint/bfile.h>
|
||||
#include <gint/hardware.h>
|
||||
#include "../fugue/fugue.h"
|
||||
#include "fygue.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_open_resolve() - try to resolve path
|
||||
*
|
||||
* notes
|
||||
* - assume that path is clean
|
||||
* - automatically mount the filesystem if needed
|
||||
* - the saved pathname will not be saved in stat */
|
||||
int fygue_open_resolve(
|
||||
char const * const path,
|
||||
struct fygue_descriptor *desc
|
||||
) {
|
||||
struct fygue_fat_descriptor fat_desc;
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
if (path == NULL || path[0] != '/' || desc == NULL)
|
||||
return -1;
|
||||
if (fygue_mount(&fsinfo) != 0)
|
||||
return -2;
|
||||
if (fygue_fat_open(&(fsinfo->fat), path, &fat_desc) != 0)
|
||||
return -3;
|
||||
memset(desc, 0x00, sizeof(struct fygue_descriptor));
|
||||
if (fat_desc.type == FYGUE_FAT_DESC_TYPE_DIR)
|
||||
{
|
||||
desc->type = FYGUE_DESC_TYPE_DIR;
|
||||
return fygue_dir_open(fsinfo, &(desc->dir), path, &(fat_desc.dir));
|
||||
}
|
||||
desc->type = FYGUE_DESC_TYPE_FILE;
|
||||
return fygue_file_open(fsinfo, &(desc->file), path, &fat_desc.file);
|
||||
}
|
||||
|
||||
/* fygue_open(): open primitive */
|
||||
int fygue_open(char const *path, int flags, GUNUSED mode_t mode)
|
||||
{
|
||||
struct fygue_descriptor *desc;
|
||||
struct fygue_resolve resolve;
|
||||
fs_descriptor_t data;
|
||||
struct fygue_descriptor desc;
|
||||
fs_descriptor_t gint_desc;
|
||||
int exists;
|
||||
|
||||
if ((flags & O_RDWR) || (flags & O_WRONLY)) {
|
||||
errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
/* preliminary checks */
|
||||
if(gint[HWFS] != HWFS_FUGUE)
|
||||
FYGUE_RET_ERRNO(ENOTSUP);
|
||||
if ((flags & O_RDWR) || (flags & O_WRONLY))
|
||||
FYGUE_RET_ERRNO(EROFS);
|
||||
|
||||
/* resolve the entry */
|
||||
int exists = fygue_resolve(path, &resolve);
|
||||
exists = fygue_open_resolve(path, &desc);
|
||||
|
||||
/* if opening fails and no explicit file creation is required, fail */
|
||||
if ((exists < 0 && (!(flags & O_CREAT) || (flags & O_DIRECTORY)))) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((exists < 0 && (!(flags & O_CREAT) || (flags & O_DIRECTORY))))
|
||||
FYGUE_RET_ERRNO(ENOENT);
|
||||
|
||||
/* if opening fails and the previous check as not returned an error,
|
||||
* it is certainly because of a creation request. We are a read-only
|
||||
* file-system, so, fail */
|
||||
if (exists < 0) {
|
||||
errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
if (exists < 0)
|
||||
FYGUE_RET_ERRNO(EROFS);
|
||||
|
||||
/* If the entry exists and O_EXCL was requested, fail.
|
||||
* note that Exclusive open means no sense unless creation is also
|
||||
* requested */
|
||||
if(exists >= 0 && (flags & O_EXCL)) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
if(exists >= 0 && (flags & O_EXCL))
|
||||
FYGUE_RET_ERRNO(EEXIST);
|
||||
|
||||
/* generate the final file descriptor */
|
||||
desc = calloc(1, sizeof(struct fygue_descriptor));
|
||||
if (desc == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
gint_desc.type = &fygue_file_descriptor_type;
|
||||
gint_desc.data = calloc(1, sizeof(struct fygue_descriptor));
|
||||
if (gint_desc.data == NULL)
|
||||
FYGUE_RET_ERRNO(ENOMEM);
|
||||
memcpy(gint_desc.data, &desc, sizeof(struct fygue_descriptor));
|
||||
if (flags & O_DIRECTORY)
|
||||
{
|
||||
if (desc.type != FYGUE_DESC_TYPE_DIR)
|
||||
FYGUE_RET_ERRNO(ENOTDIR);
|
||||
gint_desc.type = &fygue_dir_descriptor_type;
|
||||
}
|
||||
desc->path = strdup(path);
|
||||
desc->flags = flags;
|
||||
memcpy(&(desc->resolve), &resolve, sizeof(struct fygue_resolve));
|
||||
data.type = &fygue_descriptor_type;
|
||||
data.data = desc;
|
||||
if (flags & O_DIRECTORY) {
|
||||
if (resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
data.type = &fygue_dir_descriptor_type;
|
||||
}
|
||||
return fs_create_descriptor(&data);
|
||||
return fs_create_descriptor(&gint_desc);
|
||||
}
|
||||
|
|
|
@ -1,35 +1,22 @@
|
|||
#include <gint/hardware.h>
|
||||
#include "fygue.h"
|
||||
#include "fat/fat.h"
|
||||
|
||||
/* fygue_stat(): stat primitive */
|
||||
int fygue_stat(char const * const path, struct stat *statbuf)
|
||||
{
|
||||
struct fygue_resolve resolve;
|
||||
struct fygue_descriptor desc;
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
|
||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||
if (path == NULL || statbuf == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_mount(&fsinfo, true) != 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
if (fygue_resolve(path, &resolve) != 0) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
if (resolve.type == FYGUE_FILE_TYPE_DIR) {
|
||||
fygue_fat_dir_stat(
|
||||
&(fsinfo->fat),
|
||||
&(resolve.dir.fat),
|
||||
statbuf
|
||||
);
|
||||
}
|
||||
return fygue_fat_file_stat(
|
||||
&(fsinfo->fat),
|
||||
&(resolve.file.fat),
|
||||
statbuf
|
||||
);
|
||||
if(gint[HWFS] != HWFS_FUGUE)
|
||||
FYGUE_RET_ERRNO(ENOTSUP);
|
||||
if (path == NULL || statbuf == NULL)
|
||||
FYGUE_RET_ERRNO(EFAULT);
|
||||
if (fygue_mount(&fsinfo) != 0)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
if (fygue_open_resolve(path, &desc) != 0)
|
||||
FYGUE_RET_ERRNO(ENOENT);
|
||||
if (desc.type == FYGUE_DESC_TYPE_DIR)
|
||||
return fygue_fat_dir_stat(&(fsinfo->fat), &(desc.dir.fat), statbuf);
|
||||
return fygue_fat_file_stat(&(fsinfo->fat), &(desc.file.fat), statbuf);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
#include <gint/hardware.h>
|
||||
#include "fygue.h"
|
||||
|
||||
/* fygue_syncfs() - request filesystem re-synchronisation */
|
||||
int fygue_syncfs(void *data)
|
||||
{
|
||||
struct fygue_fsinfo *fsinfo;
|
||||
struct fygue_descriptor *descriptor;
|
||||
struct fygue_descriptor *desc;
|
||||
|
||||
if(gint[HWFS] != HWFS_FUGUE)
|
||||
FYGUE_RET_ERRNO(ENOTSUP);
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
if (fygue_mount(&fsinfo, false) != 0)
|
||||
return -2;
|
||||
descriptor = data;
|
||||
descriptor->dirty = true;
|
||||
FYGUE_RET_ERRNO(EBADF);
|
||||
if (fygue_mount(&fsinfo) != 0)
|
||||
FYGUE_RET_ERRNO(EIO);
|
||||
desc = data;
|
||||
desc->dirty = true;
|
||||
fsinfo->dirty = true;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue