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_open.c
|
||||||
src/fs/fygue/fygue_syncfs.c
|
src/fs/fygue/fygue_syncfs.c
|
||||||
src/fs/fygue/fygue_stat.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_read.c
|
||||||
src/fs/fygue/fygue_dir_lseek.c
|
|
||||||
src/fs/fygue/fygue_dir_write.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_dir_close.c
|
||||||
src/fs/fygue/fygue_file_lseek.c
|
src/fs/fygue/fygue_dir_sync.c
|
||||||
src/fs/fygue/fygue_file_write.c
|
src/fs/fygue/fygue_file_open.c
|
||||||
src/fs/fygue/fygue_file_close.c
|
|
||||||
src/fs/fygue/fygue_file_read.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/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_open.c
|
||||||
src/fs/fygue/fat/fat_dir_read.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_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_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_read.c
|
||||||
src/fs/fygue/fat/fat_file_seek.c
|
src/fs/fygue/fat/fat_file_seek.c
|
||||||
src/fs/fygue/fat/resolve.c
|
src/fs/fygue/fat/fat_file_stat.c
|
||||||
src/fs/fygue/fat/sector.c
|
src/fs/fygue/fat/fat_file_close.c
|
||||||
src/fs/fygue/flash/cluster.c
|
src/fs/fygue/fat/fat_file_sync.c
|
||||||
src/fs/fygue/flash/cmap.c
|
src/fs/fygue/fat/fat_open.c
|
||||||
src/fs/fygue/flash/flash.c
|
src/fs/fygue/fat/flash/cluster.c
|
||||||
src/fs/fygue/flash/sector.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)
|
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 (
|
return (
|
||||||
(desc->type == &fygue_dir_descriptor_type) ||
|
(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
|
** fygue/fat/cluster - FAT cluster handling
|
||||||
*/
|
*/
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
#include "../flash/flash.h"
|
#include "flash/flash.h"
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Internals
|
// Internals
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "../flash/flash.h"
|
#include "flash/flash.h"
|
||||||
|
|
||||||
/* _FAT_WORD() : helper for 16bit value */
|
/* _FAT_WORD() : helper for 16bit value */
|
||||||
#define FAT_WORD(x) \
|
#define FAT_WORD(x) \
|
||||||
(((x & 0xff00) >> 8) | ((x & 0x00ff) << 8))
|
(((x & 0xff00) >> 8) | ((x & 0x00ff) << 8))
|
||||||
|
|
||||||
/* _FAT_DWORD() : helper for 32bit value */
|
/* _FAT_DWORD() : helper for 32bit value */
|
||||||
#define FAT_DWORD(x) ( \
|
#define FAT_DWORD(x) ( \
|
||||||
(((x) & 0xff000000) >> 24) \
|
(((x) & 0xff000000) >> 24) \
|
||||||
| (((x) & 0x00ff0000) >> 8) \
|
| (((x) & 0x00ff0000) >> 8) \
|
||||||
| (((x) & 0x0000ff00) << 8) \
|
| (((x) & 0x0000ff00) << 8) \
|
||||||
|
@ -94,12 +94,12 @@ struct fygue_fat_file
|
||||||
int chunk_rd_offset;
|
int chunk_rd_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fygue_fat_resolve: internal resolve information */
|
/* fygue_fat_descriptor: FAT descriptor information */
|
||||||
struct fygue_fat_resolve
|
struct fygue_fat_descriptor
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
FYGUE_FAT_FILE_TYPE_FILE,
|
FYGUE_FAT_DESC_TYPE_FILE,
|
||||||
FYGUE_FAT_FILE_TYPE_DIR,
|
FYGUE_FAT_DESC_TYPE_DIR,
|
||||||
} type;
|
} type;
|
||||||
union {
|
union {
|
||||||
struct fygue_fat_file file;
|
struct fygue_fat_file file;
|
||||||
|
@ -107,17 +107,21 @@ struct fygue_fat_resolve
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Public interface
|
||||||
|
//---
|
||||||
|
|
||||||
/* fygue_fat_initialize() - fully initialize the FAT information */
|
/* fygue_fat_initialize() - fully initialize the FAT information */
|
||||||
extern int fygue_fat_initialize(struct fygue_fat *fat);
|
extern int fygue_fat_initialize(struct fygue_fat *fat);
|
||||||
|
|
||||||
/* fygue_fat_sync() - re-initialize the FAT information */
|
/* fygue_fat_sync() - re-initialize the FAT information */
|
||||||
extern int fygue_fat_sync(struct fygue_fat *fat);
|
extern int fygue_fat_sync(struct fygue_fat *fat);
|
||||||
|
|
||||||
/* fygue_fat_resolve() - resolve the path and set the dirent information */
|
/* fygue_fat_open() - resolve the path and set the dirent information */
|
||||||
extern int fygue_fat_resolve(
|
extern int fygue_fat_open(
|
||||||
struct fygue_fat *fat,
|
struct fygue_fat *fat,
|
||||||
char const * const path,
|
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 */
|
/* fygue_fat_dir_sync(): sync directory information */
|
||||||
extern int fygue_fat_dir_sync(
|
extern int fygue_fat_dir_sync(
|
||||||
struct fygue_fat *fat,
|
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 */
|
/* fygue_fat_file_sync(): sync internal information */
|
||||||
extern int fygue_fat_file_sync(
|
extern int fygue_fat_file_sync(
|
||||||
struct fygue_fat *fat,
|
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_dir *dir,
|
||||||
struct fygue_fat_dirent *dirent
|
struct fygue_fat_dirent *dirent
|
||||||
) {
|
) {
|
||||||
int rc;
|
|
||||||
|
|
||||||
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
|
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
|
||||||
if (dirent == NULL) {
|
if (dirent == NULL) {
|
||||||
dir->cluster_entry = 0;
|
dir->cluster_entry = 0;
|
||||||
dir->root_dirent_count = fat->RootEntCount;
|
dir->root_dirent_count = fat->RootEntCount;
|
||||||
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
|
dir->attribute = FYGUE_FAT_DESC_TYPE_DIR;
|
||||||
} else {
|
} else {
|
||||||
if ((dirent->attribute & FYGUE_FAT_FILE_TYPE_DIR) == 0x00)
|
if ((dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY) == 0x00)
|
||||||
return -1;
|
return -1;
|
||||||
dir->cluster_entry = dirent->cluster_id;
|
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->root_dirent_count = 0;
|
||||||
}
|
}
|
||||||
dir->dirty = false;
|
return fygue_fat_dir_sync(fat, dir, dir->cluster_entry);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,32 @@
|
||||||
/* fygue_fat_dir_sync(): sync directory information */
|
/* fygue_fat_dir_sync(): sync directory information */
|
||||||
int fygue_fat_dir_sync(
|
int fygue_fat_dir_sync(
|
||||||
struct fygue_fat *fat,
|
struct fygue_fat *fat,
|
||||||
struct fygue_fat_dir *dir
|
struct fygue_fat_dir *dir,
|
||||||
|
int cluster_id
|
||||||
) {
|
) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (fat == NULL || dir == NULL)
|
if (fat == NULL || dir == NULL)
|
||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ int fygue_fat_file_open(
|
||||||
file->chunk = NULL;
|
file->chunk = NULL;
|
||||||
file->chunk_count = 0;
|
file->chunk_count = 0;
|
||||||
file->chunk_table_max_index = 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;
|
return -1;
|
||||||
if (fygue_fat_file_seek(fat, file, 0) != 0)
|
if (fygue_fat_file_seek(fat, file, 0) != 0)
|
||||||
return -2;
|
return -2;
|
||||||
|
|
|
@ -60,15 +60,15 @@ static int _fygue_chunk_error(struct fygue_fat_file *file)
|
||||||
/* fygue_fat_file_sync(): sync internal information */
|
/* fygue_fat_file_sync(): sync internal information */
|
||||||
int fygue_fat_file_sync(
|
int fygue_fat_file_sync(
|
||||||
struct fygue_fat *fat,
|
struct fygue_fat *fat,
|
||||||
struct fygue_fat_file *file
|
struct fygue_fat_file *file,
|
||||||
|
int cluster_id
|
||||||
) {
|
) {
|
||||||
uintptr_t cluster_addr;
|
uintptr_t cluster_addr;
|
||||||
int cluster_id;
|
|
||||||
|
|
||||||
if (fat == NULL || file == NULL)
|
if (fat == NULL || file == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
file->chunk_count = 0;
|
file->chunk_count = 0;
|
||||||
cluster_id = file->cluster_entry;
|
file->cluster_entry = cluster_id;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (fygue_fat_cluster_get_addr(fat, &cluster_addr, cluster_id) != 0)
|
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 */
|
/* _fygue_resolve_set(): setup the resolve response */
|
||||||
static int _fygue_resolve_set(
|
static int _fygue_resolve_set(
|
||||||
struct fygue_fat *fat,
|
struct fygue_fat *fat,
|
||||||
struct fygue_fat_resolve *resolve,
|
struct fygue_fat_descriptor *desc,
|
||||||
struct fygue_fat_dirent *dirent
|
struct fygue_fat_dirent *dirent
|
||||||
) {
|
) {
|
||||||
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
|
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
|
||||||
resolve->type = FYGUE_FAT_FILE_TYPE_DIR;
|
desc->type = FYGUE_FAT_DESC_TYPE_DIR;
|
||||||
return fygue_fat_dir_open(fat, &(resolve->dir), dirent);
|
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
|
* notes
|
||||||
* - assume that the path is clean */
|
* - assume that the path is clean */
|
||||||
int fygue_fat_resolve(
|
int fygue_fat_open(
|
||||||
struct fygue_fat *fat,
|
struct fygue_fat *fat,
|
||||||
char const * const path,
|
char const * const path,
|
||||||
struct fygue_fat_resolve *resolve
|
struct fygue_fat_descriptor *desc
|
||||||
) {
|
) {
|
||||||
struct fygue_fat_dirent dirent;
|
struct fygue_fat_dirent dirent;
|
||||||
struct fygue_fat_dir dir;
|
struct fygue_fat_dir dir;
|
||||||
|
@ -83,7 +84,7 @@ int fygue_fat_resolve(
|
||||||
size_t len;
|
size_t len;
|
||||||
bool is_root;
|
bool is_root;
|
||||||
|
|
||||||
if (fat == NULL || path == NULL || resolve == NULL)
|
if (fat == NULL || path == NULL || desc == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (path[0] != '/')
|
if (path[0] != '/')
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -107,6 +108,6 @@ int fygue_fat_resolve(
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
if (is_root)
|
if (is_root)
|
||||||
return _fygue_resolve_set(fat, resolve, NULL);
|
return _fygue_resolve_set(fat, desc, NULL);
|
||||||
return _fygue_resolve_set(fat, resolve, &dirent);
|
return _fygue_resolve_set(fat, desc, &dirent);
|
||||||
}
|
}
|
|
@ -1,129 +1,171 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <gint/hardware.h>
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Internals
|
// Internals
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* __fygue_fsinfo: internal filesystem information */
|
/* FYGUE_GFDI_CHEK - shorthand for all GFDI prologue */
|
||||||
static struct fygue_fsinfo *__fygue_fsinfo = NULL;
|
#define FYGUE_GFDI_CHEK(type) \
|
||||||
|
_fygue_gfdi_ensure_valid(&fsinfo, desc, type)
|
||||||
|
|
||||||
//---
|
/* _fygue_gfdi_ensure_valid(): ensure GFDI validity
|
||||||
// Primitives
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* fygue_mount() - mount (if needed) and return the filesystem information
|
|
||||||
*
|
*
|
||||||
* notes
|
* notes:
|
||||||
* - assume that this global is const after initialisation */
|
* - assume info is not NULL
|
||||||
int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh)
|
* - auto mount the FS (if needed) and get information
|
||||||
{
|
* - ensure file sync if needed */
|
||||||
if (fsinfo == NULL)
|
static int _fygue_gfdi_ensure_valid(
|
||||||
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(
|
|
||||||
struct fygue_fsinfo **fsinfo,
|
struct fygue_fsinfo **fsinfo,
|
||||||
struct fygue_descriptor *desc
|
struct fygue_descriptor *desc,
|
||||||
|
unsigned int type
|
||||||
) {
|
) {
|
||||||
int (*sync)(struct fygue_descriptor*);
|
int rc;
|
||||||
struct fygue_fsinfo *ffsinfo;
|
|
||||||
|
|
||||||
if (fygue_mount(&ffsinfo, true) != 0)
|
if(gint[HWFS] != HWFS_FUGUE)
|
||||||
return -2;
|
FYGUE_RET_ERRNO(ENOTSUP);
|
||||||
if (fsinfo != NULL)
|
if (fsinfo == NULL)
|
||||||
*fsinfo = ffsinfo;
|
FYGUE_RET_ERRNO(EIO);
|
||||||
if (desc != NULL && desc->dirty)
|
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->type == FYGUE_DESC_TYPE_DIR)
|
||||||
if (desc->resolve.type == FYGUE_FILE_TYPE_DIR)
|
rc = fygue_dir_sync(*fsinfo, &(desc->dir));
|
||||||
sync = &fygue_dir_sync;
|
if (desc->type == FYGUE_DESC_TYPE_FILE)
|
||||||
if (sync(desc) != 0)
|
rc = fygue_file_sync(*fsinfo, &(desc->file));
|
||||||
return -1;
|
if (rc != 0)
|
||||||
|
FYGUE_RET_ERRNO(EIO);
|
||||||
desc->dirty = false;
|
desc->dirty = false;
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
// Descriptor
|
||||||
//---
|
//---
|
||||||
|
|
||||||
const fs_descriptor_type_t fygue_descriptor_type = {
|
/* fygue_file_descriptor_type - fygue file descriptor */
|
||||||
.read = (void*)&fygue_file_read,
|
const fs_descriptor_type_t fygue_file_descriptor_type = {
|
||||||
.write = (void*)&fygue_file_write,
|
.read = (void*)&fygue_gfdi_file_read,
|
||||||
.lseek = (void*)&fygue_file_lseek,
|
.write = (void*)&fygue_gfdi_file_write,
|
||||||
.close = (void*)&fygue_file_close,
|
.lseek = (void*)&fygue_gfdi_file_lseek,
|
||||||
|
.close = (void*)&fygue_gfdi_file_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
const fs_descriptor_type_t fygue_dir_descriptor_type = {
|
const fs_descriptor_type_t fygue_dir_descriptor_type = {
|
||||||
.read = (void*)&fygue_dir_read,
|
.read = (void*)&fygue_gfdi_dir_read,
|
||||||
.write = (void*)&fygue_dir_write,
|
.write = (void*)&fygue_gfdi_dir_write,
|
||||||
.lseek = (void*)&fygue_dir_lseek,
|
.lseek = (void*)&fygue_gfdi_dir_lseek,
|
||||||
.close = (void*)&fygue_dir_close,
|
.close = (void*)&fygue_gfdi_dir_close,
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,13 +10,15 @@ extern "C" {
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <gint/fs.h>
|
#include <gint/fs.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "fat/fat.h"
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Public global
|
// Public global
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* File descriptor type */
|
/* 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 */
|
/* Directory descriptor type */
|
||||||
extern const fs_descriptor_type_t fygue_dir_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
|
// Public (low-level) API
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* fygue_open() - open file or directory */
|
/* helper to set errno and return -1 */
|
||||||
extern int fygue_open(char const *path, int flags, mode_t mode);
|
#define FYGUE_RET_ERRNO(error) \
|
||||||
|
do { errno = error; return -1; } while(0);
|
||||||
/* 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"
|
|
||||||
|
|
||||||
/* fygue_fsinfo: internal fygue FS information */
|
/* fygue_fsinfo: internal fygue FS information */
|
||||||
struct fygue_fsinfo
|
struct fygue_fsinfo
|
||||||
|
@ -55,111 +37,162 @@ struct fygue_fsinfo
|
||||||
bool dirty;
|
bool dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fygue_resolve: internals file information */
|
/* fygue_open() - open file or directory */
|
||||||
struct fygue_resolve {
|
extern int fygue_open(char const *path, int flags, mode_t mode);
|
||||||
enum {
|
|
||||||
FYGUE_FILE_TYPE_FILE,
|
|
||||||
FYGUE_FILE_TYPE_DIR,
|
/* fygue_stat() - get file or directory information */
|
||||||
} type;
|
extern int fygue_stat(char const *path, struct stat *statbuf);
|
||||||
union {
|
|
||||||
struct {
|
/* fygue_syncfs() - request filesystem re-synchronisation */
|
||||||
off_t cursor;
|
extern int fygue_syncfs(void *data);
|
||||||
struct fygue_fat_file fat;
|
|
||||||
} file;
|
/* fygue_mount() - mount the filesystem */
|
||||||
struct {
|
extern int fygue_mount(struct fygue_fsinfo **fsinfo);
|
||||||
struct fygue_fat_dir fat;
|
|
||||||
struct dirent **dirent;
|
//---
|
||||||
int count;
|
// Internals
|
||||||
int pos;
|
//---
|
||||||
} dir;
|
|
||||||
};
|
/* 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_descriptor
|
||||||
{
|
{
|
||||||
struct fygue_resolve resolve;
|
enum {
|
||||||
char const *path;
|
FYGUE_DESC_TYPE_FILE,
|
||||||
int flags;
|
FYGUE_DESC_TYPE_DIR,
|
||||||
|
} type;
|
||||||
|
union {
|
||||||
|
struct fygue_file file;
|
||||||
|
struct fygue_dir dir;
|
||||||
|
};
|
||||||
bool dirty;
|
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 */
|
/* fygue_open_resolve() - open file or directory */
|
||||||
extern int fygue_descriptor_sync(
|
extern int fygue_open_resolve(
|
||||||
struct fygue_fsinfo **fsinfo,
|
char const *path,
|
||||||
struct fygue_descriptor *desc
|
struct fygue_descriptor *desc
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_resolve() - try to resolve path */
|
|
||||||
extern int fygue_resolve(
|
|
||||||
char const * const path,
|
|
||||||
struct fygue_resolve *resolve
|
|
||||||
);
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Directory interface
|
// 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 */
|
/* fygue_dir_read(): directory read implementation */
|
||||||
extern int fygue_dir_read(
|
extern ssize_t fygue_dir_read(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_dir *dir,
|
||||||
struct dirent **dirent,
|
struct dirent **dirent,
|
||||||
size_t size
|
size_t size
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_dir_lseek(): seek directory */
|
/* fygue_dir_lseek(): seek directory */
|
||||||
extern off_t fygue_dir_lseek(
|
extern off_t fygue_dir_lseek(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_dir *dir,
|
||||||
off_t offset,
|
off_t offset,
|
||||||
int whence
|
int whence
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_dir_write(): write directory (EISDIR) */
|
/* fygue_dir_write(): write directory (EISDIR) */
|
||||||
extern ssize_t fygue_dir_write(
|
extern ssize_t fygue_dir_write(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_dir *dir,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
size_t size
|
size_t size
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_dir_close(): close directory */
|
/* 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 */
|
/* 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
|
// 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 */
|
/* fygue_file_read(): read primitive */
|
||||||
extern ssize_t fygue_file_read(
|
extern ssize_t fygue_file_read(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_file *file,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
size_t size
|
size_t size
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_file_lseek(): seek directory */
|
/* fygue_file_lseek(): seek directory */
|
||||||
extern off_t fygue_file_lseek(
|
extern off_t fygue_file_lseek(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_file *file,
|
||||||
off_t offset,
|
off_t offset,
|
||||||
int whence
|
int whence
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_file_write(): write directory (EROFS) */
|
/* fygue_file_write(): write directory (EROFS) */
|
||||||
extern ssize_t fygue_file_write(
|
extern ssize_t fygue_file_write(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_file *file,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
size_t size
|
size_t size
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_file_close(): close directory */
|
/* 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 */
|
/* 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,29 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <gint/hardware.h>
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
#include "fat/fat.h"
|
#include "fat/fat.h"
|
||||||
|
|
||||||
/* fygue_dir_close(): close directory */
|
/* fygue_dir_close(): close directory */
|
||||||
int fygue_dir_close(struct fygue_descriptor *desc)
|
int fygue_dir_close(
|
||||||
{
|
struct fygue_fsinfo *fsinfo,
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_dir *dir
|
||||||
|
) {
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if(gint[HWFS] != HWFS_FUGUE)
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
FYGUE_RET_ERRNO(ENOTSUP);
|
||||||
errno = EBADF;
|
if (fsinfo == NULL || dir == NULL)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(EIO);
|
||||||
}
|
fygue_fat_dir_close(&(fsinfo->fat), &(dir->fat));
|
||||||
if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
|
if (dir->dirent != NULL)
|
||||||
errno = EIO;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fygue_fat_dir_close(&(fsinfo->fat), &desc->resolve.dir.fat);
|
|
||||||
if (desc->resolve.dir.dirent != NULL)
|
|
||||||
{
|
{
|
||||||
for (int i = 0 ; i < desc->resolve.dir.count ; i++) {
|
for (int i = 0 ; i < dir->count ; i++) {
|
||||||
if (desc->resolve.dir.dirent[i] != NULL)
|
if (dir->dirent[i] != NULL)
|
||||||
free(desc->resolve.dir.dirent[i]);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +1,24 @@
|
||||||
#include "fygue.h"
|
#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 */
|
/* fygue_dir_lseek(): seek directory */
|
||||||
off_t fygue_dir_lseek(
|
off_t fygue_dir_lseek(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_dir *dir,
|
||||||
off_t offset,
|
off_t offset,
|
||||||
int whence
|
int whence
|
||||||
) {
|
) {
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if (fsinfo == NULL || dir == NULL)
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
FYGUE_RET_ERRNO(EIO);
|
||||||
errno = EBADF;
|
|
||||||
return -1;
|
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END)
|
||||||
}
|
FYGUE_RET_ERRNO(EINVAL);
|
||||||
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(whence == SEEK_CUR)
|
if(whence == SEEK_CUR)
|
||||||
offset += desc->resolve.dir.pos;
|
offset += dir->pos;
|
||||||
if(whence == SEEK_END) {
|
if(whence == SEEK_END)
|
||||||
_fygue_dir_discover(desc);
|
offset += dir->count;
|
||||||
offset += desc->resolve.dir.count;
|
if(offset < 0 || offset >= dir->count + 1)
|
||||||
}
|
FYGUE_RET_ERRNO(EINVAL);
|
||||||
if(offset < 0 || offset >= desc->resolve.dir.count + 1) {
|
|
||||||
errno = EINVAL;
|
dir->pos = offset;
|
||||||
return -1;
|
return dir->pos;
|
||||||
}
|
|
||||||
desc->resolve.dir.pos = offset;
|
|
||||||
return desc->resolve.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 <string.h>
|
||||||
#include "fygue.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
|
/* fygue_dir_read(): directory read implementation
|
||||||
*
|
*
|
||||||
* notes
|
* notes
|
||||||
* - assume that the directory have read permission */
|
* - assume that the directory have read permission */
|
||||||
int fygue_dir_read(
|
ssize_t fygue_dir_read(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_dir *dir,
|
||||||
struct dirent **dirent,
|
struct dirent **dirent,
|
||||||
size_t size
|
size_t size
|
||||||
) {
|
) {
|
||||||
struct fygue_fsinfo *fsinfo;
|
if (fsinfo == NULL || dir == NULL)
|
||||||
int rc;
|
FYGUE_RET_ERRNO(EIO);
|
||||||
|
if (dirent == NULL)
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
FYGUE_RET_ERRNO(EFAULT);
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
if (size < sizeof *dirent)
|
||||||
errno = EBADF;
|
FYGUE_RET_ERRNO(EINVAL);
|
||||||
return -1;
|
if (dir->pos >= dir->count)
|
||||||
}
|
FYGUE_RET_ERRNO(EIO);
|
||||||
if (dirent == NULL) {
|
*dirent = dir->dirent[dir->pos];
|
||||||
errno = EFAULT;
|
dir->pos += 1;
|
||||||
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;
|
|
||||||
return sizeof *dirent;
|
return sizeof *dirent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,58 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <gint/hardware.h>
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
|
|
||||||
/* fygue_dir_sync(): directory-specific sync */
|
/* fygue_dir_sync(): directory-specific sync */
|
||||||
int fygue_dir_sync(struct fygue_descriptor *desc)
|
int fygue_dir_sync(
|
||||||
{
|
struct fygue_fsinfo *fsinfo,
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_dir *dir
|
||||||
|
) {
|
||||||
|
struct fygue_fat_descriptor desc;
|
||||||
|
int saved_pos;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
/* preliminary check */
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
if(gint[HWFS] != HWFS_FUGUE)
|
||||||
errno = EBADF;
|
FYGUE_RET_ERRNO(ENOTSUP);
|
||||||
return -1;
|
if (fsinfo == NULL || dir == NULL)
|
||||||
}
|
FYGUE_RET_ERRNO(EIO);
|
||||||
//if (desc->)
|
|
||||||
if (fygue_mount(&fsinfo, true)) {
|
/* update FAT-specific information */
|
||||||
errno = EIO;
|
//TODO: assume that the first cluster will remain the same ?
|
||||||
return -1;
|
if (fygue_fat_open(&(fsinfo->fat), dir->path, &desc) != 0)
|
||||||
}
|
FYGUE_RET_ERRNO(ENOENT);
|
||||||
for (int i = 0 ; i < desc->resolve.dir.count ; i++) {
|
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
|
||||||
if (desc->resolve.dir.dirent[i] == NULL)
|
FYGUE_RET_ERRNO(EIO);
|
||||||
continue;
|
|
||||||
free(desc->resolve.dir.dirent[i]);
|
|
||||||
desc->resolve.dir.dirent[i] = NULL;
|
|
||||||
}
|
|
||||||
rc = fygue_fat_dir_sync(
|
rc = fygue_fat_dir_sync(
|
||||||
&(fsinfo->fat),
|
&(fsinfo->fat),
|
||||||
&(desc->resolve.dir.fat)
|
&(desc.dir),
|
||||||
|
desc.file.cluster_entry
|
||||||
);
|
);
|
||||||
if (rc != 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,16 @@
|
||||||
|
|
||||||
/* fygue_dir_write(): write directory (EISDIR) */
|
/* fygue_dir_write(): write directory (EISDIR) */
|
||||||
ssize_t fygue_dir_write(
|
ssize_t fygue_dir_write(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_dir *dir,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
size_t size
|
size_t size
|
||||||
) {
|
) {
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if (fsinfo == NULL || dir == NULL)
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
FYGUE_RET_ERRNO(EIO);
|
||||||
errno = EBADF;
|
if (buffer == NULL)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(EFAULT);
|
||||||
}
|
if (size != 0)
|
||||||
if (buffer == NULL) {
|
FYGUE_RET_ERRNO(EISDIR);
|
||||||
errno = EFAULT;
|
return 0;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
errno = EISDIR;
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,15 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
#include "fat/fat.h"
|
#include "fat/fat.h"
|
||||||
|
|
||||||
/* fygue_file_close(): close directory */
|
/* fygue_file_close(): close directory */
|
||||||
int fygue_file_close(struct fygue_descriptor *desc)
|
int fygue_file_close(
|
||||||
{
|
struct fygue_fsinfo *fsinfo,
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_file *file
|
||||||
|
) {
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if (fsinfo == NULL || file == NULL)
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
FYGUE_RET_ERRNO(EIO);
|
||||||
errno = EBADF;
|
fygue_fat_file_close(&(fsinfo->fat), &(file->fat));
|
||||||
return -1;
|
free(file);
|
||||||
}
|
|
||||||
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));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,38 +2,26 @@
|
||||||
|
|
||||||
/* fygue_file_lseek(): seek file */
|
/* fygue_file_lseek(): seek file */
|
||||||
off_t fygue_file_lseek(
|
off_t fygue_file_lseek(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_file *file,
|
||||||
off_t offset,
|
off_t offset,
|
||||||
int whence
|
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)
|
if(whence == SEEK_CUR)
|
||||||
offset += desc->resolve.dir.pos;
|
offset += file->cursor;
|
||||||
if(whence == SEEK_END)
|
if(whence == SEEK_END)
|
||||||
offset += desc->resolve.file.size;
|
offset += file->size;
|
||||||
if(offset < 0 || offset >= desc->resolve.file.size + 1) {
|
if(offset < 0 || (unsigned)offset >= file->size + 1)
|
||||||
errno = EINVAL;
|
FYGUE_RET_ERRNO(EINVAL);
|
||||||
return -1;
|
|
||||||
}
|
if (fygue_fat_file_seek(&(fsinfo->fat), &(file->fat), offset) != 0)
|
||||||
desc->resolve.file.cursor = offset;
|
FYGUE_RET_ERRNO(EIO);
|
||||||
fygue_fat_file_seek(
|
|
||||||
&(fsinfo->fat),
|
file->cursor = offset;
|
||||||
&(desc->resolve.file.fat),
|
return file->cursor;
|
||||||
offset
|
|
||||||
);
|
|
||||||
return desc->resolve.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"
|
#include "fygue.h"
|
||||||
|
|
||||||
/* fygue_file_read(): write directory (EISDIR) */
|
/* fygue_file_read(): read file data */
|
||||||
ssize_t fygue_file_read(
|
ssize_t fygue_file_read(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_file *file,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
size_t size
|
size_t size
|
||||||
) {
|
) {
|
||||||
struct fygue_fsinfo *fsinfo;
|
if (fsinfo == NULL || file == NULL)
|
||||||
|
FYGUE_RET_ERRNO(EIO);
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if (buffer == NULL)
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
FYGUE_RET_ERRNO(EFAULT);
|
||||||
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;
|
|
||||||
}
|
|
||||||
return fygue_fat_file_read(
|
return fygue_fat_file_read(
|
||||||
&(fsinfo->fat),
|
&(fsinfo->fat),
|
||||||
&(desc->resolve.file.fat),
|
&(file->fat),
|
||||||
buffer,
|
buffer,
|
||||||
size
|
size
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,26 +1,30 @@
|
||||||
|
#include <gint/hardware.h>
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
|
|
||||||
/* fygue_file_sync(): file-specific sync */
|
/* fygue_file_sync(): file-specific sync */
|
||||||
int fygue_file_sync(struct fygue_descriptor *desc)
|
int fygue_file_sync(
|
||||||
{
|
struct fygue_fsinfo *fsinfo,
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_file *file
|
||||||
|
) {
|
||||||
|
struct fygue_fat_descriptor desc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if(gint[HWFS] != HWFS_FUGUE)
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
FYGUE_RET_ERRNO(ENOTSUP);
|
||||||
errno = EBADF;
|
if (fsinfo == NULL || file == NULL)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(EIO);
|
||||||
}
|
|
||||||
if (fygue_mount(&fsinfo, true)) {
|
//TODO: assume that the first cluster will remain the same ?
|
||||||
errno = EIO;
|
if (fygue_fat_open(&(fsinfo->fat), file->path, &desc) != 0)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(ENOENT);
|
||||||
}
|
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
|
||||||
// nothing to sync in high-level
|
FYGUE_RET_ERRNO(EIO);
|
||||||
rc = fygue_fat_file_sync(
|
rc = fygue_fat_file_sync(
|
||||||
&(fsinfo->fat),
|
&(fsinfo->fat),
|
||||||
&(desc->resolve.file.fat)
|
&(desc.file),
|
||||||
|
desc.file.cluster_entry
|
||||||
);
|
);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(EIO);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,16 @@
|
||||||
|
|
||||||
/* fygue_file_write(): write directory (EISDIR) */
|
/* fygue_file_write(): write directory (EISDIR) */
|
||||||
ssize_t fygue_file_write(
|
ssize_t fygue_file_write(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_fsinfo *fsinfo,
|
||||||
|
struct fygue_file *file,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
size_t size
|
size_t size
|
||||||
) {
|
) {
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if (fsinfo == NULL || file == NULL)
|
||||||
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
FYGUE_RET_ERRNO(EIO);
|
||||||
errno = EBADF;
|
if (buffer == NULL)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(EFAULT);
|
||||||
}
|
if (size != 0)
|
||||||
if (buffer == NULL) {
|
FYGUE_RET_ERRNO(EROFS);
|
||||||
errno = EFAULT;
|
return 0;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
errno = EROFS;
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
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 <stdlib.h>
|
||||||
#include <gint/gint.h>
|
#include <gint/gint.h>
|
||||||
#include <gint/bfile.h>
|
#include <gint/bfile.h>
|
||||||
|
#include <gint/hardware.h>
|
||||||
#include "../fugue/fugue.h"
|
#include "../fugue/fugue.h"
|
||||||
#include "fygue.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 */
|
/* fygue_open(): open primitive */
|
||||||
int fygue_open(char const *path, int flags, GUNUSED mode_t mode)
|
int fygue_open(char const *path, int flags, GUNUSED mode_t mode)
|
||||||
{
|
{
|
||||||
struct fygue_descriptor *desc;
|
struct fygue_descriptor desc;
|
||||||
struct fygue_resolve resolve;
|
fs_descriptor_t gint_desc;
|
||||||
fs_descriptor_t data;
|
int exists;
|
||||||
|
|
||||||
if ((flags & O_RDWR) || (flags & O_WRONLY)) {
|
/* preliminary checks */
|
||||||
errno = EROFS;
|
if(gint[HWFS] != HWFS_FUGUE)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(ENOTSUP);
|
||||||
}
|
if ((flags & O_RDWR) || (flags & O_WRONLY))
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
FYGUE_RET_ERRNO(EROFS);
|
||||||
|
|
||||||
/* resolve the entry */
|
/* 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 opening fails and no explicit file creation is required, fail */
|
||||||
if ((exists < 0 && (!(flags & O_CREAT) || (flags & O_DIRECTORY)))) {
|
if ((exists < 0 && (!(flags & O_CREAT) || (flags & O_DIRECTORY))))
|
||||||
errno = ENOENT;
|
FYGUE_RET_ERRNO(ENOENT);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* if opening fails and the previous check as not returned an error,
|
/* 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
|
* it is certainly because of a creation request. We are a read-only
|
||||||
* file-system, so, fail */
|
* file-system, so, fail */
|
||||||
if (exists < 0) {
|
if (exists < 0)
|
||||||
errno = EROFS;
|
FYGUE_RET_ERRNO(EROFS);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the entry exists and O_EXCL was requested, fail.
|
/* If the entry exists and O_EXCL was requested, fail.
|
||||||
* note that Exclusive open means no sense unless creation is also
|
* note that Exclusive open means no sense unless creation is also
|
||||||
* requested */
|
* requested */
|
||||||
if(exists >= 0 && (flags & O_EXCL)) {
|
if(exists >= 0 && (flags & O_EXCL))
|
||||||
errno = EEXIST;
|
FYGUE_RET_ERRNO(EEXIST);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* generate the final file descriptor */
|
/* generate the final file descriptor */
|
||||||
desc = calloc(1, sizeof(struct fygue_descriptor));
|
gint_desc.type = &fygue_file_descriptor_type;
|
||||||
if (desc == NULL) {
|
gint_desc.data = calloc(1, sizeof(struct fygue_descriptor));
|
||||||
errno = ENOMEM;
|
if (gint_desc.data == NULL)
|
||||||
return -1;
|
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);
|
return fs_create_descriptor(&gint_desc);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,22 @@
|
||||||
|
#include <gint/hardware.h>
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
#include "fat/fat.h"
|
#include "fat/fat.h"
|
||||||
|
|
||||||
/* fygue_stat(): stat primitive */
|
/* fygue_stat(): stat primitive */
|
||||||
int fygue_stat(char const * const path, struct stat *statbuf)
|
int fygue_stat(char const * const path, struct stat *statbuf)
|
||||||
{
|
{
|
||||||
struct fygue_resolve resolve;
|
struct fygue_descriptor desc;
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_fsinfo *fsinfo;
|
||||||
|
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
if(gint[HWFS] != HWFS_FUGUE)
|
||||||
if (path == NULL || statbuf == NULL) {
|
FYGUE_RET_ERRNO(ENOTSUP);
|
||||||
errno = EFAULT;
|
if (path == NULL || statbuf == NULL)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(EFAULT);
|
||||||
}
|
if (fygue_mount(&fsinfo) != 0)
|
||||||
if (fygue_mount(&fsinfo, true) != 0) {
|
FYGUE_RET_ERRNO(EIO);
|
||||||
errno = EIO;
|
if (fygue_open_resolve(path, &desc) != 0)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(ENOENT);
|
||||||
}
|
if (desc.type == FYGUE_DESC_TYPE_DIR)
|
||||||
if (fygue_resolve(path, &resolve) != 0) {
|
return fygue_fat_dir_stat(&(fsinfo->fat), &(desc.dir.fat), statbuf);
|
||||||
errno = ENOENT;
|
return fygue_fat_file_stat(&(fsinfo->fat), &(desc.file.fat), statbuf);
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
|
#include <gint/hardware.h>
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
|
|
||||||
|
/* fygue_syncfs() - request filesystem re-synchronisation */
|
||||||
int fygue_syncfs(void *data)
|
int fygue_syncfs(void *data)
|
||||||
{
|
{
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_fsinfo *fsinfo;
|
||||||
struct fygue_descriptor *descriptor;
|
struct fygue_descriptor *desc;
|
||||||
|
|
||||||
|
if(gint[HWFS] != HWFS_FUGUE)
|
||||||
|
FYGUE_RET_ERRNO(ENOTSUP);
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return -1;
|
FYGUE_RET_ERRNO(EBADF);
|
||||||
if (fygue_mount(&fsinfo, false) != 0)
|
if (fygue_mount(&fsinfo) != 0)
|
||||||
return -2;
|
FYGUE_RET_ERRNO(EIO);
|
||||||
descriptor = data;
|
desc = data;
|
||||||
descriptor->dirty = true;
|
desc->dirty = true;
|
||||||
fsinfo->dirty = true;
|
fsinfo->dirty = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue