Browse Source

[components][dfs]添加ftruncate接口

zhangjun 5 years ago
parent
commit
60f2ae4d3c

+ 25 - 0
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;
 }
 

+ 4 - 0
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
 }

+ 1 - 0
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);

+ 29 - 0
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>
 

+ 46 - 0
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.