예제 #1
0
int
abi_sigprocmask(int how, u_long *abinset, u_long *abioset)
{
	sigset_t		new_set, *nset = NULL;
	sigset_t		old_set, *oset = NULL;
	u_long			new_set_abi, old_set_abi;
	mm_segment_t		fs;
	int			error;

	if (abinset) {
		get_user(new_set_abi, abinset);
		new_set = map_sigvec_to_kernel(new_set_abi,
			current_thread_info()->exec_domain->signal_map);
		nset = &new_set;
	}

	if (abioset)
		oset = &old_set;

	fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigprocmask,howcnv[how], nset, oset, sizeof(sigset_t));
	set_fs(fs);

	if (!error && abioset) {
		old_set_abi = map_sigvec_from_kernel(old_set,
			current_thread_info()->exec_domain->signal_invmap);
		put_user(old_set_abi, abioset);
	}

	return (error);
}
예제 #2
0
파일: signal.c 프로젝트: cpc26/abi_linux
asmlinkage int
abi_sigprocmask(int how, unsigned long *abinset, unsigned long *abioset)
{
	sigset_t new_set, *nset, old_set, *oset;
	unsigned long new_set_abi, old_set_abi;
	mm_segment_t old_fs;
	int error;

	nset = oset = NULL;

	if (abinset) {
		get_user(new_set_abi, abinset);
		new_set = map_sigvec_to_kernel(new_set_abi,
			current->exec_domain->signal_map);
		nset = &new_set;
	}
	if (abioset)
		oset = &old_set;

	old_fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigprocmask)(howcnv[how], nset, oset, sizeof(sigset_t));
	set_fs(old_fs);

	if (!error && abioset) {
		old_set_abi = map_sigvec_from_kernel(old_set,
			current->exec_domain->signal_invmap);
		put_user(old_set_abi, abioset);
	}

	return error;
}
예제 #3
0
/*
 * This function is used to handle the sigaction call from SVr4 binaries.
 *
 * If anyone else uses this, this function needs to be modified since the
 * order and size of the ibcs_sigaction structure is different in ibcs
 * and the SVr4 ABI
 */
int
abi_sigaction(int abi_signum, const struct abi_sigaction *action,
		struct abi_sigaction *oldaction)
{
	struct abi_sigaction	new_sa, old_sa;
	struct sigaction	nsa, osa;
	mm_segment_t		fs;
	int			error, signo;

	signo = abi_mapsig(abi_signum);
	if (signo == -1)
		return -EINVAL;

	if (oldaction) {
		if (!access_ok(VERIFY_WRITE, oldaction,
				sizeof(struct abi_sigaction)))
			return (-EFAULT);
	}

