Exemplo n.º 1
0
/*
 * Process the signal() function from iBCS
 *
 * This version appeared in "Advanced Programming in the Unix Environment"
 * by W. Richard Stevens, page 298.
 */
void
abi_sig_handler(struct pt_regs *regp, int sig,
		__sighandler_t handler, int oneshot)
{
	struct sigaction	act, oact;
	mm_segment_t		fs;
	int			error;

	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO;
	act.sa_restorer = (void *)abi_sigret(__NR_rt_sigaction);
	if (act.sa_restorer) act.sa_flags |= SA_RESTORER;
	act.sa_handler = handler;

	if (oneshot)
		act.sa_flags |= SA_ONESHOT | SA_NOMASK;

	fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigaction,sig, &act, &oact, sizeof(sigset_t));
	set_fs(fs);

	if (error < 0) {
		set_error(regp, iABI_errors(-error));
	} else {
		set_result(regp, (int)((long)oact.sa_handler));
	}
}
Exemplo n.º 2
0
void abi_sigpause (struct pt_regs * regs)
{
	old_sigset_t   newset;
	int	sig, answer;

#ifdef __sparc__
	printk(KERN_ERR "Sparc/iBCS: sigpause not yet implemented\n");
#else
	if (!abi_signo(regs, &sig))
		return;

	newset = ~0UL;
	newset &= (1UL << (sig-1));
	answer = SYS(sigsuspend)(0, current->blocked,
			newset, regs->esi, regs->edi,
			regs->ebp, regs->eax,
			regs->xds, regs->xes,
			regs->orig_eax,
			regs->eip, regs->xcs, regs->eflags,
			regs->esp, regs->xss);

	if (answer < 0) {
		set_error(regs, iABI_errors(-answer));
	}
#endif
}
Exemplo n.º 3
0
/*
 * Process the iBCS sigignore
 *
 * This is basically a signal (...,SIG_IGN) call.
 */
void
abi_sigignore(struct pt_regs *regp)
{
	struct sigaction	act, oact;
	int			error, sig;
	mm_segment_t		fs;

	if (!abi_signo(regp, &sig))
		return;

	sigemptyset(&act.sa_mask);

	act.sa_handler = SIG_IGN;
	act.sa_flags   = SA_SIGINFO;
	act.sa_restorer = (void *)abi_sigret(__NR_rt_sigaction);
	if (act.sa_restorer) act.sa_flags |= SA_RESTORER;

	fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigaction,sig, &act, &oact, sizeof(sigset_t));
	set_fs(fs);

	if (error < 0)
		set_error(regp, iABI_errors(-error));
}
Exemplo n.º 4
0
/*
 *      Process the iBCS sigset function.
 *
 *      This is basically the same as the signal() routine with the exception
 *      that it will accept a SIG_HOLD parameter.
 *
 *      A SIG_HOLD will defer the processing of the signal until a sigrelse()
 *      function is called.
 */
