diff options
| author | zhangjun <[email protected]> | 2019-09-26 10:22:33 +0800 |
|---|---|---|
| committer | zhangjun <[email protected]> | 2019-09-26 10:22:33 +0800 |
| commit | 60f2ae4d3cee0cbf200a89df21a3949c92125cf4 (patch) | |
| tree | 26ccd41430442e07e9509711df6cbfcf2ff64228 | |
| parent | 2a39e590244cc0a8501669e409c5b07fa4d33176 (diff) | |
[components][dfs]添加ftruncate接口
| -rw-r--r-- | components/dfs/filesystems/elmfat/dfs_elm.c | 25 | ||||
| -rw-r--r-- | components/dfs/include/dfs_file.h | 4 | ||||
| -rw-r--r-- | components/dfs/include/dfs_posix.h | 1 | ||||
| -rw-r--r-- | components/dfs/src/dfs_file.c | 29 | ||||
| -rw-r--r-- | components/dfs/src/dfs_posix.c | 46 |
5 files changed, 105 insertions, 0 deletions
diff --git a/components/dfs/filesystems/elmfat/dfs_elm.c b/components/dfs/filesystems/elmfat/dfs_elm.c index 3825fd9108..b6d2c2388a 100644 --- a/components/dfs/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/filesystems/elmfat/dfs_elm.c @@ -478,6 +478,31 @@ int dfs_elm_close(struct dfs_fd *file) int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args) { + switch (cmd) + { + case RT_FIOFTRUNCATE: + { + FIL *fd; + FSIZE_t fptr, length; + FRESULT result = FR_OK; + fd = (FIL *)(file->data); + RT_ASSERT(fd != RT_NULL); + + /* save file read/write point */ + fptr = fd->fptr; + length = *(off_t*)args; + if (length <= fd->obj.objsize) + { + fd->fptr = length; + result = f_truncate(fd); + }else{ + result = f_lseek(fd, length); + } + /* restore file read/write point */ + fd->fptr = fptr; + return elm_result_to_dfs(result); + } + } return -ENOSYS; } diff --git a/components/dfs/include/dfs_file.h b/components/dfs/include/dfs_file.h index aaff3f6e9c..2dfacd653e 100644 --- a/components/dfs/include/dfs_file.h +++ b/components/dfs/include/dfs_file.h @@ -66,6 +66,10 @@ int dfs_file_lseek(struct dfs_fd *fd, off_t offset); int dfs_file_stat(const char *path, struct stat *buf); int dfs_file_rename(const char *oldpath, const char *newpath); +int dfs_file_ftruncate(struct dfs_fd *fd, off_t length); + +/* 0x5254 is just a magic number to make these relatively unique ("RT") */ +#define RT_FIOFTRUNCATE 0x52540000U #ifdef __cplusplus } diff --git a/components/dfs/include/dfs_posix.h b/components/dfs/include/dfs_posix.h index 9fd76debe2..87d5f0771e 100644 --- a/components/dfs/include/dfs_posix.h +++ b/components/dfs/include/dfs_posix.h @@ -58,6 +58,7 @@ int fstat(int fildes, struct stat *buf); int fsync(int fildes); int fcntl(int fildes, int cmd, ...); int ioctl(int fildes, int cmd, ...); +int ftruncate(int fd, off_t length); /* directory api*/ int rmdir(const char *path); diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index 5f090a7f6b..1063a278ab 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -482,6 +482,35 @@ __exit: return result; } +/** + * this function is will cause the regular file referenced by fd + * to be truncated to a size of precisely length bytes. + * + * @param fd the file descriptor. + * @param length the length to be truncated. + * + * @return the status of truncated. + */ +int dfs_file_ftruncate(struct dfs_fd *fd, off_t length) +{ + int result; + + /* fd is null or not a regular file system fd, or length is invalid */ + if (fd == NULL || fd->type != FT_REGULAR || length < 0) + return -EINVAL; + + if (fd->fops->ioctl == NULL) + return -ENOSYS; + + result = fd->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length); + + /* update current size */ + if (result == 0) + fd->size = length; + + return result; +} + #ifdef RT_USING_FINSH #include <finsh.h> diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c index 69fe56a84e..fc603df437 100644 --- a/components/dfs/src/dfs_posix.c +++ b/components/dfs/src/dfs_posix.c @@ -472,6 +472,52 @@ int ioctl(int fildes, int cmd, ...) RTM_EXPORT(ioctl); /** + * + * this function is a POSIX compliant version, which cause the regular file + * referenced by fd to be truncated to a size of precisely length bytes. + * @param fd the file descriptor. + * @param length the length to be truncated. + * + * @return Upon successful completion, ftruncate() shall return 0; + * otherwise, -1 shall be returned and errno set to indicate the error. + */ +int ftruncate(int fd, off_t length) +{ + int result; + struct dfs_fd *d; + + d = fd_get(fd); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + if (length < 0) + { + fd_put(d); + rt_set_errno(-EINVAL); + + return -1; + } + result = dfs_file_ftruncate(d, length); + if (result < 0) + { + fd_put(d); + rt_set_errno(result); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + + return 0; +} +RTM_EXPORT(ftruncate); + +/** * this function is a POSIX compliant version, which will return the * information about a mounted file system. * |
