diff --git a/components/dfs/filesystems/elmfat/dfs_elm.c b/components/dfs/filesystems/elmfat/dfs_elm.c index 3825fd9108..b4c4c627aa 100644 --- a/components/dfs/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/filesystems/elmfat/dfs_elm.c @@ -478,6 +478,33 @@ 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 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 @@ -471,6 +471,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. diff --git a/components/libc/compilers/newlib/syscalls.c b/components/libc/compilers/newlib/syscalls.c index 9919e11727..59c1881ad1 100644 --- a/components/libc/compilers/newlib/syscalls.c +++ b/components/libc/compilers/newlib/syscalls.c @@ -442,3 +442,18 @@ void abort(void) while (1); } + +uid_t getuid(void) +{ + return 0; +} + +mode_t umask(mode_t mask) +{ + return 022; +} + +int flock(int fd, int operation) +{ + return 0; +}