int abi_sigset (struct pt_regs * regs)
{
	sigset_t	 newmask, oldmask;
	__sighandler_t   vec;
	int	      sig, answer;
	mm_segment_t old_fs;

	if (abi_signo (regs, &sig)) {
		vec = (__sighandler_t) SECOND_PARAM;
		if (vec != SIG_HOLD) {
			deactivate_signal(current, sig);
			abi_sig_handler (regs, sig, vec, 0);
		} else {
/*
 *      Process the hold function
 */
			sigemptyset (&newmask);
			sigaddset  (&newmask, sig);

			TO_KERNEL (old_fs);
			answer = SYS(rt_sigprocmask) (SIG_BLOCK,
						&newmask, &oldmask,
						sizeof(sigset_t));
			FROM_KERNEL (old_fs);

			if (answer < 0) {
				set_error (regs, iABI_errors (-answer));
			}
		}
	}
	return 0;
}
Exemplo n.º 5
0
void abi_sig_handler (struct pt_regs * regs, int sig,
			__sighandler_t handler, int oneshot)
{
	struct sigaction act, oact;
	int	      answer;
	mm_segment_t old_fs;

	sigemptyset (&act.sa_mask);
	act.sa_restorer = NULL;
	act.sa_handler = handler;
	act.sa_flags   = 0;

	if (oneshot)
		act.sa_flags = SA_ONESHOT | SA_NOMASK;
	else
		act.sa_flags = 0;

	TO_KERNEL (old_fs);
	answer = SYS(rt_sigaction) (sig, &act, &oact, sizeof(sigset_t));
	FROM_KERNEL (old_fs);

	if (answer < 0) {
		set_error (regs, iABI_errors (-answer));
	} else
		set_result (regs, (int) oact.sa_handler);
}
Exemplo n.º 6
0
static void
timod_error(int fd, int prim, int terr, int uerr)
{
	struct file		*fp;
	struct T_primsg		*it;
	struct T_error_ack	*err;

#if defined(CONFIG_ABI_TRACE)
	abi_trace(ABI_TRACE_STREAMS, "TI: %u error prim=%d, TLI=%d, UNIX=%d\n",
			fd, prim, terr, uerr);
#endif

	fp = fcheck(fd);
	it = timod_mkctl(sizeof(struct T_error_ack));
	if (!it)
		return;

	err = (struct T_error_ack *)&it->type;
	err->PRIM_type = T_ERROR_ACK;
	err->ERROR_prim = prim;
	err->TLI_error = terr;
	err->UNIX_error = iABI_errors(uerr);

	it->pri = MSG_HIPRI;
	it->length = sizeof(struct T_error_ack);
	it->next = Priv(fp)->pfirst;

	Priv(fp)->pfirst = it;
	if (!Priv(fp)->plast)
		Priv(fp)->plast = it;
	timod_socket_wakeup(fp);
}
Exemplo n.º 7
0
void cxenix(struct pt_regs *regs)
{
	int sysno = regs->eax >> 8;

	if (sysno >= ARRAY_SIZE(cxenix_table))
		set_error(regs, iABI_errors(-EINVAL));
	else
		lcall7_dispatch(regs, &cxenix_table[sysno], 1);
}
Exemplo n.º 8
0
static asmlinkage void
isc_lcall7(int segment, struct pt_regs *regs)
{
	int sysno = _AX(regs) & 0xff;

	if (sysno >= ARRAY_SIZE(isc_syscall_table))
		set_error(regs, iABI_errors(-EINVAL));
	else
		lcall7_dispatch(regs, &isc_syscall_table[sysno], 1);
}
Exemplo n.º 9
0
static void
uw7_lcall7(int segment, struct pt_regs *regs)
{
	int sysno = regs->eax & 0xff;

	if (sysno >= ARRAY_SIZE(uw7_syscall_table))
		set_error(regs, iABI_errors(-EINVAL));
	else
		lcall7_dispatch(regs, &uw7_syscall_table[sysno], 1);
}
Exemplo n.º 10
0
inline int abi_signo (struct pt_regs *regs, int *sig)
{
	int    value = abi_mapsig(SIGNAL_NUMBER & 0xFF);

	if (value == -1) {
		set_error (regs, iABI_errors (EINVAL));
		return 0;
	}

	*sig = value;
	return 1;
}
Exemplo n.º 11
0
static void
isc_sysisc(struct pt_regs *regs)
{
	int sysno;

	__get_user(sysno, ((unsigned long *)_SP(regs))+1);

	if (sysno >= ARRAY_SIZE(sysisc_table))
		set_error(regs, iABI_errors(-EINVAL));
	else
		lcall7_dispatch(regs, &sysisc_table[sysno], 2);
}
Exemplo n.º 12
0
/*
 * Either we want this static or in a header...
 */
