diff --git a/lfs.c b/lfs.c index c4ef89a..9fe7563 100644 --- a/lfs.c +++ b/lfs.c @@ -2981,6 +2981,7 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { return LFS_ERR_INVAL; } + lfs_off_t pos = file->pos; lfs_off_t oldsize = lfs_file_size(lfs, file); if (size < oldsize) { // need to flush since directly changing metadata @@ -3003,8 +3004,6 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { file->ctz.size = size; file->flags |= LFS_F_DIRTY | LFS_F_READING; } else if (size > oldsize) { - lfs_off_t pos = file->pos; - // flush+seek if not already at end if (file->pos != oldsize) { int err = lfs_file_seek(lfs, file, 0, LFS_SEEK_END); @@ -3022,13 +3021,13 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { return res; } } + } - // restore pos - int err = lfs_file_seek(lfs, file, pos, LFS_SEEK_SET); - if (err < 0) { - LFS_TRACE("lfs_file_truncate -> %d", err); - return err; - } + // restore pos + int err = lfs_file_seek(lfs, file, pos, LFS_SEEK_SET); + if (err < 0) { + LFS_TRACE("lfs_file_truncate -> %d", err); + return err; } LFS_TRACE("lfs_file_truncate -> %d", 0); diff --git a/tests/test_truncate.sh b/tests/test_truncate.sh index ee42693..f33717d 100755 --- a/tests/test_truncate.sh +++ b/tests/test_truncate.sh @@ -107,6 +107,57 @@ scripts/test.py << TEST lfs_unmount(&lfs) => 0; TEST +echo "--- Write, truncate, and read ---" +scripts/test.py << TEST + lfs_mount(&lfs, &cfg) => 0; + lfs_file_open(&lfs, &file, "sequence", + LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0; + + lfs_size_t size = lfs.cfg->cache_size; + lfs_size_t qsize = size / 4; + uint8_t *wb = buffer; + uint8_t *rb = buffer + size; + for (lfs_off_t j = 0; j < size; ++j) { + wb[j] = j; + } + + /* Spread sequence over size */ + lfs_file_write(&lfs, &file, wb, size) => size; + lfs_file_size(&lfs, &file) => size; + lfs_file_tell(&lfs, &file) => size; + + lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0; + lfs_file_tell(&lfs, &file) => 0; + + /* Chop off the last quarter */ + lfs_size_t trunc = size - qsize; + lfs_file_truncate(&lfs, &file, trunc) => 0; + lfs_file_tell(&lfs, &file) => 0; + lfs_file_size(&lfs, &file) => trunc; + + /* Read should produce first 3/4 */ + lfs_file_read(&lfs, &file, rb, size) => trunc; + memcmp(rb, wb, trunc) => 0; + + /* Move to 1/4 */ + lfs_file_size(&lfs, &file) => trunc; + lfs_file_seek(&lfs, &file, qsize, LFS_SEEK_SET) => qsize; + lfs_file_tell(&lfs, &file) => qsize; + + /* Chop to 1/2 */ + trunc -= qsize; + lfs_file_truncate(&lfs, &file, trunc) => 0; + lfs_file_tell(&lfs, &file) => qsize; + lfs_file_size(&lfs, &file) => trunc; + + /* Read should produce second quarter */ + lfs_file_read(&lfs, &file, rb, size) => trunc - qsize; + memcmp(rb, wb + qsize, trunc - qsize) => 0; + + lfs_file_close(&lfs, &file) => 0; + lfs_unmount(&lfs) => 0; +TEST + echo "--- Truncate and write ---" scripts/test.py << TEST lfs_mount(&lfs, &cfg) => 0;