mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'fix/fatfs-vfs-fcntl-setfl' into 'master'
fix(fatfs): preserve access mode in VFS F_SETFL See merge request espressif/esp-idf!51880
This commit is contained in:
@@ -195,6 +195,13 @@ TEST_CASE("(WL) overwrite and append file", "[fatfs][wear_levelling]")
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
TEST_CASE("(WL) fcntl F_SETFL preserves access mode", "[fatfs][wear_levelling]")
|
||||
{
|
||||
test_setup();
|
||||
test_fatfs_fcntl_setfl("/spiflash/fcntl.txt");
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
TEST_CASE("(WL) can lseek", "[fatfs][wear_levelling]")
|
||||
{
|
||||
test_setup();
|
||||
|
||||
@@ -94,6 +94,37 @@ void test_fatfs_overwrite_append(const char* filename)
|
||||
TEST_ASSERT_EQUAL(0, fclose(f_r));
|
||||
}
|
||||
|
||||
void test_fatfs_fcntl_setfl(const char* filename)
|
||||
{
|
||||
unlink(filename);
|
||||
int fd = open(filename, O_RDWR | O_CREAT | O_TRUNC);
|
||||
TEST_ASSERT_NOT_EQUAL(-1, fd);
|
||||
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
TEST_ASSERT_NOT_EQUAL(-1, flags);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_ACCMODE);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_APPEND);
|
||||
|
||||
/* F_SETFL must not clobber O_ACCMODE when arg is only a status flag. */
|
||||
TEST_ASSERT_EQUAL(0, fcntl(fd, F_SETFL, O_APPEND));
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_ACCMODE);
|
||||
TEST_ASSERT_NOT_EQUAL(0, flags & O_APPEND);
|
||||
|
||||
TEST_ASSERT_EQUAL(4, write(fd, "AAAA", 4));
|
||||
TEST_ASSERT_NOT_EQUAL(-1, lseek(fd, 0, SEEK_SET));
|
||||
TEST_ASSERT_EQUAL(4, write(fd, "BBBB", 4));
|
||||
TEST_ASSERT_EQUAL(0, close(fd));
|
||||
|
||||
char buf[10] = { 0 };
|
||||
FILE *f_r = fopen(filename, "r");
|
||||
TEST_ASSERT_NOT_NULL(f_r);
|
||||
TEST_ASSERT_EQUAL(8, fread(buf, 1, 8, f_r));
|
||||
TEST_ASSERT_EQUAL_STRING_LEN("AAAABBBB", buf, 8);
|
||||
TEST_ASSERT_EQUAL(0, fclose(f_r));
|
||||
unlink(filename);
|
||||
}
|
||||
|
||||
void test_fatfs_read_file(const char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "r");
|
||||
|
||||
@@ -33,6 +33,8 @@ void test_fatfs_open_file_with_o_creat_flag(const char* filename);
|
||||
|
||||
void test_fatfs_overwrite_append(const char* filename);
|
||||
|
||||
void test_fatfs_fcntl_setfl(const char* filename);
|
||||
|
||||
void test_fatfs_read_file(const char* filename);
|
||||
|
||||
void test_fatfs_read_file_utf_8(const char* filename);
|
||||
|
||||
@@ -719,10 +719,15 @@ static int vfs_fat_fcntl(void* ctx, int fd, int cmd, int arg)
|
||||
case F_GETFL:
|
||||
result = fat_ctx->flags[fd];
|
||||
break;
|
||||
case F_SETFL:
|
||||
fat_ctx->flags[fd] = arg;
|
||||
case F_SETFL: {
|
||||
/* POSIX: F_SETFL changes status flags only; access mode is immutable.
|
||||
* FatFS honors O_APPEND on write(). O_NONBLOCK is stored for F_GETFL
|
||||
* round-trip but does not make I/O non-blocking. */
|
||||
const uint32_t setfl_mask = (uint32_t)(O_APPEND | O_NONBLOCK);
|
||||
fat_ctx->flags[fd] = (fat_ctx->flags[fd] & ~setfl_mask) | ((uint32_t)arg & setfl_mask);
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
// no-ops:
|
||||
case F_SETLK:
|
||||
case F_SETLKW:
|
||||
|
||||
Reference in New Issue
Block a user