mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 23:39:17 +02:00
fygue: support stat for directory and file
This commit is contained in:
parent
8b5ede80fe
commit
bad0dbd5f4
10 changed files with 227 additions and 16 deletions
|
@ -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_stat.c
|
||||
src/fs/fygue/fygue_dir_read.c
|
||||
src/fs/fygue/fygue_dir_lseek.c
|
||||
src/fs/fygue/fygue_dir_write.c
|
||||
|
@ -271,6 +272,8 @@ set(SOURCES
|
|||
src/fs/fygue/fat/initialize.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_file_stat.c
|
||||
src/fs/fygue/fat/resolve.c
|
||||
src/fs/fygue/fat/sector.c
|
||||
src/fs/fygue/flash/cluster.c
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define FS_FYGUE_FAT_H 1
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../flash/flash.h"
|
||||
|
||||
|
@ -17,6 +18,14 @@
|
|||
| (((x) & 0x000000ff) << 24) \
|
||||
)
|
||||
|
||||
/* FYGUE_FAT_ATTR_* : FAT dirent attribute */
|
||||
#define FYGUE_FAT_ATTR_READ_ONLY 0x01
|
||||
#define FYGUE_FAT_ATTR_HIDDEN 0x02
|
||||
#define FYGUE_FAT_ATTR_SYSTEM 0x04
|
||||
#define FYGUE_FAT_ATTR_VOLUME 0x08
|
||||
#define FYGUE_FAT_ATTR_DIRECTORY 0x10
|
||||
#define FYGUE_FAT_ATTR_ARCHIVE 0x20
|
||||
|
||||
/* fygue_fat - fat information */
|
||||
struct fygue_fat
|
||||
{
|
||||
|
@ -26,6 +35,8 @@ struct fygue_fat
|
|||
} Type;
|
||||
int SectorHiddenCount;
|
||||
int SectorCount;
|
||||
int SectorSize;
|
||||
int SectorPerClus;
|
||||
int ClusterCount;
|
||||
int TotalCapacity;
|
||||
int RootEntCount;
|
||||
|
@ -47,10 +58,10 @@ struct fygue_fat
|
|||
struct fygue_fat_dirent
|
||||
{
|
||||
char name[256];
|
||||
int type;
|
||||
size_t size;
|
||||
uintptr_t meta_addr;
|
||||
unsigned int cluster_id;
|
||||
int attribute;
|
||||
};
|
||||
|
||||
/* fygue_fat_dir - fygue directory information */
|
||||
|
@ -65,12 +76,15 @@ struct fygue_fat_dir
|
|||
uintptr_t dirent_current_addr;
|
||||
bool end_of_dirent;
|
||||
bool dirty;
|
||||
int attribute;
|
||||
};
|
||||
|
||||
/* fygue_fat_file: file information needed to perform IO primitives */
|
||||
struct fygue_fat_file
|
||||
{
|
||||
int todo;
|
||||
int cluster_entry;
|
||||
int attribute;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/* fygue_fat_resolve: internal resolve information */
|
||||
|
@ -99,6 +113,10 @@ extern int fygue_fat_resolve(
|
|||
struct fygue_fat_resolve *resolve
|
||||
);
|
||||
|
||||
//---
|
||||
// Directory interface
|
||||
//---
|
||||
|
||||
/* fygue_fat_dir_read(): readdir primitive */
|
||||
extern int fygue_fat_dir_read(
|
||||
struct fygue_fat *fat,
|
||||
|
@ -112,6 +130,24 @@ extern int fygue_fat_dir_close(
|
|||
struct fygue_fat_dir *dir
|
||||
);
|
||||
|
||||
/* fygue_fat_dir_stat(): directory stat primitive */
|
||||
extern int fygue_fat_dir_stat(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_dir *dir,
|
||||
struct stat *statbuf
|
||||
);
|
||||
|
||||
//---
|
||||
// File interface
|
||||
//---
|
||||
|
||||
/* fygue_fat_file_stat(): directory stat primitive */
|
||||
extern int fygue_fat_file_stat(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_file *file,
|
||||
struct stat *statbuf
|
||||
);
|
||||
|
||||
//---
|
||||
// Cluster interface
|
||||
//---
|
||||
|
|
|
@ -155,7 +155,7 @@ static void _fygue_fat_readdir_dirent_gen(
|
|||
while (finfo->idx > 0)
|
||||
current->name[idx++] = finfo->filename[--finfo->idx];
|
||||
current->name[idx] = 0x00;
|
||||
current->type = dirent->DIR_Attr;
|
||||
current->attribute = dirent->DIR_Attr;
|
||||
current->size = FAT_DWORD(dirent->DIR_FileSize);
|
||||
current->meta_addr = (uintptr_t)dirent;
|
||||
current->cluster_id = (
|
||||
|
|
66
src/fs/fygue/fat/fat_dir_stat.c
Normal file
66
src/fs/fygue/fat/fat_dir_stat.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <errno.h>
|
||||
#include "fat.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* _get_mode(): get "pseudo" file mode */
|
||||
static mode_t _get_mode(struct fygue_fat_dir *dir)
|
||||
{
|
||||
mode_t mode;
|
||||
|
||||
mode = 0777;
|
||||
if (dir->attribute & FYGUE_FAT_ATTR_READ_ONLY)
|
||||
mode = 0444;
|
||||
if (dir->attribute & FYGUE_FAT_ATTR_DIRECTORY)
|
||||
return mode | S_IFDIR;
|
||||
return S_IFREG | 0777;
|
||||
}
|
||||
|
||||
/* _get_block_size(): return one cluster size */
|
||||
static int _get_block_size(struct fygue_fat *fat)
|
||||
{
|
||||
return (fat->SectorSize * fat->SectorPerClus);
|
||||
}
|
||||
|
||||
/* _get_block_nb(): count the number of cluster */
|
||||
static int _get_block_nb(struct fygue_fat *fat, int cluster)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
while (fygue_fat_cluster_get_next(fat, &cluster) == 0)
|
||||
count += 1;
|
||||
return count;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_fat_dir_stat(): directory-specific stat primitive */
|
||||
int fygue_fat_dir_stat(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_dir *dir,
|
||||
struct stat *statbuf
|
||||
) {
|
||||
if (fat == NULL || dir == NULL || statbuf == NULL) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
statbuf->st_dev = 0; /* not supported */
|
||||
statbuf->st_ino = dir->cluster_entry;
|
||||
statbuf->st_mode = _get_mode(dir);
|
||||
statbuf->st_nlink = 0; /* not supported */
|
||||
statbuf->st_uid = 0; /* not supported */
|
||||
statbuf->st_gid = 0; /* not supported */
|
||||
statbuf->st_rdev = 0; /* not supported */
|
||||
statbuf->st_size = 0;
|
||||
statbuf->st_atime = 0; /* not supported */
|
||||
statbuf->st_mtime = 0; /* not supported */
|
||||
statbuf->st_ctime = 0; /* not supported */
|
||||
statbuf->st_blksize = _get_block_size(fat);
|
||||
statbuf->st_blocks = _get_block_nb(fat, dir->cluster_entry);
|
||||
return 0;
|
||||
}
|
61
src/fs/fygue/fat/fat_file_stat.c
Normal file
61
src/fs/fygue/fat/fat_file_stat.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include <errno.h>
|
||||
#include "fat.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* _get_mode(): get "pseudo" file mode */
|
||||
static mode_t _get_mode(int attribute)
|
||||
{
|
||||
if (attribute & FYGUE_FAT_ATTR_READ_ONLY)
|
||||
return S_IFDIR | 0444;
|
||||
return S_IFDIR | 0777;
|
||||
}
|
||||
|
||||
/* _get_block_size(): return one cluster size */
|
||||
static int _get_block_size(struct fygue_fat *fat)
|
||||
{
|
||||
return (fat->SectorSize * fat->SectorPerClus);
|
||||
}
|
||||
|
||||
/* _get_block_nb(): count the number of cluster */
|
||||
static int _get_block_nb(struct fygue_fat *fat, int cluster)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = 1;
|
||||
while (fygue_fat_cluster_get_next(fat, &cluster) == 0)
|
||||
count += 1;
|
||||
return count;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_fat_file_stat(): directory-specific stat primitive */
|
||||
int fygue_fat_file_stat(
|
||||
struct fygue_fat *fat,
|
||||
struct fygue_fat_file *file,
|
||||
struct stat *statbuf
|
||||
) {
|
||||
if (fat == NULL || file == NULL || statbuf == NULL) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
statbuf->st_dev = 0; /* not supported */
|
||||
statbuf->st_ino = file->cluster_entry;
|
||||
statbuf->st_mode = _get_mode(file->attribute);
|
||||
statbuf->st_nlink = 0; /* not supported */
|
||||
statbuf->st_uid = 0; /* not supported */
|
||||
statbuf->st_gid = 0; /* not supported */
|
||||
statbuf->st_rdev = 0; /* not supported */
|
||||
statbuf->st_size = file->size;
|
||||
statbuf->st_atime = 0; /* not supported */
|
||||
statbuf->st_mtime = 0; /* not supported */
|
||||
statbuf->st_ctime = 0; /* not supported */
|
||||
statbuf->st_blksize = _get_block_size(fat);
|
||||
statbuf->st_blocks = _get_block_nb(fat, file->cluster_entry);
|
||||
return 0;
|
||||
}
|
|
@ -127,6 +127,8 @@ static int _fygue_fat_configure(struct fygue_fat *fat)
|
|||
|
||||
fat->TotalCapacity = DataSec * FAT_WORD(bpb->BPB_BytsPerSec);
|
||||
fat->RootEntCount = FAT_WORD(bpb->BPB_RootEntCnt);
|
||||
fat->SectorSize = FAT_WORD(bpb->BPB_BytsPerSec);
|
||||
fat->SectorPerClus = bpb->BPB_SecPerClus;
|
||||
|
||||
// todo : FAT12-specific operation
|
||||
fat->ClusterCount = FAT_WORD(bpb->BPB_FATSz16);
|
||||
|
|
|
@ -36,15 +36,18 @@ static int _fygue_dirent_resolve(
|
|||
struct fygue_fat_dir *dir,
|
||||
struct fygue_fat_dirent *dirent
|
||||
) {
|
||||
int rc;
|
||||
|
||||
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
|
||||
if (dirent == NULL)
|
||||
{
|
||||
if (dirent == NULL) {
|
||||
dir->cluster_entry = 0;
|
||||
dir->root_dirent_count = fat->RootEntCount;
|
||||
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
|
||||
} else {
|
||||
if ((dirent->type & 0x10) == 0x00)
|
||||
if ((dirent->attribute & FYGUE_FAT_FILE_TYPE_DIR) == 0x00)
|
||||
return -1;
|
||||
dir->cluster_entry = dirent->cluster_id;
|
||||
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
|
||||
dir->root_dirent_count = 0;
|
||||
}
|
||||
dir->dirty = false;
|
||||
|
@ -52,18 +55,19 @@ static int _fygue_dirent_resolve(
|
|||
dir->dirent_cursor = 0;
|
||||
dir->end_of_dirent = false;
|
||||
dir->cluster_current = dir->cluster_entry;
|
||||
int rc = fygue_fat_cluster_get_sector(
|
||||
rc = fygue_fat_cluster_get_sector(
|
||||
fat,
|
||||
dir->cluster_current,
|
||||
&dir->sector_id
|
||||
);
|
||||
if (rc != 0)
|
||||
return -1;
|
||||
return fygue_fat_sector_get_addr(
|
||||
return -2;
|
||||
rc = fygue_fat_sector_get_addr(
|
||||
fat,
|
||||
&dir->dirent_current_addr,
|
||||
dir->sector_id
|
||||
);
|
||||
return (rc != 0) ? -3 : 0;
|
||||
}
|
||||
|
||||
/* _fygue_opendir_find() - try to find the directory entry */
|
||||
|
@ -90,11 +94,14 @@ static int _fygue_resolve_set(
|
|||
struct fygue_fat_resolve *resolve,
|
||||
struct fygue_fat_dirent *dirent
|
||||
) {
|
||||
resolve->type = FYGUE_FAT_FILE_TYPE_DIR;
|
||||
if (_fygue_dirent_resolve(fat, &(resolve->dir), dirent) == 0)
|
||||
return 0;
|
||||
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
|
||||
resolve->type = FYGUE_FAT_FILE_TYPE_DIR;
|
||||
return _fygue_dirent_resolve(fat, &(resolve->dir), dirent);
|
||||
}
|
||||
resolve->type = FYGUE_FAT_FILE_TYPE_FILE;
|
||||
// todo: support IO file information
|
||||
resolve->file.attribute = dirent->attribute;
|
||||
resolve->file.cluster_entry = dirent->cluster_id;
|
||||
resolve->file.size = dirent->size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ int fygue_resolve(char const * const path, struct fygue_resolve *resolve)
|
|||
return -1;
|
||||
if (fygue_mount(&fsinfo, true) != 0)
|
||||
return -2;
|
||||
if (fygue_fat_resolve(&(fsinfo->fat), path, &fat_resolve) < 0)
|
||||
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)
|
||||
|
|
|
@ -24,7 +24,7 @@ int fygue_open(char const *path, int flags, GUNUSED mode_t mode)
|
|||
/* if opening fails and no explicit file creation is required, fail */
|
||||
if ((exists < 0 && (!(flags & O_CREAT) || (flags & O_DIRECTORY)))) {
|
||||
errno = ENOENT;
|
||||
return exists;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if opening fails and the previous check as not returned an error,
|
||||
|
@ -32,7 +32,7 @@ int fygue_open(char const *path, int flags, GUNUSED mode_t mode)
|
|||
* file-system, so, fail */
|
||||
if (exists < 0) {
|
||||
errno = EROFS;
|
||||
return exists;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If the entry exists and O_EXCL was requested, fail.
|
||||
|
|
36
src/fs/fygue/fygue_stat.c
Normal file
36
src/fs/fygue/fygue_stat.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
#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_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
|
||||
);
|
||||
}
|
Loading…
Add table
Reference in a new issue