fygue: support readdir() + small fixes

This commit is contained in:
Yann MAGNIN 2025-04-04 08:50:24 +02:00
parent e4e09052fc
commit dae0972878
No known key found for this signature in database
GPG key ID: D82629D933EADC59
7 changed files with 92 additions and 23 deletions

View file

@ -263,6 +263,7 @@ set(SOURCES
src/fs/fygue/fygue.c
src/fs/fygue/fygue_open.c
src/fs/fygue/fygue_syncfs.c
src/fs/fygue/fygue_dir_read.c
src/fs/fygue/fat/cluster.c
src/fs/fygue/fat/initialize.c
src/fs/fygue/fat/readdir.c

View file

@ -43,6 +43,7 @@ struct fygue_fat
};
/* fygue_fat_dirent - FAT dirent information */
//TODO: flexible name array like the high-level `struct dirent` ?
struct fygue_fat_dirent
{
char name[256];

View file

@ -102,10 +102,6 @@ static int _fygue_resolve_set(
// Public
//---
char const *debug_prefix = "";
char const *debug_start = "";
size_t debug_len = 0;
/* fygue_fat_resolve(): resolve any path provided
*
* notes
@ -138,9 +134,6 @@ int fygue_fat_resolve(
is_root = false;
continue;
}
debug_prefix = prefix;
debug_start = start;
debug_len = len;
if (_fygue_dirent_find(fat, &dir, &dirent, start, len) != 0)
return -4;
if (_fygue_path_get_name(&prefix, &start, &len) != 0)

View file

@ -55,9 +55,9 @@ int fygue_resolve(char const * const path, struct fygue_resolve *resolve)
return -1;
if (fygue_mount(&fsinfo, true) != 0)
return -2;
int rc = fygue_fat_resolve(&(fsinfo->fat), path, &fat_resolve);
if (rc < 0)
return rc;
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;
@ -69,6 +69,7 @@ int fygue_resolve(char const * const path, struct fygue_resolve *resolve)
);
} else {
resolve->type = FYGUE_FILE_TYPE_DIR;
resolve->dir.dirent = NULL;
memcpy(
&(resolve->dir.fat),
&(fat_resolve.dir),
@ -90,7 +91,7 @@ const fs_descriptor_type_t fygue_descriptor_type = {
};
const fs_descriptor_type_t fygue_dir_descriptor_type = {
.read = NULL,
.read = (void*)&fygue_dir_read,
.write = NULL,
.lseek = NULL,
.close = NULL,

View file

@ -28,10 +28,7 @@ extern const fs_descriptor_type_t fygue_dir_descriptor_type;
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 * restrict path,
struct stat * restrict statbuf
);
extern int fygue_stat(char const *path, struct stat *statbuf);
/* fygue_syncfs() - request filesystem re-synchronisation */
extern int fygue_syncfs(void *desc);
@ -44,11 +41,7 @@ extern int fygue_syncfs(void *desc);
#include <errno.h>
#define ENOTSUP_IF_NOT_FYGUE(rc) \
if( \
(gint[HWFS] != HWFS_FUGUE) || \
(flags & O_WRONLY) || \
(flags & O_RDWR) \
) { \
if(gint[HWFS] != HWFS_FUGUE) { \
errno = ENOTSUP; \
return (rc); \
}
@ -75,6 +68,7 @@ struct fygue_resolve {
} file;
struct {
struct fygue_fat_dir fat;
struct dirent *dirent;
} dir;
};
};
@ -98,6 +92,13 @@ extern int fygue_resolve(
struct fygue_resolve *resolve
);
/* fygue_dir_read(): directory read implementation */
extern int fygue_dir_read(
struct fygue_descriptor *desc,
struct dirent **dirent,
size_t size
);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,68 @@
#include <stdlib.h>
#include <string.h>
#include "fygue.h"
/* fygue_dir_read(): directory read implementation
*
* notes
* - assume that the directory have read permission */
int fygue_dir_read(
struct fygue_descriptor *desc,
struct dirent **dirent,
size_t size
) {
struct fygue_fat_dirent fat_dirent;
struct fygue_fsinfo *fsinfo;
size_t len;
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_mount(&fsinfo, true) != 0) {
errno = EIO;
return -1;
}
/* get the next FAT dirent */
rc = fygue_fat_readdir(
&(fsinfo->fat),
&desc->resolve.dir.fat,
&fat_dirent
);
if (rc <= -3)
return 0;
if (rc < 0) {
errno = EIO;
return -1;
}
/* since `struct dirent` use flexible array to store the filename
* we need to reallocate the buffer each time */
//FIXME: ensure UTF-8/SHIFT-JS
len = strlen(fat_dirent.name);
*dirent = desc->resolve.dir.dirent;
*dirent = realloc(*dirent, sizeof(struct dirent) + len + 2);
if (*dirent == NULL) {
errno = ENOMEM;
return -1;
}
/* convert FAT dirent into generic dirent information */
//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;
}

View file

@ -12,6 +12,10 @@ int fygue_open(char const *path, int flags, GUNUSED mode_t mode)
struct fygue_resolve resolve;
fs_descriptor_t data;
if ((flags & O_RDWR) || (flags & O_WRONLY)) {
errno = EROFS;
return -1;
}
ENOTSUP_IF_NOT_FYGUE(-1);
/* resolve the entry */