linux-user: Split out helpers for sigsuspend

Two new functions: process_sigsuspend_mask and finish_sigsuspend_mask.
Move the size check and copy-from-user code.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20220315084308.433109-3-richard.henderson@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
Richard Henderson 2022-03-15 01:43:05 -07:00 committed by Laurent Vivier
parent 7fb5ef350b
commit 0a99f09383
3 changed files with 66 additions and 23 deletions

View file

@ -9557,41 +9557,35 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_sigsuspend
case TARGET_NR_sigsuspend:
{
TaskState *ts = cpu->opaque;
sigset_t *set;
#if defined(TARGET_ALPHA)
TaskState *ts = cpu->opaque;
/* target_to_host_old_sigset will bswap back */
abi_ulong mask = tswapal(arg1);
target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
set = &ts->sigsuspend_mask;
target_to_host_old_sigset(set, &mask);
#else
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
return -TARGET_EFAULT;
target_to_host_old_sigset(&ts->sigsuspend_mask, p);
unlock_user(p, arg1, 0);
#endif
ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
SIGSET_T_SIZE));
if (ret != -QEMU_ERESTARTSYS) {
ts->in_sigsuspend = 1;
ret = process_sigsuspend_mask(&set, arg1, sizeof(target_sigset_t));
if (ret != 0) {
return ret;
}
#endif
ret = get_errno(safe_rt_sigsuspend(set, SIGSET_T_SIZE));
finish_sigsuspend_mask(ret);
}
return ret;
#endif
case TARGET_NR_rt_sigsuspend:
{
TaskState *ts = cpu->opaque;
sigset_t *set;
if (arg2 != sizeof(target_sigset_t)) {
return -TARGET_EINVAL;
}
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
return -TARGET_EFAULT;
target_to_host_sigset(&ts->sigsuspend_mask, p);
unlock_user(p, arg1, 0);
ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
SIGSET_T_SIZE));
if (ret != -QEMU_ERESTARTSYS) {
ts->in_sigsuspend = 1;
ret = process_sigsuspend_mask(&set, arg1, arg2);
if (ret != 0) {
return ret;
}
ret = get_errno(safe_rt_sigsuspend(set, SIGSET_T_SIZE));
finish_sigsuspend_mask(ret);
}
return ret;
#ifdef TARGET_NR_rt_sigtimedwait