__inline int
abi_signo(struct pt_regs *regp, int *sigp)
{
	int			value;

	value = abi_mapsig(SIGNAL_NUMBER(regp) & 0xFF);
	if (value == -1) {
		set_error(regp, iABI_errors(EINVAL));
		return 0;
	} else {
		*sigp = value;
		return 1;
	}
}
Exemplo n.º 13
0
/*
 * Process the iBCS sigpause
 *
 * Wait for the signal indicated to arrive before resuming the
 * processing. I do not know if the signal is processed first using
 * the normal event processing before the return. If someone can
 * shed some light on this then please correct this code. I block
 * the signal and look for it to show up in the pending list.
 */
void
abi_sigpause(struct pt_regs *regs)
{
	old_sigset_t		newset;
	int			error, sig;

	if (!abi_signo(regs, &sig))
		return;
	newset = (~0UL) & (1UL << (sig-1));
#ifdef CONFIG_65BIT
	error = 0;
#else
	error = SYS(sigsuspend,0, current->blocked.sig[0], newset);
#endif
	if (error < 0) set_error(regs, iABI_errors(-error));
}
Exemplo n.º 14
0
/*
 *      Process the iBCS sigrelse.
 *
 *      Re-enable the signal processing from a previously suspended
 *      signal. This may have been done by calling the sighold() function
 *      or a longjmp() during the signal processing routine. If you do a
 *      longjmp() function then it is expected that you will call sigrelse
 *      before going on with the program.
 */
void abi_sigrelse (struct pt_regs * regs)
{
	sigset_t   newmask, oldmask;
	int	sig, answer;
	mm_segment_t old_fs;

	if (!abi_signo (regs, &sig))
		return;

	sigemptyset (&newmask);
	sigaddset   (&newmask, sig);

	TO_KERNEL (old_fs);
	answer = SYS(rt_sigprocmask) (SIG_UNBLOCK, &newmask, &oldmask,
				sizeof(sigset_t));
	FROM_KERNEL (old_fs);

	if (answer < 0) {
		set_error (regs, iABI_errors (-answer));
	}
}
Exemplo n.º 15
0
/*
 * Process the iBCS sigrelse.
 *
 * Re-enable the signal processing from a previously suspended
 * signal. This may have been done by calling the sighold() function
 * or a longjmp() during the signal processing routine. If you do a
 * longjmp() function then it is expected that you will call sigrelse
 * or set the handler again using sigset before going on with the program.
 */
void
abi_sigrelse(struct pt_regs *regp)
{
	sigset_t	newmask, oldmask;
	int		error, sig;
	mm_segment_t	fs;

	if (!abi_signo(regp, &sig))
		return;

	sigemptyset(&newmask);
	sigaddset(&newmask, sig);

	fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigprocmask,SIG_UNBLOCK, &newmask,
			&oldmask, sizeof(sigset_t));
	set_fs(fs);

	if (error < 0)
		set_error(regp, iABI_errors(-error));
}
Exemplo n.º 16
0
/*
 * Process the SVR4 sigset function.
 *
 * This is basically the same as the signal() routine with the
 * exception that it will accept a SIG_HOLD parameter.
 *
 * A SIG_HOLD will defer the processing of the signal until a sigrelse()
 * function is called or the signal handler is set again using this function.
 */
