fygue: (untested) complete re-architecture + syncfs() support

This commit is contained in:
Yann MAGNIN 2025-04-10 13:15:04 +02:00
parent c99a18d748
commit 69d59cd4d2
No known key found for this signature in database
GPG key ID: D82629D933EADC59
32 changed files with 753 additions and 600 deletions

View file

@ -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)

View file

@ -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)
);
}

View file

@ -2,7 +2,7 @@
** fygue/fat/cluster - FAT cluster handling
*/
#include "fat.h"
#include "../flash/flash.h"
#include "flash/flash.h"
//---
// Internals

View file

@ -4,7 +4,7 @@
#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) \
@ -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
);
//---

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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)

View file

@ -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);
}

View file

@ -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,
};

View file

@ -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;
/* 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;
} file;
struct {
struct fygue_fat_dir fat;
struct dirent **dirent;
int count;
int pos;
} dir;
};
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
}

View file

@ -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)
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)
{
struct fygue_fsinfo *fsinfo;
ENOTSUP_IF_NOT_FYGUE(-1);
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
errno = EBADF;
return -1;
for (int i = 0 ; i < dir->count ; i++) {
if (dir->dirent[i] != NULL)
free(dir->dirent[i]);
}
if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
errno = EIO;
return -1;
free(dir->dirent);
}
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++) {
if (desc->resolve.dir.dirent[i] != NULL)
free(desc->resolve.dir.dirent[i]);
}
free(desc->resolve.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;
}

View file

@ -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;
}

View 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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)
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;
errno = EISDIR;
return -1;
}

View file

@ -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;
}

View file

@ -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;
}

View 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;
}

View file

@ -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
);

View file

@ -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;
}

View file

@ -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)
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;
errno = EROFS;
return -1;
}

View 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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}