vfs, fatfs: Add file truncate for fatfs

This commit is contained in:
Renz Bagaporo
2018-06-12 18:29:05 +08:00
committed by Renz Christian Bagaporo
parent 0e501e5edd
commit ea711f2ee9
9 changed files with 214 additions and 2 deletions

View File

@@ -85,6 +85,7 @@ static int vfs_fat_closedir(void* ctx, DIR* pdir);
static int vfs_fat_mkdir(void* ctx, const char* name, mode_t mode);
static int vfs_fat_rmdir(void* ctx, const char* name);
static int vfs_fat_access(void* ctx, const char *path, int amode);
static int vfs_fat_truncate(void* ctx, const char *path, off_t length);
static vfs_fat_ctx_t* s_fat_ctxs[FF_VOLUMES] = { NULL, NULL };
//backwards-compatibility with esp_vfs_fat_unregister()
@@ -144,6 +145,7 @@ esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive, siz
.mkdir_p = &vfs_fat_mkdir,
.rmdir_p = &vfs_fat_rmdir,
.access_p = &vfs_fat_access,
.truncate_p = &vfs_fat_truncate,
};
size_t ctx_size = sizeof(vfs_fat_ctx_t) + max_files * sizeof(FIL);
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) calloc(1, ctx_size);
@@ -751,3 +753,74 @@ static int vfs_fat_access(void* ctx, const char *path, int amode)
return ret;
}
static int vfs_fat_truncate(void* ctx, const char *path, off_t length)
{
FRESULT res;
FIL* file;
int ret = 0;
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
_lock_acquire(&fat_ctx->lock);
prepend_drive_to_path(fat_ctx, &path, NULL);
file = (FIL*) calloc(1, sizeof(FIL));
if (file == NULL) {
ESP_LOGD(TAG, "truncate alloc failed");
errno = ENOMEM;
ret = -1;
goto out;
}
res = f_open(file, path, FA_WRITE);
if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res);
ret = -1;
goto out;
}
res = f_size(file);
if (res < length) {
ESP_LOGD(TAG, "truncate does not support extending size");
errno = EPERM;
ret = -1;
goto close;
}
res = f_lseek(file, length);
if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res);
ret = -1;
goto close;
}
res = f_truncate(file);
if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res);
ret = -1;
}
close:
res = f_close(file);
if (res != FR_OK) {
ESP_LOGE(TAG, "closing file opened for truncate failed");
// Overwrite previous errors, since not being able to close
// an opened file is a more critical issue.
errno = fresult_to_errno(res);
ret = -1;
}
out:
free(file);
_lock_release(&fat_ctx->lock);
return ret;
}