diff --git a/src/spiffs.h b/src/spiffs.h index c9a7865..58e49fb 100644 --- a/src/spiffs.h +++ b/src/spiffs.h @@ -501,7 +501,7 @@ s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh); * @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 - * @retval s32_t error code + * @returns 0 on success, error code otherwise */ s32_t SPIFFS_ftruncate(spiffs* fs, spiffs_file fh, u32_t new_size); diff --git a/src/spiffs_hydrogen.c b/src/spiffs_hydrogen.c index e937fdf..bfeb3cf 100644 --- a/src/spiffs_hydrogen.c +++ b/src/spiffs_hydrogen.c @@ -748,7 +748,7 @@ s32_t SPIFFS_ftruncate(spiffs* fs, spiffs_file fh, u32_t new_size) { spiffs_fflush_cache(fs, fh); #endif - s32_t file_size = (fd->size == SPIFFS_UNDEFINED_LEN) ? 0 : fd->size; + 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) { diff --git a/src/test/test_hydrogen.c b/src/test/test_hydrogen.c index 52126b2..72aea74 100644 --- a/src/test/test_hydrogen.c +++ b/src/test/test_hydrogen.c @@ -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)