Message ID | 20200824192116.65562-3-Filip.Bozuta@syrmia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introducing functionality for a group of 4 time64 syscalls | expand |
Le 24/08/2020 à 21:21, Filip Bozuta a écrit : > This patch implements functionality for following time64 syscalls: > > *rt_sigtimedwait_time64() > > This is a year 2038 safe variant of syscall: > > int rt_sigtimedwait(const sigset_t *set, siginfo_t *info, > const struct timespec *timeout, size_t sigsetsize) > --synchronously wait for queued signals-- > man page: https://man7.org/linux/man-pages/man2/rt_sigtimedwait.2.html > > *sched_rr_get_interval_time64() > > This is a year 2038 safe variant of syscall: > > int sched_rr_get_interval(pid_t pid, struct timespec *tp) > --get the SCHED_RR interval for the named process-- > man page: https://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html > > Implementation notes: > > These syscalls were implemented in similar ways like > 'rt_sigtimedwait()' and 'sched_rr_get_interval()' except > that functions 'target_to_host_timespec64()' and > 'host_to_target_timespec64()' were used to convert values > of 'struct timespec' between host and target. > > Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> > Reviewed-by: Laurent Vivier <laurent@vivier.eu> > --- > linux-user/syscall.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index a359bd8620..0533a5a5bb 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -8831,6 +8831,48 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > } > } > return ret; > +#endif > +#ifdef TARGET_NR_rt_sigtimedwait_time64 > + case TARGET_NR_rt_sigtimedwait_time64: > + { > + sigset_t set; > + struct timespec uts, *puts; > + siginfo_t uinfo; > + > + if (arg4 != sizeof(target_sigset_t)) { > + return -TARGET_EINVAL; > + } > + > + p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); > + if (!p) { > + return -TARGET_EFAULT; > + } > + target_to_host_sigset(&set, p); > + unlock_user(p, arg1, 0); > + if (arg3) { > + puts = &uts; > + if (target_to_host_timespec64(puts, arg3)) { > + return -TARGET_EFAULT; > + } > + } else { > + puts = NULL; > + } > + ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts, > + SIGSET_T_SIZE)); > + if (!is_error(ret)) { > + if (arg2) { > + p = lock_user(VERIFY_WRITE, arg2, > + sizeof(target_siginfo_t), 0); > + if (!p) { > + return -TARGET_EFAULT; > + } > + host_to_target_siginfo(p, &uinfo); > + unlock_user(p, arg2, sizeof(target_siginfo_t)); > + } > + ret = host_to_target_signal(ret); > + } > + } > + return ret; > #endif > case TARGET_NR_rt_sigqueueinfo: > { > @@ -10351,6 +10393,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > } > return ret; > #endif > +#ifdef TARGET_NR_sched_rr_get_interval_time64 > + case TARGET_NR_sched_rr_get_interval_time64: > + { > + struct timespec ts; > + ret = get_errno(sched_rr_get_interval(arg1, &ts)); > + if (!is_error(ret)) { > + ret = host_to_target_timespec64(arg2, &ts); > + } > + } > + return ret; > +#endif > #if defined(TARGET_NR_nanosleep) > case TARGET_NR_nanosleep: > { > Applied to my linux-user-for-5.2 branch. Thanks, Laurent
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a359bd8620..0533a5a5bb 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8831,6 +8831,48 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } } return ret; +#endif +#ifdef TARGET_NR_rt_sigtimedwait_time64 + case TARGET_NR_rt_sigtimedwait_time64: + { + sigset_t set; + struct timespec uts, *puts; + siginfo_t uinfo; + + if (arg4 != sizeof(target_sigset_t)) { + return -TARGET_EINVAL; + } + + p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); + if (!p) { + return -TARGET_EFAULT; + } + target_to_host_sigset(&set, p); + unlock_user(p, arg1, 0); + if (arg3) { + puts = &uts; + if (target_to_host_timespec64(puts, arg3)) { + return -TARGET_EFAULT; + } + } else { + puts = NULL; + } + ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts, + SIGSET_T_SIZE)); + if (!is_error(ret)) { + if (arg2) { + p = lock_user(VERIFY_WRITE, arg2, + sizeof(target_siginfo_t), 0); + if (!p) { + return -TARGET_EFAULT; + } + host_to_target_siginfo(p, &uinfo); + unlock_user(p, arg2, sizeof(target_siginfo_t)); + } + ret = host_to_target_signal(ret); + } + } + return ret; #endif case TARGET_NR_rt_sigqueueinfo: { @@ -10351,6 +10393,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } return ret; #endif +#ifdef TARGET_NR_sched_rr_get_interval_time64 + case TARGET_NR_sched_rr_get_interval_time64: + { + struct timespec ts; + ret = get_errno(sched_rr_get_interval(arg1, &ts)); + if (!is_error(ret)) { + ret = host_to_target_timespec64(arg2, &ts); + } + } + return ret; +#endif #if defined(TARGET_NR_nanosleep) case TARGET_NR_nanosleep: {