mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 15:29:16 +02:00
fygue: support directory lseek,write(error),close
This commit is contained in:
parent
dae0972878
commit
8b5ede80fe
11 changed files with 215 additions and 41 deletions
|
@ -264,9 +264,13 @@ 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_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_close.c
|
||||||
src/fs/fygue/fat/cluster.c
|
src/fs/fygue/fat/cluster.c
|
||||||
src/fs/fygue/fat/initialize.c
|
src/fs/fygue/fat/initialize.c
|
||||||
src/fs/fygue/fat/readdir.c
|
src/fs/fygue/fat/fat_dir_read.c
|
||||||
|
src/fs/fygue/fat/fat_dir_close.c
|
||||||
src/fs/fygue/fat/resolve.c
|
src/fs/fygue/fat/resolve.c
|
||||||
src/fs/fygue/fat/sector.c
|
src/fs/fygue/fat/sector.c
|
||||||
src/fs/fygue/flash/cluster.c
|
src/fs/fygue/flash/cluster.c
|
||||||
|
|
|
@ -99,13 +99,19 @@ extern int fygue_fat_resolve(
|
||||||
struct fygue_fat_resolve *resolve
|
struct fygue_fat_resolve *resolve
|
||||||
);
|
);
|
||||||
|
|
||||||
/* fygue_fat_readdir(): readdir primitive */
|
/* fygue_fat_dir_read(): readdir primitive */
|
||||||
extern int fygue_fat_readdir(
|
extern int fygue_fat_dir_read(
|
||||||
struct fygue_fat *fat,
|
struct fygue_fat *fat,
|
||||||
struct fygue_fat_dir *dir,
|
struct fygue_fat_dir *dir,
|
||||||
struct fygue_fat_dirent *dirent
|
struct fygue_fat_dirent *dirent
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* fygue_fat_dir_close(): closedir primitive */
|
||||||
|
extern int fygue_fat_dir_close(
|
||||||
|
struct fygue_fat *fat,
|
||||||
|
struct fygue_fat_dir *dir
|
||||||
|
);
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Cluster interface
|
// Cluster interface
|
||||||
//---
|
//---
|
||||||
|
|
11
src/fs/fygue/fat/fat_dir_close.c
Normal file
11
src/fs/fygue/fat/fat_dir_close.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "fat.h"
|
||||||
|
|
||||||
|
/* fygue_fat_dir_close(): closedir primitive */
|
||||||
|
int fygue_fat_dir_close(struct fygue_fat *fat, struct fygue_fat_dir *dir)
|
||||||
|
{
|
||||||
|
if (fat == NULL || dir == NULL)
|
||||||
|
return -1;
|
||||||
|
// nothing to do here...
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -371,14 +371,14 @@ static int _fygue_readdir_fat_check(struct _fat_info *finfo)
|
||||||
// Public
|
// Public
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* fygue_fat_readdir() - readdir-like primitive
|
/* fygue_fat_dir_read() - readdir-like primitive
|
||||||
*
|
*
|
||||||
* return
|
* return
|
||||||
* -3 no dirent remaning
|
* -3 no dirent remaning
|
||||||
* -2 internal error
|
* -2 internal error
|
||||||
* -1 argument error
|
* -1 argument error
|
||||||
* 0 success */
|
* 0 success */
|
||||||
int fygue_fat_readdir(
|
int fygue_fat_dir_read(
|
||||||
struct fygue_fat *fat,
|
struct fygue_fat *fat,
|
||||||
struct fygue_fat_dir *dir,
|
struct fygue_fat_dir *dir,
|
||||||
struct fygue_fat_dirent *current
|
struct fygue_fat_dirent *current
|
|
@ -76,7 +76,7 @@ static int _fygue_dirent_find(
|
||||||
) {
|
) {
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (fygue_fat_readdir(fat, dir, dirent) != 0)
|
if (fygue_fat_dir_read(fat, dir, dirent) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (strncmp(dirent->name, start, len) != 0)
|
if (strncmp(dirent->name, start, len) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -92,7 +92,7 @@ const fs_descriptor_type_t fygue_descriptor_type = {
|
||||||
|
|
||||||
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_dir_read,
|
||||||
.write = NULL,
|
.write = (void*)&fygue_dir_write,
|
||||||
.lseek = NULL,
|
.lseek = (void*)&fygue_dir_lseek,
|
||||||
.close = NULL,
|
.close = NULL,
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,7 +68,9 @@ struct fygue_resolve {
|
||||||
} file;
|
} file;
|
||||||
struct {
|
struct {
|
||||||
struct fygue_fat_dir fat;
|
struct fygue_fat_dir fat;
|
||||||
struct dirent *dirent;
|
struct dirent **dirent;
|
||||||
|
int count;
|
||||||
|
int pos;
|
||||||
} dir;
|
} dir;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -99,6 +101,20 @@ extern int fygue_dir_read(
|
||||||
size_t size
|
size_t size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* fygue_dir_lseek(): seek directory */
|
||||||
|
extern off_t fygue_dir_lseek(
|
||||||
|
struct fygue_descriptor *desc,
|
||||||
|
off_t offset,
|
||||||
|
int whence
|
||||||
|
);
|
||||||
|
|
||||||
|
/* fygue_dir_write(): write directory (EISDIR) */
|
||||||
|
ssize_t fygue_dir_write(
|
||||||
|
struct fygue_descriptor *desc,
|
||||||
|
void *buffer,
|
||||||
|
size_t size
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
30
src/fs/fygue/fygue_dir_close.c
Normal file
30
src/fs/fygue/fygue_dir_close.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "fygue.h"
|
||||||
|
#include "fat/fat.h"
|
||||||
|
|
||||||
|
int fygue_dir_close(struct fygue_descriptor *desc)
|
||||||
|
{
|
||||||
|
struct fygue_fsinfo *fsinfo;
|
||||||
|
|
||||||
|
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||||
|
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fygue_mount(&fsinfo, true) != 0) {
|
||||||
|
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++) {
|
||||||
|
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));
|
||||||
|
return 0;
|
||||||
|
}
|
45
src/fs/fygue/fygue_dir_lseek.c
Normal file
45
src/fs/fygue/fygue_dir_lseek.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#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,
|
||||||
|
off_t offset,
|
||||||
|
int whence
|
||||||
|
) {
|
||||||
|
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
|
@ -2,6 +2,68 @@
|
||||||
#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
|
||||||
|
@ -11,9 +73,7 @@ int fygue_dir_read(
|
||||||
struct dirent **dirent,
|
struct dirent **dirent,
|
||||||
size_t size
|
size_t size
|
||||||
) {
|
) {
|
||||||
struct fygue_fat_dirent fat_dirent;
|
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_fsinfo *fsinfo;
|
||||||
size_t len;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
ENOTSUP_IF_NOT_FYGUE(-1);
|
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||||
|
@ -34,35 +94,15 @@ int fygue_dir_read(
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (desc->resolve.dir.pos >= desc->resolve.dir.count)
|
||||||
/* get the next FAT dirent */
|
{
|
||||||
rc = fygue_fat_readdir(
|
rc = _fygue_dir_fat_read(fsinfo, desc);
|
||||||
&(fsinfo->fat),
|
if (rc == -2)
|
||||||
&desc->resolve.dir.fat,
|
return 0;
|
||||||
&fat_dirent
|
if (rc < 0)
|
||||||
);
|
return rc;
|
||||||
if (rc <= -3)
|
|
||||||
return 0;
|
|
||||||
if (rc < 0) {
|
|
||||||
errno = EIO;
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
*dirent = desc->resolve.dir.dirent[desc->resolve.dir.pos];
|
||||||
/* since `struct dirent` use flexible array to store the filename
|
desc->resolve.dir.pos += 1;
|
||||||
* we need to reallocate the buffer each time */
|
return sizeof *dirent;
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
|
|
22
src/fs/fygue/fygue_dir_write.c
Normal file
22
src/fs/fygue/fygue_dir_write.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "fygue.h"
|
||||||
|
|
||||||
|
/* fygue_dir_write(): write directory (EISDIR) */
|
||||||
|
ssize_t fygue_dir_write(
|
||||||
|
struct fygue_descriptor *desc,
|
||||||
|
void *buffer,
|
||||||
|
size_t size
|
||||||
|
) {
|
||||||
|
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||||
|
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (buffer == NULL) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
errno = EISDIR;
|
||||||
|
return -1;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue