コード例 #1
0
int
svr4_semsys(struct pt_regs *regp)
{
	int			which, arg1, arg2, arg3;
	union semun		*arg4;

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

	/*
	 * XXX - The value for arg4 depends on how union
	 * passing is implement on this architecture and
	 * compiler. The following is *only* known to be
	 * right for Intel (the default else case).
	 */
#ifdef __sparc__
	arg4 = (union semun *)get_syscall_parameter(regp, 4);
#else
	arg4 = (union semun *)(((u_long *)_SP(regp)) + (5));
#endif

	switch (which) {
	case SVR4_semctl:
		return svr4_semctl(arg1, arg2, arg3, arg4);
	case SVR4_semget:
		return svr4_semget(arg1, arg2, arg3);
	case SVR4_semop:
		return svr4_semop(arg1, (struct sembuf *)((long)arg2), arg3);
	}

	return -EINVAL;
}
コード例 #2
0
int
sco_ioctl(struct pt_regs *regs)
{
	u_int			num;
	int			fd;
	caddr_t			data;

	fd = (int)get_syscall_parameter(regs, 0);
	num = (u_int)get_syscall_parameter(regs, 1);
	data = (caddr_t)get_syscall_parameter(regs, 2);

	return do_ioctl(regs, fd, num, data);
}
コード例 #3
0
ファイル: syslocal.c プロジェクト: cpc26/abi_linux
int svr4_syslocal(struct pt_regs * regs)
{
	int	cmd;

	cmd = get_syscall_parameter (regs, 0);

	switch (cmd) {
#ifdef CONFIG_ABI_IBCS_WYSEMP
		case SL_QUERY:
			return 0;

		case SL_NENG:
			return 1;

		case SL_MACHTYPE:
			return (EISA_bus ? SL_MACH_EISA : SL_MACH_AT);
#endif
	}

#ifdef CONFIG_ABI_TRACE
	if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) {
		printk(KERN_DEBUG "iBCS2: unsupported syslocal call %d\n", cmd);
	}