	if (action) {
		error = copy_from_user(&new_sa, action,
				sizeof(struct abi_sigaction));
		if (error)
			return (-EFAULT);
		nsa.sa_handler = new_sa.sa_handler;
		nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask,
			current_thread_info()->exec_domain->signal_map);
		nsa.sa_flags = SA_SIGINFO;
		if (new_sa.sa_flags & ABI_SA_ONSTACK)
			nsa.sa_flags |= SA_ONSTACK;
		if (new_sa.sa_flags & ABI_SA_RESTART)
			nsa.sa_flags |= SA_RESTART;
		if (new_sa.sa_flags & ABI_SA_NODEFER)
			nsa.sa_flags |= SA_NODEFER;
		if (new_sa.sa_flags & ABI_SA_RESETHAND)
			nsa.sa_flags |= SA_RESETHAND;
		if (new_sa.sa_flags & ABI_SA_NOCLDSTOP)
			nsa.sa_flags |= SA_NOCLDSTOP;
		if (new_sa.sa_flags & ABI_SA_NOCLDWAIT)
			nsa.sa_flags |= SA_NOCLDWAIT;
		nsa.sa_restorer = (void *)abi_sigret(__NR_rt_sigaction);
		if (nsa.sa_restorer) nsa.sa_flags |= SA_RESTORER;
	}

	fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigaction,signo, action ? &nsa : NULL,
			oldaction ? &osa : NULL, sizeof(sigset_t));
	set_fs(fs);

	if (error || !oldaction)
		return (error);

	old_sa.sa_handler = osa.sa_handler;
	old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask,
			current_thread_info()->exec_domain->signal_invmap);
	old_sa.sa_flags = 0;
	if (osa.sa_flags & SA_ONSTACK)
		old_sa.sa_flags |= ABI_SA_ONSTACK;
	if (osa.sa_flags & SA_RESTART)
		old_sa.sa_flags |= ABI_SA_RESTART;
	if (osa.sa_flags & SA_NODEFER)
		old_sa.sa_flags |= ABI_SA_NODEFER;
	if (osa.sa_flags & SA_RESETHAND)
		old_sa.sa_flags |= ABI_SA_RESETHAND;
	if (osa.sa_flags & SA_NOCLDSTOP)
		old_sa.sa_flags |= ABI_SA_NOCLDSTOP;
	if (osa.sa_flags & SA_NOCLDWAIT)
		old_sa.sa_flags |= ABI_SA_NOCLDWAIT;
	/*
	 * We already did the verify_area at the beginning.
	 */
	if (__copy_to_user(oldaction, &old_sa, sizeof(struct abi_sigaction)))
		return -EFAULT;
	return 0;
}
예제 #4
0
파일: signal.c 프로젝트: cpc26/abi_linux
asmlinkage int abi_sigaction(int abi_signum, const struct abi_sigaction * action,
	struct abi_sigaction * oldaction)
{
	struct abi_sigaction new_sa, old_sa;
	int error, signo;
	mm_segment_t old_fs;
	struct sigaction nsa, osa;

	signo = abi_mapsig(abi_signum);
	if (signo == -1)
		return -EINVAL;

	if (oldaction) {
		error = verify_area(VERIFY_WRITE, oldaction,
				sizeof(struct abi_sigaction));
		if (error)
			return error;
	}

	if (action) {
		error = copy_from_user(&new_sa, action,
				sizeof(struct abi_sigaction));
		if (error)
			return -EFAULT;
		nsa.sa_restorer = NULL;
		nsa.sa_handler = new_sa.sa_handler;
		nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask,
			current->exec_domain->signal_map);
		if(new_sa.sa_flags & ABI_SA_ONSTACK)
			nsa.sa_flags |= SA_ONSTACK;
		if(new_sa.sa_flags & ABI_SA_RESTART)
			nsa.sa_flags |= SA_RESTART;
		if(new_sa.sa_flags & ABI_SA_NODEFER)
			nsa.sa_flags |= SA_NODEFER;
		if(new_sa.sa_flags & ABI_SA_RESETHAND)
			nsa.sa_flags |= SA_RESETHAND;
		if(new_sa.sa_flags & ABI_SA_NOCLDSTOP)
			nsa.sa_flags |= SA_NOCLDSTOP;
		if(new_sa.sa_flags & ABI_SA_NOCLDWAIT)
			nsa.sa_flags |= SA_NOCLDWAIT;
	}

	old_fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigaction)(signo,
				action ? &nsa : NULL,
				oldaction ? &osa : NULL,
				sizeof(sigset_t));
	set_fs(old_fs);

	if (!error && oldaction) {
		old_sa.sa_handler = osa.sa_handler;
		old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask,
			current->exec_domain->signal_invmap);
		old_sa.sa_flags = 0;
		if(osa.sa_flags & SA_ONSTACK)
			old_sa.sa_flags |= ABI_SA_ONSTACK;
		if(osa.sa_flags & SA_RESTART)
			old_sa.sa_flags |= ABI_SA_RESTART;
		if(osa.sa_flags & SA_NODEFER)
			old_sa.sa_flags |= ABI_SA_NODEFER;
		if(osa.sa_flags & SA_RESETHAND)
			old_sa.sa_flags |= ABI_SA_RESETHAND;
		if(osa.sa_flags & SA_NOCLDSTOP)
			old_sa.sa_flags |= ABI_SA_NOCLDSTOP;
		if(osa.sa_flags & SA_NOCLDWAIT)
			old_sa.sa_flags |= ABI_SA_NOCLDWAIT;
		/* This should never fail... */
		copy_to_user(oldaction, &old_sa, sizeof(struct abi_sigaction));
	}
	return error;
}