diff --git a/kernel/components/lwp/lwp_syscall.c b/kernel/components/lwp/lwp_syscall.c index a8705c6cd38f8e74fef5650114c62bc258c733f9..b7cca79561662e9e754b9b7576df10319e57a8b9 100644 --- a/kernel/components/lwp/lwp_syscall.c +++ b/kernel/components/lwp/lwp_syscall.c @@ -57,6 +57,8 @@ #include #include "lwp_ipc_internal.h" +#include + #define SET_ERRNO(no) rt_set_errno(-(no)) #define GET_ERRNO() ((rt_get_errno() > 0) ? (-rt_get_errno()) : rt_get_errno()) struct musl_sockaddr @@ -3897,6 +3899,60 @@ int sys_setrlimit(unsigned int resource, struct rlimit *rlim) return -ENOSYS; } +int sys_getrandom(void *buf, size_t buflen, unsigned int flags) +{ + int ret = -1; + int count = 0; + void *kmem = RT_NULL; + rt_device_t rd_dev = RT_NULL; + + if (flags & GRND_RANDOM) + rd_dev = rt_device_find("random"); + else + rd_dev = rt_device_find("urandom"); + + if (rd_dev == RT_NULL) + { + return -EFAULT; + } + + if (rt_device_open(rd_dev, RT_DEVICE_OFLAG_RDONLY) != RT_EOK) + { + return -EFAULT; + } + + if (!lwp_user_accessable(buf, buflen)) + { + rt_device_close(rd_dev); + return -EFAULT; + } + + kmem = kmem_get(buflen); + if (!kmem) + { + rt_device_close(rd_dev); + return -ENOMEM; + } + + while (count < buflen) + { + ret = rt_device_read(rd_dev, count, kmem + count, buflen - count); + if (ret <= 0) + break; + count += ret; + } + rt_device_close(rd_dev); + + ret = count; + if (count > 0) + { + ret = lwp_put_to_user(buf, kmem, count); + } + kmem_put(kmem); + + return ret; +} + const static void* func_table[] = { (void *)sys_exit, /* 01 */ @@ -4080,6 +4136,7 @@ const static void* func_table[] = (void *)sys_prlimit64, /* 140 */ (void *)sys_getrlimit, (void *)sys_setrlimit, + (void *)sys_getrandom, }; const void *lwp_get_sys_api(rt_uint32_t number)