Преглед изворни кода

[component] add openat syscall. (#7488)

geniusgogo пре 2 година
родитељ
комит
0e4a3142a8
3 измењених фајлова са 136 додато и 0 уклоњено
  1. 47 0
      components/dfs/dfs_v1/src/dfs_posix.c
  2. 47 0
      components/dfs/dfs_v2/src/dfs_posix.c
  3. 42 0
      components/lwp/lwp_syscall.c

+ 47 - 0
components/dfs/dfs_v1/src/dfs_posix.c

@@ -62,6 +62,53 @@ int open(const char *file, int flags, ...)
 }
 }
 RTM_EXPORT(open);
 RTM_EXPORT(open);
 
 
+#ifndef AT_FDCWD
+#define AT_FDCWD (-100)
+#endif
+int openat(int dirfd, const char *path, int flag, ...)
+{
+    struct dfs_file *d;
+    char *fullpath;
+    int fd;
+
+    if (!path)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
+    fullpath = (char*)path;
+
+    if (path[0] != '/')
+    {
+        if (dirfd != AT_FDCWD)
+        {
+            d = fd_get(dirfd);
+            if (!d || !d->vnode)
+            {
+                rt_set_errno(-EBADF);
+                return -1;
+            }
+
+            fullpath = dfs_normalize_path(d->vnode->fullpath, path);
+            if (!fullpath)
+            {
+                rt_set_errno(-ENOMEM);
+                return -1;
+            }
+        }
+    }
+
+    fd = open(fullpath, flag, 0);
+
+    if (fullpath != path)
+    {
+        rt_free(fullpath);
+    }
+
+    return fd;
+}
+
 /**
 /**
  * this function is a POSIX compliant version,
  * this function is a POSIX compliant version,
  * which will create a new file or rewrite an existing one
  * which will create a new file or rewrite an existing one

+ 47 - 0
components/dfs/dfs_v2/src/dfs_posix.c

@@ -62,6 +62,53 @@ int open(const char *file, int flags, ...)
 }
 }
 RTM_EXPORT(open);
 RTM_EXPORT(open);
 
 
+#ifndef AT_FDCWD
+#define AT_FDCWD (-100)
+#endif
+int openat(int dirfd, const char *path, int flag, ...)
+{
+    struct dfs_file *d;
+    char *fullpath;
+    int fd;
+
+    if (!path)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
+    fullpath = (char*)path;
+
+    if (path[0] != '/')
+    {
+        if (dirfd != AT_FDCWD)
+        {
+            d = fd_get(dirfd);
+            if (!d || !d->vnode)
+            {
+                rt_set_errno(-EBADF);
+                return -1;
+            }
+
+            fullpath = dfs_normalize_path(d->vnode->fullpath, path);
+            if (!fullpath)
+            {
+                rt_set_errno(-ENOMEM);
+                return -1;
+            }
+        }
+    }
+
+    fd = open(fullpath, flag, 0);
+
+    if (fullpath != path)
+    {
+        rt_free(fullpath);
+    }
+
+    return fd;
+}
+
 /**
 /**
  * this function is a POSIX compliant version,
  * this function is a POSIX compliant version,
  * which will create a new file or rewrite an existing one
  * which will create a new file or rewrite an existing one

+ 42 - 0
components/lwp/lwp_syscall.c

@@ -518,6 +518,47 @@ sysret_t sys_open(const char *name, int flag, ...)
 #endif
 #endif
 }
 }
 
 
+/* syscall: "open" ret: "int" args: "const char *" "mode_t" "mode" */
+sysret_t sys_openat(int dirfd, const char *name, int flag, mode_t mode)
+{
+#ifdef ARCH_MM_MMU
+    int ret = -1;
+    int err = 0;
+    rt_size_t len = 0;
+    char *kname = RT_NULL;
+
+    len = lwp_user_strlen(name, &err);
+    if (!len || err != 0)
+    {
+        return -EINVAL;
+    }
+
+    kname = (char *)kmem_get(len + 1);
+    if (!kname)
+    {
+        return -ENOMEM;
+    }
+
+    lwp_get_from_user(kname, (void *)name, len + 1);
+    ret = openat(dirfd, kname, flag, mode);
+    if (ret < 0)
+    {
+        ret = GET_ERRNO();
+    }
+
+    kmem_put(kname);
+
+    return ret;
+#else
+    if (!lwp_user_accessable((void *)name, 1))
+    {
+        return -EFAULT;
+    }
+    int ret = openat(dirfd, name, flag, mode);
+    return (ret < 0 ? GET_ERRNO() : ret);
+#endif
+}
+
 /* syscall: "close" ret: "int" args: "int" */
 /* syscall: "close" ret: "int" args: "int" */
 sysret_t sys_close(int fd)
 sysret_t sys_close(int fd)
 {
 {
@@ -4995,6 +5036,7 @@ const static struct rt_syscall_def func_table[] =
     SYSCALL_SIGN(sys_statfs64),
     SYSCALL_SIGN(sys_statfs64),
     SYSCALL_SIGN(sys_fstatfs),
     SYSCALL_SIGN(sys_fstatfs),
     SYSCALL_SIGN(sys_fstatfs64),
     SYSCALL_SIGN(sys_fstatfs64),
+    SYSCALL_SIGN(sys_openat),                           /* 175 */
 };
 };
 
 
 const void *lwp_get_sys_api(rt_uint32_t number)
 const void *lwp_get_sys_api(rt_uint32_t number)