linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()'
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> Message-Id: <20200824192116.65562-3-Filip.Bozuta@syrmia.com> [lv: add missing defined(TARGET_NR_rt_sigtimedwait_time64)] Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
parent
6ac03b2cac
commit
ddcbde157d
@ -764,7 +764,7 @@ safe_syscall6(ssize_t, recvfrom, int, fd, void *, buf, size_t, len,
|
||||
safe_syscall3(ssize_t, sendmsg, int, fd, const struct msghdr *, msg, int, flags)
|
||||
safe_syscall3(ssize_t, recvmsg, int, fd, struct msghdr *, msg, int, flags)
|
||||
safe_syscall2(int, flock, int, fd, int, operation)
|
||||
#ifdef TARGET_NR_rt_sigtimedwait
|
||||
#if defined(TARGET_NR_rt_sigtimedwait) || defined(TARGET_NR_rt_sigtimedwait_time64)
|
||||
safe_syscall4(int, rt_sigtimedwait, const sigset_t *, these, siginfo_t *, uinfo,
|
||||
const struct timespec *, uts, size_t, sigsetsize)
|
||||
#endif
|
||||
@ -1243,7 +1243,8 @@ static inline abi_long target_to_host_timespec(struct timespec *host_ts,
|
||||
defined(TARGET_NR_mq_timedsend_time64) || \
|
||||
defined(TARGET_NR_mq_timedreceive_time64) || \
|
||||
(defined(TARGET_NR_timerfd_settime64) && defined(CONFIG_TIMERFD)) || \
|
||||
defined(TARGET_NR_clock_nanosleep_time64)
|
||||
defined(TARGET_NR_clock_nanosleep_time64) || \
|
||||
defined(TARGET_NR_rt_sigtimedwait_time64)
|
||||
static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
|
||||
abi_ulong target_addr)
|
||||
{
|
||||
@ -9044,6 +9045,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:
|
||||
{
|
||||
@ -10568,6 +10611,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:
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user