diff --git a/lfs.c b/lfs.c index d35d5d6db..3d8420b68 100644 --- a/lfs.c +++ b/lfs.c @@ -6235,6 +6235,41 @@ 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)); + + return 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); +} + +#ifndef LFS_READONLY +int lfs_file_setattr(lfs_t *lfs, lfs_file_t *file, + uint8_t type, const void *buffer, lfs_size_t size) +{ + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_getattr(%p, %p)", (void*)lfs, (void*)file); + LFS_TRACE("lfs_file_getattr(%"PRIu8", %p, %"PRIu32")", + type, buffer, size); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + return lfs_dir_commit(lfs, &file->m, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_USERATTR + type, file->id, size), buffer})); +} +#endif + #ifndef LFS_READONLY int lfs_mkdir(lfs_t *lfs, const char *path) { int err = LFS_LOCK(lfs->cfg); diff --git a/lfs.h b/lfs.h index 847389737..35a70dd79 100644 --- a/lfs.h +++ b/lfs.h @@ -657,6 +657,33 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file); lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file); +// Get a custom attribute of file +// +// Custom attributes are uniquely identified by an 8-bit type and limited +// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller than +// the buffer, it will be padded with zeros. If the stored attribute is larger, +// then it will be silently truncated. If no attribute is found, the error +// LFS_ERR_NOATTR is returned and the buffer is filled with zeros. +// +// Returns the size of the attribute, or a negative error code on failure. +// Note, the returned size is the size of the attribute on disk, irrespective +// of the size of the buffer. This can be used to dynamically allocate a buffer +// or check for existance. +lfs_ssize_t lfs_file_getattr(lfs_t *lfs, lfs_file_t *file, + uint8_t type, void *buffer, lfs_size_t size); + +// Set custom attributes of file +// +// Custom attributes are uniquely identified by an 8-bit type and limited +// to LFS_ATTR_MAX bytes. If an attribute is not found, it will be +// implicitly created. +// +// Returns a negative error code on failure. +#ifndef LFS_READONLY +int lfs_file_setattr(lfs_t *lfs, lfs_file_t *file, + uint8_t type, const void *buffer, lfs_size_t size); +#endif + /// Directory operations /// #ifndef LFS_READONLY