static int
linux32_shmctl(struct lwp *l, const struct linux32_sys_ipc_args *uap,
    register_t *retval)
{
	int shmid, cmd, error;
	struct shmid_ds bs;
	struct linux32_shmid_ds ls;
	struct linux32_shmid64_ds ls64;

	shmid = SCARG(uap, a1);
	cmd = SCARG(uap, a2);

	switch (cmd & ~LINUX32_IPC_64) {

	case LINUX32_SHM_STAT:
		return ENOSYS;

	case LINUX32_IPC_STAT:
		error = shmctl1(l, shmid, IPC_STAT, &bs);
		if (error != 0)
			return error;
		if (cmd & LINUX32_IPC_64) {
			bsd_to_linux32_shmid64_ds(&bs, &ls64);
			error = copyout(&ls64, SCARG_P32(uap, ptr), sizeof ls64);
		} else {
			bsd_to_linux32_shmid_ds(&bs, &ls);
			error = copyout(&ls, SCARG_P32(uap, ptr), sizeof ls);
		}
		return error;

	case LINUX32_IPC_SET:
		if (cmd & LINUX32_IPC_64) {
			error = copyin(SCARG_P32(uap, ptr), &ls64, sizeof ls64);
			linux32_to_bsd_shmid64_ds(&ls64, &bs);
		} else {
			error = copyin(SCARG_P32(uap, ptr), &ls, sizeof ls);
			linux32_to_bsd_shmid_ds(&ls, &bs);
		}
		if (error != 0)
			return error;
		return shmctl1(l, shmid, IPC_SET, &bs);

	case LINUX32_IPC_RMID:
		return shmctl1(l, shmid, IPC_RMID, NULL);

	case LINUX32_SHM_LOCK:
		return shmctl1(l, shmid, SHM_LOCK, NULL);

	case LINUX32_SHM_UNLOCK:
		return shmctl1(l, shmid, SHM_UNLOCK, NULL);

	case LINUX32_IPC_INFO:
	case LINUX32_SHM_INFO:
		return ENOSYS;

	default:
		return EINVAL;
	}
}               
예제 #2
0
int
netbsd32___shmctl13(struct lwp *l, const struct netbsd32___shmctl13_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) shmid;
		syscallarg(int) cmd;
		syscallarg(netbsd32_shmid_dsp_t) buf;
	} */
	struct shmid_ds ds;
	struct netbsd32_shmid_ds ds32;
	int error, cmd;

	cmd = SCARG(uap, cmd);
	if (cmd == IPC_SET) {
		error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
		if (error)
			return error;
		netbsd32_to_shmid_ds(&ds32, &ds);
	}

	error = shmctl1(l, SCARG(uap, shmid), cmd,
	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);

	if (error == 0 && cmd == IPC_STAT) {
		netbsd32_from_shmid_ds(&ds, &ds32);
		error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
	}

	return error;
}
예제 #3
0
int
sys_shmctl(struct proc *p, void *v, register_t *retval)
{
	struct sys_shmctl_args /* {
		syscallarg(int) shmid;
		syscallarg(int) cmd;
		syscallarg(struct shmid_ds *) buf;
	} */ *uap = v;

	return (shmctl1(p, SCARG(uap, shmid), SCARG(uap, cmd),
	    (caddr_t)SCARG(uap, buf), copyin, copyout));
}
예제 #4
0
int
ibcs2_sys_shmsys(struct lwp *l, const struct ibcs2_sys_shmsys_args *uap, register_t *retval)
{
#ifdef SYSVSHM
	/* {
		syscallarg(int) which;
		syscallarg(int) a2;
		syscallarg(int) a3;
		syscallarg(int) a4;
	} */
	struct shmid_ds shmbuf;
	struct ibcs2_shmid_ds *isp, ishmbuf;
	int cmd, error;

	switch (SCARG(uap, which)) {
	case 0:						/* shmat */
		break;

	case 1:						/* shmctl */
		cmd = SCARG(uap, a3);
		isp = (struct ibcs2_shmid_ds *)SCARG(uap, a4);
		if (cmd == IPC_SET) {
			error = copyin(isp, &ishmbuf, sizeof(ishmbuf));
			if (error)
				return error;
			cvt_ishmid2shmid(&ishmbuf, &shmbuf);
		}

		error = shmctl1(l, SCARG(uap, a2), cmd,
		    (cmd == IPC_SET || cmd == IPC_STAT) ? &shmbuf : NULL);

		if (error == 0 && cmd == IPC_STAT) {
			cvt_shmid2ishmid(&shmbuf, &ishmbuf);
			error = copyout(&ishmbuf, isp, sizeof(ishmbuf));
		}
		return error;

	case 2:						/* shmdt */
		break;

	case 3:						/* shmget */
		break;

	default:
		return EINVAL;
	}
	return compat_10_sys_shmsys(l, (const void *)uap, retval);
#else
	return EINVAL;
#endif
}