diff options
| author | xqyjlj <[email protected]> | 2023-03-29 11:54:25 +0800 |
|---|---|---|
| committer | guo <[email protected]> | 2023-03-31 10:56:37 +0800 |
| commit | cd1e0a790124c216c5df3d3eb448e98f37f22097 (patch) | |
| tree | 8ae0d8b8805c6b98a7948f2b0d17759e39986775 /components/lwp/lwp_syscall.c | |
| parent | e4bd8e00f0e7b56b181c810f73249eb6fc9b63f9 (diff) | |
✨ feat(components): add statfs, statfs64, fstatfs, fstatfs64 support
Diffstat (limited to 'components/lwp/lwp_syscall.c')
| -rw-r--r-- | components/lwp/lwp_syscall.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index db5434264c..e7851c29cd 100644 --- a/components/lwp/lwp_syscall.c +++ b/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) |