int
abi_sigset(struct pt_regs *regp)
{
	int		sig, error;
	sigset_t	newmask, oldmask;
	__sighandler_t	vec;
	mm_segment_t	fs;
	int		action;


	if (abi_signo(regp, &sig) == 0)
		return 0;

	vec = (__sighandler_t)SECOND_PARAM(regp);
	action = SIG_BLOCK;

	if (vec != SIG_HOLD) {
		action = SIG_UNBLOCK;
		deactivate_signal(current, sig);
		abi_sig_handler(regp, sig, vec, 0);
	}

	/*
	 * Process the signal hold/unhold function.
	 */
	sigemptyset(&newmask);
	sigaddset(&newmask, sig);

	fs = get_fs();
	set_fs(get_ds());
	error = SYS(rt_sigprocmask,action, &newmask, &oldmask,
		sizeof(sigset_t));
	set_fs(fs);

	if (error < 0)
		set_error(regp, iABI_errors(-error));

	return 0;
}
Exemplo n.º 17
0
void abi_sigignore (struct pt_regs * regs)
{
	struct sigaction act, oact;
	int	      sig, answer;
	mm_segment_t old_fs;

	if (!abi_signo (regs, &sig))
		return;

	sigemptyset (&act.sa_mask);

	act.sa_restorer = NULL;
	act.sa_handler = SIG_IGN;
	act.sa_flags   = 0;

	TO_KERNEL (old_fs);
	answer = SYS(rt_sigaction) (sig, &act, &oact, sizeof(sigset_t));
	FROM_KERNEL (old_fs);

	if (answer < 0) {
		set_error (regs, iABI_errors (-answer));
	}
}
Exemplo n.º 18
0
int
svr4_shmsys(struct pt_regs *regp)
{
	int			arg1, arg2, arg3, cmd, err = 0;
	u_long			raddr;
	mm_segment_t		fs;

	cmd = get_syscall_parameter(regp, 0);
	if (cmd == SVR4_shmdt) {
		err = svr4_shmdt(regp);
		goto out;
	}

	arg1 = get_syscall_parameter(regp, 1);
	arg2 = get_syscall_parameter(regp, 2);
	arg3 = get_syscall_parameter(regp, 3);

	switch (cmd) {
	case SVR4_shmat:
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmat(%d, %x, %o)\n", arg1, arg2, arg3);
#endif

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmat, arg1, arg2, arg3, &raddr);
#else
		err = SYS(ipc,SHMAT+0x10000,arg1,arg3,&raddr,arg2);
#endif
		set_fs(fs);
		if (err >= 0)
			err = (int)raddr;

#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmat returns %x\n", err);
#endif
		break;
	case SVR4_shmget:
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmget(%d, %x, %o)\n", arg1, arg2, arg3);
#endif
#ifdef CONFIG_65BIT
		err = SYS(shmget, arg1, arg2, arg3);
#else
		err = SYS(ipc,SHMGET,arg1, arg2, arg3);
#endif
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "shmget returns %d\n", err);
#endif
		break;
	case SVR4_shmctl:
		err = svr4_shmctl(arg1, arg2, (char *)((long)arg3));
		break;
	default:
#if defined(CONFIG_ABI_TRACE)
		__abi_trace("shmsys: unsupported command: %x\n", cmd);
#endif
		err = -EINVAL;
	}

out:
	if (err < 0 && err > -255) {
	        set_error(regp, iABI_errors(-err));
#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_API, "Error %d\n", get_result(regp));
#endif
		return 0;
	}

	clear_error(regp);
	set_result(regp, err);
	return 0;
}
Exemplo n.º 19
0
int svr4_shmsys(struct pt_regs * regs)
{
	int command = get_syscall_parameter (regs, 0);
	int arg1, arg2, arg3;
	mm_segment_t old_fs;
	long retval = 0;
	char *addr = 0;

	arg1 = arg2 = arg3 = 0;
	switch (command) {
		case U_SHMAT:
		case U_SHMCTL:
		case U_SHMGET:
			arg1 = get_syscall_parameter (regs, 1);
			arg2 = get_syscall_parameter (regs, 2);
			arg3 = get_syscall_parameter (regs, 3);
			break;
		case U_SHMDT:
			addr = (char *) get_syscall_parameter (regs, 1);
			break;
		default:
			printk(KERN_ERR "%d iBCS: bad SHM command %d\n",
				current->pid, command);
			retval = -EINVAL;
			goto test_exit;
	}

	switch (command) {
		case U_SHMAT: {
#ifdef IPCCALL
			unsigned long raddr;
#endif
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmat: args: %d %x %o \n",
					current->pid,
					arg1, arg2, arg3);
#endif
			/*
			 * raddr = 0 tells sys_shmat to limit to 2G
			 *	and we are IBCS, no raddr value to return
			 */
#ifdef IPCCALL
			old_fs = get_fs();
			set_fs(get_ds());
			retval = SYS (ipc) (IPCCALL(1,SHMAT), arg1, arg3, &raddr, (char *) arg2);
			set_fs(old_fs);
			if (retval >= 0)
				retval = raddr;
#else
			retval = SYS (ipc) (SHMAT, arg1, arg3, 0, (char *) arg2);
#endif

#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmat: return val is %lx\n",
					current->pid, retval);
#endif
			goto test_exit;
		}

		case U_SHMGET:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmget: args: %d %x %o \n",
					current->pid,
					arg1, arg2, arg3);
