Bläddra i källkod

✨ feat(components): add statfs, statfs64, fstatfs, fstatfs64 support

xqyjlj 2 år sedan
förälder
incheckning
cd1e0a7901

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

@@ -520,6 +520,32 @@ int statfs(const char *path, struct statfs *buf)
 }
 RTM_EXPORT(statfs);
 
+/**
+ * this function is a POSIX compliant version, which will return the
+ * information about a mounted file system.
+ *
+ * @param fildes the file description.
+ * @param buf the buffer to save the returned information.
+ *
+ * @return 0 on successful, others on failed.
+ */
+int fstatfs(int fildes, struct statfs *buf)
+{
+    struct dfs_fd *d;
+
+    /* get the fd */
+    d = fd_get(fildes);
+    if (d == NULL)
+    {
+        rt_set_errno(-EBADF);
+
+        return -1;
+    }
+
+    return statfs(d->vnode->fullpath, buf);
+}
+RTM_EXPORT(fstatfs);
+
 /**
  * this function is a POSIX compliant version, which will make a directory
  *

+ 16 - 0
components/libc/compilers/common/include/sys/statfs.h

@@ -5,6 +5,7 @@
  *
  * Change Logs:
  * Date           Author       Notes
+ * 2023-03-27     xqyjlj       adapt musl
  */
 
 #ifndef __SYS_STATFS_H__
@@ -16,16 +17,31 @@
 extern "C" {
 #endif
 
+#ifdef RT_USING_MUSLLIBC
+/* this is required for musl <sys/statfs.h> */
+#ifndef _POSIX_SOURCE
+#define _POSIX_SOURCE
+#include_next <sys/statfs.h>
+/* limiting influence of _POSIX_SOURCE */
+#undef _POSIX_SOURCE
+
+#else /* def _POSIX_SOURCE */
+#include_next <sys/statfs.h>
+#endif
+#else
 struct statfs
 {
     size_t f_bsize;   /* block size */
     size_t f_blocks;  /* total data blocks in file system */
     size_t f_bfree;   /* free blocks in file system */
+    size_t f_bavail;  /* free blocks available to unprivileged user*/
 };
 
 int statfs(const char *path, struct statfs *buf);
 int fstatfs(int fd, struct statfs *buf);
 
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 142 - 0
components/lwp/lwp_syscall.c

@@ -4611,6 +4611,144 @@ sysret_t sys_uname(struct utsname *uts)
     return 0;
 }
 
+sysret_t sys_statfs(const char *path, struct statfs *buf)
+{
+    int ret = 0;
+    int err;
+    size_t len;
+    size_t copy_len;
+    char *copy_path;
+    struct statfs statfsbuff = {0};
+
+    if (!lwp_user_accessable((void *)buf, sizeof(struct statfs)))
+    {
+        return -EFAULT;
+    }
+
+    len = lwp_user_strlen(path, &err);
+    if (err)
+    {
+        return -EFAULT;
+    }
+
+    copy_path = (char*)rt_malloc(len + 1);
+    if (!copy_path)
+    {
+        return -ENOMEM;
+    }
+
+    copy_len = lwp_get_from_user(copy_path, (void*)path, len);
+    if (copy_len == 0)
+    {
+        rt_free(copy_path);
+        return -EFAULT;
+    }
+    copy_path[copy_len] = '\0';
+
+    ret = _SYS_WRAP(statfs(copy_path, &statfsbuff));
+    rt_free(copy_path);
+
+    if (ret == 0)
+    {
+        lwp_put_to_user(buf, &statfsbuff, sizeof statfsbuff);
+    }
+
+    return ret;
+}
+
+sysret_t sys_statfs64(const char *path, size_t sz, struct statfs *buf)
+{
+    int ret = 0;
+    int err;
+    size_t len;
+    size_t copy_len;
+    char *copy_path;
+    struct statfs statfsbuff = {0};
+
+    if (!lwp_user_accessable((void *)buf, sizeof(struct statfs)))
+    {
+        return -EFAULT;
+    }
+
+    if (sz != sizeof(struct statfs)) {
+        return -EINVAL;
+    }
+
+    len = lwp_user_strlen(path, &err);
+    if (err)
+    {
+        return -EFAULT;
+    }
+
+    copy_path = (char*)rt_malloc(len + 1);
+    if (!copy_path)
+    {
+        return -ENOMEM;
+    }
+
+    copy_len = lwp_get_from_user(copy_path, (void*)path, len);
+    if (copy_len == 0)
+    {
+        rt_free(copy_path);
+        return -EFAULT;
+    }
+    copy_path[copy_len] = '\0';
+
+    ret = _SYS_WRAP(statfs(copy_path, &statfsbuff));
+    rt_free(copy_path);
+
+    if (ret == 0)
+    {
+        lwp_put_to_user(buf, &statfsbuff, sizeof statfsbuff);
+    }
+
+    return ret;
+}
+
+sysret_t sys_fstatfs(int fd, struct statfs *buf)
+{
+    int ret = 0;
+    struct statfs statfsbuff = {0};
+
+    if (!lwp_user_accessable((void *)buf, sizeof(struct statfs)))
+    {
+        return -EFAULT;
+    }
+
+    ret = _SYS_WRAP(fstatfs(fd, &statfsbuff));
+
+    if (ret == 0)
+    {
+        lwp_put_to_user(buf, &statfsbuff, sizeof statfsbuff);
+    }
+
+    return ret;
+}
+
+sysret_t sys_fstatfs64(int fd, size_t sz, struct statfs *buf)
+{
+    int ret = 0;
+    struct statfs statfsbuff = {0};
+
+    if (!lwp_user_accessable((void *)buf, sizeof(struct statfs)))
+    {
+        return -EFAULT;
+    }
+
+    if (sz != sizeof(struct statfs)) {
+        return -EINVAL;
+    }
+
+    ret = _SYS_WRAP(fstatfs(fd, &statfsbuff));
+
+    if (ret == 0)
+    {
+        lwp_put_to_user(buf, &statfsbuff, sizeof statfsbuff);
+    }
+
+    return ret;
+}
+
 const static struct rt_syscall_def func_table[] =
 {
     SYSCALL_SIGN(sys_exit),            /* 01 */
@@ -4822,6 +4960,10 @@ const static struct rt_syscall_def func_table[] =
     SYSCALL_SIGN(sys_mq_close),
     SYSCALL_SIGN(sys_stat), //TODO should be replaced by sys_lstat if symbolic link are implemented
     SYSCALL_SIGN(sys_uname),                            /* 170 */
+    SYSCALL_SIGN(sys_statfs),
+    SYSCALL_SIGN(sys_statfs64),
+    SYSCALL_SIGN(sys_fstatfs),
+    SYSCALL_SIGN(sys_fstatfs64),
 };
 
 const void *lwp_get_sys_api(rt_uint32_t number)