Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lfs:Added lfs_file_getattr interface #1047

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -6235,6 +6235,38 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
return res;
}

lfs_ssize_t lfs_file_getattr(lfs_t *lfs, lfs_file_t *file,
uint8_t type, void *buffer, lfs_size_t size)
{
int err = LFS_LOCK(lfs->cfg);
if (err) {
return err;
}
LFS_TRACE("lfs_file_setattr(%p, %p)", (void*)lfs, (void*)file);
LFS_TRACE("lfs_file_setattr(%"PRIu8", %p, %"PRIu32")",
type, buffer, size);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));

if (file->cfg && file->cfg->attrs) {
for (unsigned i = 0; i < file->cfg->attr_count; i++) {
const struct lfs_attr *attr = &file->cfg->attrs[i];
if (attr->type == LFS_TYPE_USERATTR + type) {
lfs_size_t attr_size = lfs_min(size, attr->size);
memcpy(buffer, attr->buffer, attr_size);
LFS_UNLOCK(lfs->cfg);
return 0;
}
}
}

err = lfs_dir_get(lfs, &file->m,
LFS_MKTAG(0x7ff, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_USERATTR + type,
file->id, lfs_min(size, lfs->attr_max)), buffer);
LFS_UNLOCK(lfs->cfg);
return (err < 0) ? LFS_ERR_NOATTR : 0;
}

#ifndef LFS_READONLY
int lfs_mkdir(lfs_t *lfs, const char *path) {
int err = LFS_LOCK(lfs->cfg);
Expand Down
7 changes: 7 additions & 0 deletions lfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,13 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
// Returns the size of the file, or a negative error code on failure.
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);

// Get the attribute of a file
//
// Retrieves the value of the attribute specified by `type` for the given `file`.
// Copies up to `size` bytes into `buffer`. Returns 0 on success, or a negative
// error code (e.g., LFS_ERR_NOATTR if not found).
lfs_ssize_t lfs_file_getattr(lfs_t *lfs, lfs_file_t *file,
uint8_t type, void *buffer, lfs_size_t size);

/// Directory operations ///

Expand Down
48 changes: 48 additions & 0 deletions tests/test_attrs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,51 @@ code = '''
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
'''

[cases.test_file_getattr]
code = '''
struct lfs_attr_s {
uint32_t at_ver;
uint32_t at_mode;
uint32_t at_uid;
uint32_t at_gid;
uint64_t at_atim;
uint64_t at_mtim;
uint64_t at_ctim;
};

lfs_t lfs;
lfs_format(&lfs, cfg) => 0;
lfs_mount(&lfs, cfg) => 0;

lfs_file_t file;
struct lfs_attr_s attr_get[1024];
memset(attr_get, 0, sizeof(attr_get));
lfs_file_open(&lfs, &file, "hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file, "world", strlen("world")) => strlen("world");
lfs_file_getattr(&lfs, &file, 0, attr_get, sizeof(struct lfs_attr_s)) => -61;

struct lfs_attr_s attr_set = {
.at_ver = 1,
.at_mode = 0644,
.at_uid = 1000,
.at_gid = 1000,
.at_atim = 1693123456,
.at_mtim = 1693123456,
.at_ctim = 1693123456,
};
lfs_setattr(&lfs, "hello", 0, &attr_set, sizeof(attr_set)) => 0;
memset(attr_get, 0, sizeof(attr_get));
lfs_file_getattr(&lfs, &file, 0, attr_get, sizeof(struct lfs_attr_s)) => 0;
attr_get->at_ver => attr_set.at_ver;
attr_get->at_mode => attr_set.at_mode;
attr_get->at_uid => attr_set.at_uid;
attr_get->at_gid => attr_set.at_gid;
attr_get->at_atim => attr_set.at_atim;
attr_get->at_mtim => attr_set.at_mtim;
attr_get->at_ctim => attr_set.at_ctim;

lfs_file_sync(&lfs, &file) => 0;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
'''
Loading