#endif
			retval = SYS (ipc) (SHMGET, arg1, arg2, arg3, 0);
			goto test_exit;

		case U_SHMDT:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmdt: arg: %lx\n",
					current->pid, (unsigned long)addr);
#endif
			retval = SYS (ipc) (SHMDT, 0, 0, 0, addr);
			goto test_exit;

		case U_SHMCTL:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmctl: args: %d %x %o %d %x\n",
					current->pid,
					arg1, arg2, arg3, arg3, arg3);
#endif
			switch (arg2) {
				case U_SHMLOCK:
					retval = SYS (ipc) (SHMCTL, arg1, SHM_LOCK, 0, arg3);
					goto test_exit;

				case U_SHMUNLOCK:
					retval = SYS (ipc) (SHMCTL, arg1, SHM_UNLOCK, 0, arg3);
					goto test_exit;

				case U_IPC_SET: {
					struct ibcs_shmid_ds is;
					struct shmid_ds ls;

					retval = verify_area(VERIFY_WRITE, (char *)arg3, sizeof(is));
					if (retval)
						goto test_exit;

					copy_from_user(&is, (char *)arg3, sizeof(is));
					ishm_to_lshm(&is, &ls);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_SET, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm(&ls, &is);
					copy_to_user((char *)arg3, &is, sizeof(is));
					goto test_exit;
				}

				case U_IPC_SET_L: {
					struct ibcs_shmid_ds_l is;
					struct shmid_ds ls;

					retval = verify_area(VERIFY_WRITE, (char *)arg3, sizeof(is));
					if (retval)
						goto test_exit;

					copy_from_user(&is, (char *)arg3, sizeof(is));
					ishm_to_lshm_l(&is, &ls);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_SET, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm_l(&ls, &is);
					copy_to_user((char *)arg3, &is, sizeof(is));
					goto test_exit;
				}

				case U_IPC_RMID:
				case U_IPC_RMID_L:
					retval = SYS (ipc) (SHMCTL, arg1, IPC_RMID, arg3);
					goto test_exit;

				case U_IPC_STAT: {
					struct ibcs_shmid_ds is;
					struct shmid_ds ls;

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_STAT, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm(&ls, &is);
					retval = copy_to_user((char *)arg3, &is, sizeof(is)) ? -EFAULT : 0;
					goto test_exit;
				}

				case U_IPC_STAT_L: {
					struct ibcs_shmid_ds_l is;
					struct shmid_ds ls;

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_STAT, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm_l(&ls, &is);
					retval = copy_to_user((char *)arg3, &is, sizeof(is)) ? -EFAULT : 0;
					goto test_exit;
				}

				default:
					printk(KERN_ERR "%d iBCS: ibcs_shmctl: unsupported command %d\n",
						current->pid, arg2);
			}
			retval = -EINVAL;
			goto test_exit;

		default:
#ifdef CONFIG_ABI_TRACE
			printk(KERN_DEBUG "%d iBCS: ibcs_shm: command: %x\n",
				current->pid, command);
#endif
			retval = -EINVAL;
			goto test_exit;
	}

test_exit:;
	if ((retval < 0) && (retval > -255)) {
	        set_error (regs, iABI_errors (-retval));
#ifdef CONFIG_ABI_TRACE
		if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
			printk(KERN_DEBUG "%d iBCS: Error %ld\n",
				current->pid, get_result (regs));
#endif
	} else {
	    	clear_error (regs);
		set_result (regs, retval);
	}

	return 0;
}