kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'feature/vfs_spiffs_(f)truncate_support' into 'master'
spiffs: Add vfs (f)truncate api support Closes IDFGH-316 and IDFGH-2880 See merge request espressif/esp-idf!17524pull/8629/head
commit
b95d2e30d0
|
@ -68,6 +68,8 @@ static long vfs_spiffs_telldir(void* ctx, DIR* pdir);
|
||||||
static void vfs_spiffs_seekdir(void* ctx, DIR* pdir, long offset);
|
static void vfs_spiffs_seekdir(void* ctx, DIR* pdir, long offset);
|
||||||
static int vfs_spiffs_mkdir(void* ctx, const char* name, mode_t mode);
|
static int vfs_spiffs_mkdir(void* ctx, const char* name, mode_t mode);
|
||||||
static int vfs_spiffs_rmdir(void* ctx, const char* name);
|
static int vfs_spiffs_rmdir(void* ctx, const char* name);
|
||||||
|
static int vfs_spiffs_truncate(void* ctx, const char *path, off_t length);
|
||||||
|
static int vfs_spiffs_ftruncate(void* ctx, int fd, off_t length);
|
||||||
#ifdef CONFIG_SPIFFS_USE_MTIME
|
#ifdef CONFIG_SPIFFS_USE_MTIME
|
||||||
static int vfs_spiffs_utime(void *ctx, const char *path, const struct utimbuf *times);
|
static int vfs_spiffs_utime(void *ctx, const char *path, const struct utimbuf *times);
|
||||||
#endif // CONFIG_SPIFFS_USE_MTIME
|
#endif // CONFIG_SPIFFS_USE_MTIME
|
||||||
|
@ -352,6 +354,8 @@ esp_err_t esp_vfs_spiffs_register(const esp_vfs_spiffs_conf_t * conf)
|
||||||
.telldir_p = &vfs_spiffs_telldir,
|
.telldir_p = &vfs_spiffs_telldir,
|
||||||
.mkdir_p = &vfs_spiffs_mkdir,
|
.mkdir_p = &vfs_spiffs_mkdir,
|
||||||
.rmdir_p = &vfs_spiffs_rmdir,
|
.rmdir_p = &vfs_spiffs_rmdir,
|
||||||
|
.truncate_p = &vfs_spiffs_truncate,
|
||||||
|
.ftruncate_p = &vfs_spiffs_ftruncate,
|
||||||
#ifdef CONFIG_SPIFFS_USE_MTIME
|
#ifdef CONFIG_SPIFFS_USE_MTIME
|
||||||
.utime_p = &vfs_spiffs_utime,
|
.utime_p = &vfs_spiffs_utime,
|
||||||
#else
|
#else
|
||||||
|
@ -725,6 +729,44 @@ static int vfs_spiffs_rmdir(void* ctx, const char* name)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vfs_spiffs_truncate(void* ctx, const char *path, off_t length)
|
||||||
|
{
|
||||||
|
assert(path);
|
||||||
|
esp_spiffs_t * efs = (esp_spiffs_t *)ctx;
|
||||||
|
int fd = SPIFFS_open(efs->fs, path, SPIFFS_WRONLY, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = SPIFFS_ftruncate(efs->fs, fd, length);
|
||||||
|
if (res < 0) {
|
||||||
|
(void)SPIFFS_close(efs->fs, fd);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = SPIFFS_close(efs->fs, fd);
|
||||||
|
if (res < 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
err:
|
||||||
|
errno = spiffs_res_to_errno(SPIFFS_errno(efs->fs));
|
||||||
|
SPIFFS_clearerr(efs->fs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vfs_spiffs_ftruncate(void* ctx, int fd, off_t length)
|
||||||
|
{
|
||||||
|
esp_spiffs_t * efs = (esp_spiffs_t *)ctx;
|
||||||
|
int res = SPIFFS_ftruncate(efs->fs, fd, length);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = spiffs_res_to_errno(SPIFFS_errno(efs->fs));
|
||||||
|
SPIFFS_clearerr(efs->fs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int vfs_spiffs_link(void* ctx, const char* n1, const char* n2)
|
static int vfs_spiffs_link(void* ctx, const char* n1, const char* n2)
|
||||||
{
|
{
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f5e26c4e933189593a71c6b82cda381a7b21e41c
|
Subproject commit 2b73a7fd31f7608cd3ca46a2da8f53ff3da411b7
|
|
@ -8,6 +8,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
@ -165,6 +166,111 @@ void test_spiffs_rename(const char* filename_prefix)
|
||||||
TEST_ASSERT_EQUAL(0, fclose(fdst));
|
TEST_ASSERT_EQUAL(0, fclose(fdst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_spiffs_truncate(const char *filename)
|
||||||
|
{
|
||||||
|
int read = 0;
|
||||||
|
int truncated_len = 0;
|
||||||
|
|
||||||
|
const char input[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
char output[sizeof(input)];
|
||||||
|
|
||||||
|
test_spiffs_create_file_with_text(filename, input);
|
||||||
|
|
||||||
|
// Extending file beyond size is not supported
|
||||||
|
TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input) + 1));
|
||||||
|
TEST_ASSERT_EQUAL(-1, truncate(filename, -1));
|
||||||
|
|
||||||
|
// Truncating should succeed
|
||||||
|
const char truncated_1[] = "ABCDEFGHIJ";
|
||||||
|
truncated_len = strlen(truncated_1);
|
||||||
|
TEST_ASSERT_EQUAL(0, truncate(filename, truncated_len));
|
||||||
|
|
||||||
|
|
||||||
|
FILE* f = fopen(filename, "rb");
|
||||||
|
TEST_ASSERT_NOT_NULL(f);
|
||||||
|
memset(output, 0, sizeof(output));
|
||||||
|
read = fread(output, 1, sizeof(output), f);
|
||||||
|
TEST_ASSERT_EQUAL(truncated_len, read);
|
||||||
|
TEST_ASSERT_EQUAL_STRING_LEN(truncated_1, output, truncated_len);
|
||||||
|
TEST_ASSERT_EQUAL(0, fclose(f));
|
||||||
|
|
||||||
|
// Once truncated, the new file size should be the basis
|
||||||
|
// whether truncation should succeed or not
|
||||||
|
TEST_ASSERT_EQUAL(-1, truncate(filename, truncated_len + 1));
|
||||||
|
TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input)));
|
||||||
|
TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input) + 1));
|
||||||
|
TEST_ASSERT_EQUAL(-1, truncate(filename, -1));
|
||||||
|
|
||||||
|
|
||||||
|
// Truncating a truncated file should succeed
|
||||||
|
const char truncated_2[] = "ABCDE";
|
||||||
|
truncated_len = strlen(truncated_2);
|
||||||
|
TEST_ASSERT_EQUAL(0, truncate(filename, truncated_len));
|
||||||
|
|
||||||
|
f = fopen(filename, "rb");
|
||||||
|
TEST_ASSERT_NOT_NULL(f);
|
||||||
|
memset(output, 0, sizeof(output));
|
||||||
|
read = fread(output, 1, sizeof(output), f);
|
||||||
|
TEST_ASSERT_EQUAL(truncated_len, read);
|
||||||
|
TEST_ASSERT_EQUAL_STRING_LEN(truncated_2, output, truncated_len);
|
||||||
|
TEST_ASSERT_EQUAL(0, fclose(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_spiffs_ftruncate(const char *filename)
|
||||||
|
{
|
||||||
|
int truncated_len = 0;
|
||||||
|
|
||||||
|
const char input[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
char output[sizeof(input)];
|
||||||
|
|
||||||
|
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(-1, fd);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(strlen(input), write(fd, input, strlen(input)));
|
||||||
|
|
||||||
|
// Extending file beyond size is not supported
|
||||||
|
TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input) + 1));
|
||||||
|
TEST_ASSERT_EQUAL(-1, ftruncate(fd, -1));
|
||||||
|
|
||||||
|
// Truncating should succeed
|
||||||
|
const char truncated_1[] = "ABCDEFGHIJ";
|
||||||
|
truncated_len = strlen(truncated_1);
|
||||||
|
TEST_ASSERT_EQUAL(0, ftruncate(fd, truncated_len));
|
||||||
|
TEST_ASSERT_EQUAL(0, close(fd));
|
||||||
|
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(-1, fd);
|
||||||
|
memset(output, 0, sizeof(output));
|
||||||
|
TEST_ASSERT_EQUAL(truncated_len, read(fd, output, sizeof(output)));
|
||||||
|
TEST_ASSERT_EQUAL_STRING_LEN(truncated_1, output, truncated_len);
|
||||||
|
TEST_ASSERT_EQUAL(0, close(fd));
|
||||||
|
|
||||||
|
// further truncate the file
|
||||||
|
fd = open(filename, O_WRONLY);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(-1, fd);
|
||||||
|
// Once truncated, the new file size should be the basis
|
||||||
|
// whether truncation should succeed or not
|
||||||
|
TEST_ASSERT_EQUAL(-1, ftruncate(fd, truncated_len + 1));
|
||||||
|
TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input)));
|
||||||
|
TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input) + 1));
|
||||||
|
TEST_ASSERT_EQUAL(-1, ftruncate(fd, -1));
|
||||||
|
|
||||||
|
// Truncating a truncated file should succeed
|
||||||
|
const char truncated_2[] = "ABCDE";
|
||||||
|
truncated_len = strlen(truncated_2);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(0, ftruncate(fd, truncated_len));
|
||||||
|
TEST_ASSERT_EQUAL(0, close(fd));
|
||||||
|
|
||||||
|
// open file for reading and validate the content
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(-1, fd);
|
||||||
|
memset(output, 0, sizeof(output));
|
||||||
|
TEST_ASSERT_EQUAL(truncated_len, read(fd, output, sizeof(output)));
|
||||||
|
TEST_ASSERT_EQUAL_STRING_LEN(truncated_2, output, truncated_len);
|
||||||
|
TEST_ASSERT_EQUAL(0, close(fd));
|
||||||
|
}
|
||||||
|
|
||||||
void test_spiffs_can_opendir(const char* path)
|
void test_spiffs_can_opendir(const char* path)
|
||||||
{
|
{
|
||||||
char name_dir_file[64];
|
char name_dir_file[64];
|
||||||
|
@ -574,6 +680,20 @@ TEST_CASE("rename moves a file", "[spiffs]")
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("truncate a file", "[spiffs]")
|
||||||
|
{
|
||||||
|
test_setup();
|
||||||
|
test_spiffs_truncate("/spiffs/truncate.txt");
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ftruncate a file", "[spiffs]")
|
||||||
|
{
|
||||||
|
test_setup();
|
||||||
|
test_spiffs_ftruncate("/spiffs/ftrunc.txt");
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("can opendir root directory of FS", "[spiffs]")
|
TEST_CASE("can opendir root directory of FS", "[spiffs]")
|
||||||
{
|
{
|
||||||
test_setup();
|
test_setup();
|
||||||
|
|
Ładowanie…
Reference in New Issue