瀏覽代碼

[DFS] Add fcntl API (same with ioctl in RT-Thread).

BernardXiong 7 年之前
父節點
當前提交
5a95d35626
共有 4 個文件被更改,包括 56 次插入9 次删除
  1. 2 0
      components/dfs/include/dfs_posix.h
  2. 21 1
      components/dfs/src/dfs_file.c
  3. 26 8
      components/dfs/src/dfs_posix.c
  4. 7 0
      include/libc/libc_fcntl.h

+ 2 - 0
components/dfs/include/dfs_posix.h

@@ -22,6 +22,7 @@
  * 2009-05-27     Yi.qiu       The first version.
  * 2010-07-18     Bernard      add stat and statfs structure definitions.
  * 2011-05-16     Yi.qiu       Change parameter name of rename, "new" is C++ key word.
+ * 2017-12-27     Bernard      Add fcntl API.
  */
 
 #ifndef __DFS_POSIX_H__
@@ -66,6 +67,7 @@ int unlink(const char *pathname);
 int stat(const char *file, struct stat *buf);
 int fstat(int fildes, struct stat *buf);
 int fsync(int fildes);
+int fcntl(int fildes, int cmd, void *data);
 int ioctl(int fildes, int cmd, void *data);
 
 /* directory api*/

+ 21 - 1
components/dfs/src/dfs_file.c

@@ -173,9 +173,29 @@ int dfs_file_close(struct dfs_fd *fd)
  */
 int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
 {
-    if (fd == NULL || fd->type != FT_REGULAR)
+    if (fd == NULL)
         return -EINVAL;
 
+    /* regular file system fd */
+    if (fd->type == FT_REGULAR)
+    {
+        switch (cmd)
+        {
+        case F_GETFL:
+            return fd->flags; /* return flags */
+        case F_SETFL:
+            {
+                int flags = (int)args;
+                int mask  = O_NONBLOCK | O_APPEND;
+
+                flags &= mask;
+                fd->flags &= mask;
+                fd->flags |= flags;
+            }
+            return 0;
+        }
+    }
+
     if (fd->fops->ioctl != NULL)
         return fd->fops->ioctl(fd, cmd, args);
 

+ 26 - 8
components/dfs/src/dfs_posix.c

@@ -428,28 +428,46 @@ RTM_EXPORT(fsync);
  * @return 0 on successful completion. Otherwise, -1 shall be returned and errno
  * set to indicate the error.
  */
-int ioctl(int fildes, int cmd, void *data)
+int fcntl(int fildes, int cmd, void *data)
 {
-    int ret;
+    int ret = -1;
     struct dfs_fd *d;
 
     /* get the fd */
     d = fd_get(fildes);
-    if (d == NULL)
+    if (d)
     {
-        rt_set_errno(-EBADF);
-        return -1;
+        ret = dfs_file_ioctl(d, cmd, data);
+        fd_put(d);
     }
+    else ret = -EBADF;
 
-    ret = dfs_file_ioctl(d, cmd, data);
     if (ret != 0)
     {
         rt_set_errno(ret);
         ret = -1;
     }
-    fd_put(d);
 
-    return ret;
+    return 0;
+}
+RTM_EXPORT(fcntl);
+
+/**
+ * this function is a POSIX compliant version, which shall perform a variety of
+ * control functions on devices.
+ *
+ * @param fildes the file description
+ * @param cmd the specified command
+ * @param data represents the additional information that is needed by this
+ * specific device to perform the requested function.
+ *
+ * @return 0 on successful completion. Otherwise, -1 shall be returned and errno
+ * set to indicate the error.
+ */
+int ioctl(int fildes, int cmd, void *data)
+{
+    /* we use fcntl for this API. */
+    return fcntl(fildes, cmd, data);
 }
 RTM_EXPORT(ioctl);
 

+ 7 - 0
include/libc/libc_fcntl.h

@@ -16,6 +16,13 @@
 #define O_ACCMODE   (_O_RDONLY | _O_WRONLY | _O_RDWR)
 #endif
 
+#ifndef F_GETFL
+#define F_GETFL  3
+#endif
+#ifndef F_SETFL
+#define F_SETFL  4
+#endif
+
 #else
 #define O_RDONLY         00
 #define O_WRONLY         01