Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe9c1db2 authored by Al Viro's avatar Al Viro
Browse files

generic compat_sys_rt_sigpending()



conditional on GENERIC_COMPAT_RT_SIGPENDING; by the end of that series
it will become the same thing as COMPAT and conditional will die out.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 322a56cb
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -362,6 +362,9 @@ config GENERIC_SIGALTSTACK
config GENERIC_COMPAT_RT_SIGPROCMASK
config GENERIC_COMPAT_RT_SIGPROCMASK
	bool
	bool


config GENERIC_COMPAT_RT_SIGPENDING
	bool

#
#
# ABI hall of shame
# ABI hall of shame
#
#
+4 −0
Original line number Original line Diff line number Diff line
@@ -598,6 +598,10 @@ asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
					  compat_sigset_t __user *oset,
					  compat_sigset_t __user *oset,
					  compat_size_t sigsetsize);
					  compat_size_t sigsetsize);
#endif
#endif
#ifdef CONFIG_GENERIC_COMPAT_RT_SIGPENDING
asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
					 compat_size_t sigsetsize);
#endif
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
				 unsigned long arg);
				 unsigned long arg);
+0 −1
Original line number Original line Diff line number Diff line
@@ -243,7 +243,6 @@ extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
				 siginfo_t *info);
				 siginfo_t *info);
extern long do_sigpending(void __user *, unsigned long);
extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
				const struct timespec *);
				const struct timespec *);
extern int sigprocmask(int, sigset_t *, sigset_t *);
extern int sigprocmask(int, sigset_t *, sigset_t *);
+35 −17
Original line number Original line Diff line number Diff line
@@ -2654,28 +2654,19 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
#endif
#endif
#endif
#endif


long do_sigpending(void __user *set, unsigned long sigsetsize)
static int do_sigpending(void *set, unsigned long sigsetsize)
{
{
	long error = -EINVAL;
	sigset_t pending;

	if (sigsetsize > sizeof(sigset_t))
	if (sigsetsize > sizeof(sigset_t))
		goto out;
		return -EINVAL;


	spin_lock_irq(&current->sighand->siglock);
	spin_lock_irq(&current->sighand->siglock);
	sigorsets(&pending, &current->pending.signal,
	sigorsets(set, &current->pending.signal,
		  &current->signal->shared_pending.signal);
		  &current->signal->shared_pending.signal);
	spin_unlock_irq(&current->sighand->siglock);
	spin_unlock_irq(&current->sighand->siglock);


	/* Outside the lock because only this thread touches it.  */
	/* Outside the lock because only this thread touches it.  */
	sigandsets(&pending, &current->blocked, &pending);
	sigandsets(set, &current->blocked, set);

	return 0;
	error = -EFAULT;
	if (!copy_to_user(set, &pending, sigsetsize))
		error = 0;

out:
	return error;
}
}


/**
/**
@@ -2684,10 +2675,37 @@ out:
 *  @set: stores pending signals
 *  @set: stores pending signals
 *  @sigsetsize: size of sigset_t type or larger
 *  @sigsetsize: size of sigset_t type or larger
 */
 */
SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize)
SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
{
	sigset_t set;
	int err = do_sigpending(&set, sigsetsize);
	if (!err && copy_to_user(uset, &set, sigsetsize))
		err = -EFAULT;
	return err;
}

#ifdef CONFIG_COMPAT
#ifdef CONFIG_GENERIC_COMPAT_RT_SIGPENDING
COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
		compat_size_t, sigsetsize)
{
{
	return do_sigpending(set, sigsetsize);
#ifdef __BIG_ENDIAN
	sigset_t set;
	int err = do_sigpending(&set, sigsetsize);
	if (!err) {
		compat_sigset_t set32;
		sigset_to_compat(&set32, &set);
		/* we can get here only if sigsetsize <= sizeof(set) */
		if (copy_to_user(uset, &set32, sigsetsize))
			err = -EFAULT;
	}
	}
	return err;
#else
	return sys_rt_sigpending((sigset_t __user *)uset, sigsetsize);
#endif
}
#endif
#endif


#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER
#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER


@@ -3216,7 +3234,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
 */
 */
SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
{
{
	return do_sigpending(set, sizeof(*set));
	return sys_rt_sigpending((sigset_t __user *)set, sizeof(old_sigset_t)); 
}
}


#endif
#endif