mirror of
https://github.com/pellepl/spiffs.git
synced 2026-06-05 21:15:18 +00:00
Merge pull request #287 from vamshi51/feature/spiffs_ftruncate
Feature/spiffs ftruncate
This commit is contained in:
@@ -496,6 +496,15 @@ s32_t SPIFFS_remove(spiffs *fs, const char *path);
|
||||
*/
|
||||
s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh);
|
||||
|
||||
/**
|
||||
* Truncates a file at given size
|
||||
* @param fs the file system struct
|
||||
* @param fh the filehandle of the file to truncate
|
||||
* @param new_size the new size, must be less than existing file size
|
||||
* @returns 0 on success, error code otherwise
|
||||
*/
|
||||
s32_t SPIFFS_ftruncate(spiffs* fs, spiffs_file fh, u32_t new_size);
|
||||
|
||||
/**
|
||||
* Gets file status by path
|
||||
* @param fs the file system struct
|
||||
|
||||
@@ -724,6 +724,45 @@ s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) {
|
||||
#endif // SPIFFS_READ_ONLY
|
||||
}
|
||||
|
||||
s32_t SPIFFS_ftruncate(spiffs* fs, spiffs_file fh, u32_t new_size) {
|
||||
#if SPIFFS_READ_ONLY
|
||||
(void)fs; (void)fh; (void)new_size;
|
||||
return SPIFFS_ERR_RO_NOT_IMPL;
|
||||
#else
|
||||
SPIFFS_API_CHECK_CFG(fs);
|
||||
SPIFFS_API_CHECK_MOUNT(fs);
|
||||
SPIFFS_LOCK(fs);
|
||||
|
||||
spiffs_fd* fd;
|
||||
|
||||
fh = SPIFFS_FH_UNOFFS(fs, fh);
|
||||
s32_t res = spiffs_fd_get(fs, fh, &fd);
|
||||
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||
|
||||
if ((fd->flags & SPIFFS_O_WRONLY) == 0) {
|
||||
res = SPIFFS_ERR_NOT_WRITABLE;
|
||||
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||
}
|
||||
|
||||
#if SPIFFS_CACHE_WR
|
||||
spiffs_fflush_cache(fs, fh);
|
||||
#endif
|
||||
|
||||
u32_t file_size = (fd->size == SPIFFS_UNDEFINED_LEN) ? 0 : fd->size;
|
||||
if (new_size == file_size) {
|
||||
res = SPIFFS_OK;
|
||||
} else if (new_size > file_size) {
|
||||
res = SPIFFS_ERR_END_OF_OBJECT; // Same error we'd get from SPIFFS_lseek
|
||||
} else {
|
||||
res = spiffs_object_truncate(fd, new_size, 0);
|
||||
}
|
||||
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||
|
||||
SPIFFS_UNLOCK(fs);
|
||||
return SPIFFS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) {
|
||||
(void)fh;
|
||||
spiffs_page_object_ix_header objix_hdr;
|
||||
|
||||
@@ -1003,6 +1003,65 @@ TEST(truncate_big_file)
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST(ftruncate_file)
|
||||
{
|
||||
int truncated_len = 0;
|
||||
char input[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
char output[sizeof(input)];
|
||||
|
||||
spiffs_file fd = SPIFFS_open(FS, "ftruncate", SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC , 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
TEST_CHECK_EQ(strlen(input), SPIFFS_write(FS, fd, input, strlen(input)));
|
||||
|
||||
// Extending file beyond size is not supported
|
||||
TEST_CHECK_EQ(SPIFFS_ERR_END_OF_OBJECT, SPIFFS_ftruncate(FS, fd, strlen(input) + 1));
|
||||
TEST_CHECK_EQ(SPIFFS_ERR_END_OF_OBJECT, SPIFFS_ftruncate(FS, fd, -1));
|
||||
|
||||
// Truncating should succeed
|
||||
const char truncated_1[] = "ABCDEFGHIJ";
|
||||
truncated_len = strlen(truncated_1);
|
||||
TEST_CHECK_EQ(0, SPIFFS_ftruncate(FS, fd, truncated_len));
|
||||
TEST_CHECK_EQ(0, SPIFFS_close(FS, fd));
|
||||
|
||||
// open file for reading and validate the content
|
||||
fd = SPIFFS_open(FS, "ftruncate", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
memset(output, 0, sizeof(output));
|
||||
TEST_CHECK_EQ(truncated_len, SPIFFS_read(FS, fd, output, sizeof(output)));
|
||||
TEST_CHECK_EQ(0, strncmp(truncated_1, output, truncated_len));
|
||||
TEST_CHECK_EQ(0, SPIFFS_close(FS, fd));
|
||||
|
||||
// further truncate the file
|
||||
fd = SPIFFS_open(FS, "ftruncate", SPIFFS_WRONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
// Once truncated, the new file size should be the basis
|
||||
// whether truncation should succeed or not
|
||||
TEST_CHECK_EQ(SPIFFS_ERR_END_OF_OBJECT, SPIFFS_ftruncate(FS, fd, truncated_len + 1));
|
||||
TEST_CHECK_EQ(SPIFFS_ERR_END_OF_OBJECT, SPIFFS_ftruncate(FS, fd, strlen(input)));
|
||||
TEST_CHECK_EQ(SPIFFS_ERR_END_OF_OBJECT, SPIFFS_ftruncate(FS, fd, strlen(input) + 1));
|
||||
TEST_CHECK_EQ(SPIFFS_ERR_END_OF_OBJECT, SPIFFS_ftruncate(FS, fd, -1));
|
||||
|
||||
// Truncating a truncated file should succeed
|
||||
const char truncated_2[] = "ABCDE";
|
||||
truncated_len = strlen(truncated_2);
|
||||
|
||||
TEST_CHECK_EQ(0, SPIFFS_ftruncate(FS, fd, truncated_len));
|
||||
TEST_CHECK_EQ(0, SPIFFS_close(FS, fd));
|
||||
|
||||
// open file for reading and validate the content
|
||||
fd = SPIFFS_open(FS, "ftruncate", SPIFFS_RDONLY, 0);
|
||||
TEST_CHECK(fd > 0);
|
||||
|
||||
memset(output, 0, sizeof(output));
|
||||
|
||||
TEST_CHECK_EQ(truncated_len, SPIFFS_read(FS, fd, output, sizeof(output)));
|
||||
TEST_CHECK_EQ(0, strncmp(truncated_2, output, truncated_len));
|
||||
|
||||
TEST_CHECK_EQ(0, SPIFFS_close(FS, fd));
|
||||
|
||||
return TEST_RES_OK;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST(simultaneous_write) {
|
||||
int res = SPIFFS_creat(FS, "simul1", 0);
|
||||
@@ -2471,6 +2530,7 @@ SUITE_TESTS(hydrogen_tests)
|
||||
ADD_TEST(write_big_file_chunks_huge)
|
||||
ADD_TEST(write_big_files_chunks_huge)
|
||||
ADD_TEST(truncate_big_file)
|
||||
ADD_TEST(ftruncate_file)
|
||||
ADD_TEST(simultaneous_write)
|
||||
ADD_TEST(simultaneous_write_append)
|
||||
ADD_TEST(file_uniqueness)
|
||||
|
||||
Reference in New Issue
Block a user