#endif

	return -EINVAL;
}
コード例 #4
0
int
uw7_context(struct pt_regs * regs)
{
	int fcn = get_syscall_parameter(regs, 0);
	uw7_context_t * uc = (uw7_context_t *) get_syscall_parameter(regs, 1);

	switch (fcn) {
		case UW7_GETCONTEXT:
			return getcontext(uc, regs);

		case UW7_GETXCONTEXT:
			return getxcontext(uc, regs);

		case UW7_SETCONTEXT:
			return setcontext(uc, regs);
	}
	return -EINVAL;
}
コード例 #5
0
int
svr4_msgsys(struct pt_regs *regp)
{
	int			err, cmd, arg1, arg2, arg3, arg4, arg5;

	/*
	 * Special handling as msgrcv is ugly.
	 */
	cmd = get_syscall_parameter(regp, 0);
	arg1 = get_syscall_parameter(regp, 1);
	arg2 = get_syscall_parameter(regp, 2);

	switch (cmd) {
	case SVR4_msgget:
#ifdef CONFIG_65BIT
		err = SYS(msgget, arg1, arg2);
#else
		err = SYS(ipc,MSGGET,arg1,arg2);
#endif
		return err;
	case SVR4_msgctl:
		arg3 = get_syscall_parameter(regp, 3);
		return svr4_msgctl(arg1, arg2, (caddr_t)((long)arg3));
	case SVR4_msgrcv:
		arg3 = get_syscall_parameter(regp, 3);
		arg4 = get_syscall_parameter(regp, 4);
		arg5 = get_syscall_parameter(regp, 5);
#ifdef CONFIG_65BIT
		err = SYS(msgrcv, arg1, arg2, arg3, arg4, arg5);
#else
		err = SYS(ipc,MSGRCV+0x10000,arg1,arg3,arg5,arg2,arg4);
#endif
		return err;
	case SVR4_msgsnd:
		arg3 = get_syscall_parameter(regp, 3);
		arg4 = get_syscall_parameter(regp, 4);
#ifdef CONFIG_65BIT
		err = SYS(msgsnd, arg1, arg2, arg3, arg4);
#else
		err = SYS(ipc,MSGSND,arg1,arg3,arg4,arg2);
#endif
		return ((err > 0) ? 0 : err);
	}

#if defined(CONFIG_ABI_TRACE)
	__abi_trace("msgsys: unsupported command: %x\n", cmd);
#endif
	return -EINVAL;
}
コード例 #6
0
ファイル: signal.c プロジェクト: cpc26/abi_linux
int abi_sigsuspend(struct pt_regs * regs)
{
	unsigned long * set;
	unsigned long oldset;
	old_sigset_t newset;
	int error;

	if (personality(PER_BSD)) {
		oldset = get_syscall_parameter (regs, 0);
	} else
	{
		set = (unsigned long *)get_syscall_parameter (regs, 0);
		error = get_user(oldset, set);
		if (error)
			return error;
	}
	newset = map_bitvec(oldset,
		current->exec_domain->signal_map);

#ifdef CONFIG_ABI_TRACE
	if ((ibcs_trace & TRACE_SIGNAL) || ibcs_func_p->trace)
		printk("iBCS: sigsuspend oldset, newset = %lx %lx\n",
			oldset, newset);
#endif
	{
#if 0
	    extern do_sigpause(unsigned int, struct pt_regs *);
	    return do_sigpause(newset, regs);
#endif
	}
	return SYS(sigsuspend)(0, oldset,
			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);
}
コード例 #7
0
static int
svr4_shmdt(struct pt_regs *regp)
{
	caddr_t			addr = (caddr_t)get_syscall_parameter(regp, 1);
int retval;
#if defined(CONFIG_ABI_TRACE)
	abi_trace(ABI_TRACE_API, "shmdt(%p)\n", addr);
#endif
#ifdef CONFIG_65BIT
	retval=SYS(shmdt,addr);
#else
	retval=SYS(ipc,SHMDT,0,0,0,addr);
#endif
	return retval;
}
コード例 #8
0
int
svr4_putpmsg(struct pt_regs *regs)
{
	struct file		*fp;
	struct inode		*ip;
	int			fd;
	int			error = -EBADF;

	fd = (int)get_syscall_parameter(regs, 0);
	fp = fget(fd);
	if (fp) {
		ip = fp->f_dentry->d_inode;
		if (S_ISSOCK(ip->i_mode) || IS_SPX(ip))
			error = timod_putmsg(fd, ip, 1, regs);
		fput(fp);
	}
	return error;
}
コード例 #9
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;
}
コード例 #10
0
ファイル: ipc.c プロジェクト: cpc26/abi_linux
int svr4_msgsys(struct pt_regs * regs)
{
	int command = get_syscall_parameter (regs, 0);
	int arg1, arg2, arg4, arg5;
	mm_segment_t old_fs;
	char *arg3;
	int retval;

	arg1 = get_syscall_parameter (regs, 1);
	arg2 = get_syscall_parameter (regs, 2);
	arg3 = (char *) get_syscall_parameter (regs, 3);

	switch (command) {
		/* hard one first */
		case U_MSGCTL:
			switch (arg2) {
				case U_IPC_SET: {
					struct ibcs_msqid_ds im;
					struct msqid_ds lm;

					retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
					if (retval)
						return retval;

					copy_from_user(&im, (char *) arg3, sizeof(im));
					imsq_to_lmsq(&im, &lm);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (MSGCTL, arg1, IPC_SET, 0, &lm);
					set_fs (old_fs);

					lmsq_to_imsq(&lm, &im);
					copy_to_user((char *)arg3, &im, sizeof(im));
					return retval;
				}

				case U_IPC_SET_L: {
					struct ibcs_msqid_ds_l im;
					struct msqid_ds lm;

					retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
					if (retval)
						return retval;

					copy_from_user(&im, (char *) arg3, sizeof(im));
					imsq_to_lmsq_l(&im, &lm);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (MSGCTL, arg1, IPC_SET, 0, &lm);
					set_fs (old_fs);

					lmsq_to_imsq_l(&lm, &im);
					copy_to_user((char *)arg3, &im, sizeof(im));
					return retval;
				}

			case U_IPC_RMID:
			case U_IPC_RMID_L:
				return SYS (ipc) (MSGCTL, arg1, IPC_RMID, 0, arg3);

			case U_IPC_STAT: {
				struct ibcs_msqid_ds im;
				struct msqid_ds lm;

				retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
				if (retval)
					return retval;

				old_fs = get_fs();
				set_fs (get_ds());
				retval = SYS (ipc) (MSGCTL, arg1, IPC_STAT, 0, &lm);
				set_fs (old_fs);

				if (retval < 0)
					return retval;

				lmsq_to_imsq(&lm, &im);
				copy_to_user((char *)arg3, &im, sizeof(im));
				return retval;
			}

			case U_IPC_STAT_L: {
				struct ibcs_msqid_ds_l im;
				struct msqid_ds lm;

				retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
				if (retval)
					return retval;

				old_fs = get_fs();
				set_fs (get_ds());
				retval = SYS (ipc) (MSGCTL, arg1, IPC_STAT, 0, &lm);
				set_fs (old_fs);

				if (retval < 0)
					return retval;

				lmsq_to_imsq_l(&lm, &im);
				copy_to_user((char *)arg3, &im, sizeof(im));
				return retval;
			}

			default:
				printk(KERN_ERR "%d ibcs_msgctl: unsupported command %d\n",
					current->pid, arg2);
		}

		case U_MSGGET:
			return SYS (ipc) (MSGGET, arg1, arg2, 0, 0);

		case U_MSGSND:
			arg4 = get_syscall_parameter (regs, 4);
			retval = SYS (ipc) (MSGSND, arg1, arg3, arg4, (char *) arg2);
			return ((retval > 0) ? 0 : retval);

		case U_MSGRCV: {
#ifdef IPCCALL
			arg4 = get_syscall_parameter (regs, 4);
			arg5 = get_syscall_parameter (regs, 5);
			return SYS(ipc)(IPCCALL(1,MSGRCV), arg1, arg3, arg5, arg2, arg4);
#else
#ifdef __sparc__
		        printk(KERN_ERR
				"%d Sparc/IBCS: Kludgy U_MSGRCV not implemented\n",
				current->pid);
			return -EINVAL;
#else /* __sparc__ */
			struct ipc_kludge *scratch;
			long old_esp = regs->esp;

			scratch = (struct ipc_kludge *)((regs->esp-1024-sizeof(struct ipc_kludge)) & 0xfffffffc);
			regs->esp = (long)scratch;
			get_user(arg4, ((unsigned long *) regs->esp) + 5);
			get_user(arg5, ((unsigned long *) regs->esp) + 6);
			put_user((long)arg2, &scratch->msgp);
			put_user((long)arg4, &scratch->msgtyp);
			retval = SYS (ipc) (MSGRCV, arg1, arg3, arg5, scratch);
			regs->esp = old_esp;
			return retval;
#endif /* sparc */
#endif /* IPCCALL */
		}

		default:
			printk(KERN_ERR "%d ibcs_msgctl: unsupported command %d\n",
				current->pid, command);
	}
	return -EINVAL;
}
コード例 #11
0
ファイル: ipc.c プロジェクト: cpc26/abi_linux
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;
}
コード例 #12
0
ファイル: ipc.c プロジェクト: cpc26/abi_linux
int svr4_semsys(struct pt_regs *regs)
{
	int command = get_syscall_parameter (regs, 0);
	int arg1, arg2, arg3;
	union semun *arg4;
	struct semid_ds ls;
	union semun lsemun;
	mm_segment_t old_fs;
	int retval;

	arg1 = get_syscall_parameter (regs, 1);
	arg2 = get_syscall_parameter (regs, 2);
	arg3 = get_syscall_parameter (regs, 3);
	switch (command) {
		case U_SEMCTL:
			/* XXX - The value for arg4 depends on how union
			 * passing is implement on this architecture and
			 * compiler. The following is *only* known to be
			 * right for Intel (the default else case).
			 */
#ifdef __sparc__
			arg4 = (union semun *)get_syscall_parameter (regs, 4);
#else
			arg4 = (union semun *)(((unsigned long *) regs->esp) + (5));
#endif
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
			printk(KERN_DEBUG "%d iBCS: ibcs_semctl: args: %d %d %d %lx\n",
					current->pid,
					 arg1, arg2, arg3, (unsigned long)arg4);
#endif
			switch (arg3) {
				case U_IPC_SET: {
					struct ibcs_semid_ds is, *is_p;

					retval = get_user(is_p, (struct ibcs_semid_ds **)&arg4->buf);
					if (!retval)
						retval = verify_area(VERIFY_WRITE, is_p, sizeof(is));
					if (retval)
						return retval;

					copy_from_user(&is, (char *)is_p, sizeof(is));
					isem_to_lsem(&is, &ls);

					lsemun.buf = &ls;
					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SEMCTL, arg1, arg2, IPC_SET, &lsemun);
					set_fs(old_fs);

					lsem_to_isem(&ls, &is);
					copy_to_user((char *)is_p, &is, sizeof(is));
					return retval;
				}

				case U_IPC_SET_L: {
					struct ibcs_semid_ds_l is, *is_p;

					retval = get_user(is_p, (struct ibcs_semid_ds_l **)&arg4->buf);
					if (!retval)
						retval = verify_area(VERIFY_WRITE, is_p, sizeof(is));
					if (retval)
						return retval;

					copy_from_user(&is, (char *)is_p, sizeof(is));
					isem_to_lsem_l(&is, &ls);

					lsemun.buf = &ls;
					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SEMCTL, arg1, arg2, IPC_SET, &lsemun);
					set_fs(old_fs);

					lsem_to_isem_l(&ls, &is);
					copy_to_user((char *)is_p, &is, sizeof(is));
					return retval;
				}

				case U_IPC_RMID:
				case U_IPC_RMID_L:
				case U_SETVAL:
				case U_GETVAL:
				case U_GETPID:
				case U_GETNCNT:
				case U_GETZCNT: {
					int cmd = ibcs_sem_trans(arg3);
					return SYS (ipc) (SEMCTL, arg1, arg2, cmd, arg4);
				}

				case U_SETALL:
				case U_GETALL: {
					int cmd = ibcs_sem_trans(arg3);
					return SYS (ipc) (SEMCTL, arg1, 0, cmd, arg4);
				}

				case U_IPC_STAT: {
					struct ibcs_semid_ds is, *is_p;

					retval = get_user(is_p, (struct ibcs_semid_ds **)&arg4->buf);
					if (!retval)
						retval = verify_area(VERIFY_WRITE, (char *)is_p, sizeof(is));
					if (retval)
						return retval;

					lsemun.buf = &ls;
					old_fs = get_fs();
					set_fs(get_ds());
					retval = SYS (ipc) (SEMCTL, arg1, 0, IPC_STAT, &lsemun);
					set_fs(old_fs);
					if (retval < 0)
						return retval;

					lsem_to_isem(&ls, &is);
					copy_to_user((char *)is_p, &is, sizeof(is));
					return retval;
				}

				case U_IPC_STAT_L: {
					struct ibcs_semid_ds_l is, *is_p;

					retval = get_user(is_p, (struct ibcs_semid_ds_l **)&arg4->buf);
					if (!retval)
						retval = verify_area(VERIFY_WRITE, (char *)is_p, sizeof(is));
					if (retval)
						return retval;

					lsemun.buf = &ls;
					old_fs = get_fs();
					set_fs(get_ds());
					retval = SYS (ipc) (SEMCTL, arg1, 0, IPC_STAT, &lsemun);
					set_fs(old_fs);
					if (retval < 0)
						return retval;

					lsem_to_isem_l(&ls, &is);
					copy_to_user((char *)is_p, &is, sizeof(is));
					return retval;
				}

				default:
					printk(KERN_ERR "%d ibcs_semctl: unsupported command %d\n",
						current->pid, arg3);
					return -EINVAL;
		  	}

		case U_SEMGET:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_semget: args: %d %d %o \n",
					current->pid,
					arg1, arg2, arg3);
#endif
			return SYS (ipc) (SEMGET, arg1, arg2, arg3, 0);

		case U_SEMOP:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) {
				int x;
				struct sembuf tmp;
				struct sembuf *tp = (struct sembuf *) arg2;

				printk(KERN_DEBUG "%d iBCS: ibcs_semop: args: %d 0x%08lx %d\n",
					current->pid,
					arg1, (unsigned long)arg2, arg3);
				for (x = 0; x < arg3; x++) {
					copy_from_user (&tmp, tp, sizeof (tmp));
					printk(KERN_DEBUG "%d iBCS: ibcs_semop args: %d %d 0%o \n",
						current->pid,
						tmp.sem_num, tmp.sem_op, tmp.sem_flg);
					tp++;
				}
			}
#endif
			return SYS (ipc) (SEMOP, arg1, arg3, 0, (struct sembuf *) arg2);
	}
	return -EINVAL;
}