|
@@ -76,6 +76,8 @@
|
|
#include "lwp_ipc_internal.h"
|
|
#include "lwp_ipc_internal.h"
|
|
#include <sched.h>
|
|
#include <sched.h>
|
|
|
|
|
|
|
|
+#include <sys/sysinfo.h>
|
|
|
|
+
|
|
#ifndef GRND_NONBLOCK
|
|
#ifndef GRND_NONBLOCK
|
|
#define GRND_NONBLOCK 0x0001
|
|
#define GRND_NONBLOCK 0x0001
|
|
#endif /* GRND_NONBLOCK */
|
|
#endif /* GRND_NONBLOCK */
|
|
@@ -2621,6 +2623,54 @@ sysret_t sys_stat(const char *file, struct stat *buf)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+sysret_t sys_lstat(const char *file, struct stat *buf)
|
|
|
|
+{
|
|
|
|
+ int ret = 0;
|
|
|
|
+ int err;
|
|
|
|
+ size_t len;
|
|
|
|
+ size_t copy_len;
|
|
|
|
+ char *copy_path;
|
|
|
|
+ struct stat statbuff = {0};
|
|
|
|
+
|
|
|
|
+ if (!lwp_user_accessable((void *)buf, sizeof(struct stat)))
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ len = lwp_user_strlen(file, &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*)file, len);
|
|
|
|
+ if (copy_len == 0)
|
|
|
|
+ {
|
|
|
|
+ rt_free(copy_path);
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+ copy_path[copy_len] = '\0';
|
|
|
|
+#ifdef RT_USING_DFS_V2
|
|
|
|
+ ret = _SYS_WRAP(dfs_file_lstat(copy_path, &statbuff));
|
|
|
|
+#else
|
|
|
|
+ ret = _SYS_WRAP(stat(copy_path, &statbuff));
|
|
|
|
+#endif
|
|
|
|
+ rt_free(copy_path);
|
|
|
|
+
|
|
|
|
+ if (ret == 0)
|
|
|
|
+ {
|
|
|
|
+ lwp_put_to_user(buf, &statbuff, sizeof statbuff);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
sysret_t sys_notimpl(void)
|
|
sysret_t sys_notimpl(void)
|
|
{
|
|
{
|
|
return -ENOSYS;
|
|
return -ENOSYS;
|
|
@@ -4292,6 +4342,99 @@ sysret_t sys_setaffinity(pid_t pid, size_t size, void *set)
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+sysret_t sys_getaffinity(pid_t pid, size_t size, void *set)
|
|
|
|
+{
|
|
|
|
+#ifdef ARCH_MM_MMU
|
|
|
|
+ cpu_set_t mask;
|
|
|
|
+ struct rt_lwp *lwp;
|
|
|
|
+
|
|
|
|
+ if (size <= 0 || size > sizeof(cpu_set_t))
|
|
|
|
+ {
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ if (!lwp_user_accessable(set, size))
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (pid == 0) lwp = lwp_self();
|
|
|
|
+ else lwp = lwp_from_pid(pid);
|
|
|
|
+ if (!lwp)
|
|
|
|
+ {
|
|
|
|
+ return -ESRCH;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifdef RT_USING_SMP
|
|
|
|
+ if (lwp->bind_cpu == RT_CPUS_NR) /* not bind */
|
|
|
|
+ {
|
|
|
|
+ CPU_ZERO_S(size, &mask);
|
|
|
|
+ }
|
|
|
|
+ else /* set bind cpu */
|
|
|
|
+ {
|
|
|
|
+ /* TODO: only single-core bindings are now supported of rt-smart */
|
|
|
|
+ CPU_SET_S(lwp->bind_cpu, size, &mask);
|
|
|
|
+ }
|
|
|
|
+#else
|
|
|
|
+ CPU_SET_S(0, size, &mask);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (lwp_put_to_user(set, &mask, size) != size)
|
|
|
|
+ {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+#else
|
|
|
|
+ return -1;
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+sysret_t sys_sysinfo(void *info)
|
|
|
|
+{
|
|
|
|
+#ifdef ARCH_MM_MMU
|
|
|
|
+ struct sysinfo kinfo = {0};
|
|
|
|
+ rt_size_t total_pages = 0, free_pages = 0;
|
|
|
|
+
|
|
|
|
+ if (!lwp_user_accessable(info, sizeof(struct sysinfo)))
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ kinfo.uptime = rt_tick_get_millisecond() / 1000;
|
|
|
|
+ /* TODO: 1, 5, and 15 minute load averages */
|
|
|
|
+ kinfo.loads[0] = kinfo.loads[1] = kinfo.loads[2] = rt_object_get_length(RT_Object_Class_Thread);
|
|
|
|
+ rt_page_get_info(&total_pages, &free_pages);
|
|
|
|
+ kinfo.totalram = total_pages;
|
|
|
|
+ kinfo.freeram = free_pages;
|
|
|
|
+
|
|
|
|
+ /* TODO: implementation procfs, here is counter the lwp number */
|
|
|
|
+ struct lwp_avl_struct *pids = lwp_get_pid_ary();
|
|
|
|
+ for (int index = 0; index < RT_LWP_MAX_NR; index++)
|
|
|
|
+ {
|
|
|
|
+ struct rt_lwp *lwp = (struct rt_lwp *)pids[index].data;
|
|
|
|
+
|
|
|
|
+ if (lwp)
|
|
|
|
+ {
|
|
|
|
+ kinfo.procs++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rt_page_high_get_info(&total_pages, &free_pages);
|
|
|
|
+ kinfo.totalhigh = total_pages;
|
|
|
|
+ kinfo.freehigh = free_pages;
|
|
|
|
+ kinfo.mem_unit = ARCH_PAGE_SIZE;
|
|
|
|
+
|
|
|
|
+ if (lwp_put_to_user(info, &kinfo, sizeof(struct sysinfo)) != sizeof(struct sysinfo))
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+#else
|
|
|
|
+ return -1;
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
sysret_t sys_sched_setparam(pid_t pid, void *param)
|
|
sysret_t sys_sched_setparam(pid_t pid, void *param)
|
|
{
|
|
{
|
|
struct sched_param *sched_param = (struct sched_param *)param;
|
|
struct sched_param *sched_param = (struct sched_param *)param;
|
|
@@ -4901,6 +5044,60 @@ sysret_t sys_umount2(char *__special_file, int __flags)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+sysret_t sys_link(const char *existing, const char *new)
|
|
|
|
+{
|
|
|
|
+ int ret = -1;
|
|
|
|
+
|
|
|
|
+#ifdef ARCH_MM_MMU
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ lwp_user_strlen(existing, &err);
|
|
|
|
+ if (err)
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ lwp_user_strlen(new, &err);
|
|
|
|
+ if (err)
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+#ifdef RT_USING_DFS_V2
|
|
|
|
+ ret = dfs_file_link(existing, new);
|
|
|
|
+#else
|
|
|
|
+ SET_ERRNO(EFAULT);
|
|
|
|
+#endif
|
|
|
|
+ return (ret < 0 ? GET_ERRNO() : ret);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+sysret_t sys_symlink(const char *existing, const char *new)
|
|
|
|
+{
|
|
|
|
+ int ret = -1;
|
|
|
|
+
|
|
|
|
+#ifdef ARCH_MM_MMU
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ lwp_user_strlen(existing, &err);
|
|
|
|
+ if (err)
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ lwp_user_strlen(new, &err);
|
|
|
|
+ if (err)
|
|
|
|
+ {
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+#ifdef RT_USING_DFS_V2
|
|
|
|
+ ret = dfs_file_symlink(existing, new);
|
|
|
|
+#else
|
|
|
|
+ SET_ERRNO(EFAULT);
|
|
|
|
+#endif
|
|
|
|
+ return (ret < 0 ? GET_ERRNO() : ret);
|
|
|
|
+}
|
|
|
|
+
|
|
const static struct rt_syscall_def func_table[] =
|
|
const static struct rt_syscall_def func_table[] =
|
|
{
|
|
{
|
|
SYSCALL_SIGN(sys_exit), /* 01 */
|
|
SYSCALL_SIGN(sys_exit), /* 01 */
|
|
@@ -5110,7 +5307,7 @@ const static struct rt_syscall_def func_table[] =
|
|
SYSCALL_SIGN(sys_mq_notify),
|
|
SYSCALL_SIGN(sys_mq_notify),
|
|
SYSCALL_SIGN(sys_mq_getsetattr),
|
|
SYSCALL_SIGN(sys_mq_getsetattr),
|
|
SYSCALL_SIGN(sys_mq_close),
|
|
SYSCALL_SIGN(sys_mq_close),
|
|
- SYSCALL_SIGN(sys_stat), //TODO should be replaced by sys_lstat if symbolic link are implemented
|
|
|
|
|
|
+ SYSCALL_SIGN(sys_lstat),
|
|
SYSCALL_SIGN(sys_uname), /* 170 */
|
|
SYSCALL_SIGN(sys_uname), /* 170 */
|
|
SYSCALL_SIGN(sys_statfs),
|
|
SYSCALL_SIGN(sys_statfs),
|
|
SYSCALL_SIGN(sys_statfs64),
|
|
SYSCALL_SIGN(sys_statfs64),
|
|
@@ -5119,6 +5316,10 @@ const static struct rt_syscall_def func_table[] =
|
|
SYSCALL_SIGN(sys_openat), /* 175 */
|
|
SYSCALL_SIGN(sys_openat), /* 175 */
|
|
SYSCALL_SIGN(sys_mount),
|
|
SYSCALL_SIGN(sys_mount),
|
|
SYSCALL_SIGN(sys_umount2),
|
|
SYSCALL_SIGN(sys_umount2),
|
|
|
|
+ SYSCALL_SIGN(sys_link),
|
|
|
|
+ SYSCALL_SIGN(sys_symlink),
|
|
|
|
+ SYSCALL_SIGN(sys_getaffinity), /* 180 */
|
|
|
|
+ SYSCALL_SIGN(sys_sysinfo),
|
|
};
|
|
};
|
|
|
|
|
|
const void *lwp_get_sys_api(rt_uint32_t number)
|
|
const void *lwp_get_sys_api(rt_uint32_t number)
|