コード例 #1
0
ファイル: svr4_fcntl.c プロジェクト: Tommmster/netbsd-avr32
int
svr4_sys_fcntl(struct lwp *l, const struct svr4_sys_fcntl_args *uap, register_t *retval)
{
	struct sys_fcntl_args	fa;
	register_t		flags;
	struct svr4_flock64	ifl64;
	struct svr4_flock	ifl;
	struct flock		fl;
	int error;
	int cmd;

	SCARG(&fa, fd) = SCARG(uap, fd);
	SCARG(&fa, arg) = SCARG(uap, arg);

	switch (SCARG(uap, cmd)) {
	case SVR4_F_DUPFD:
		cmd = F_DUPFD;
		break;
	case SVR4_F_GETFD:
		cmd = F_GETFD;
		break;
	case SVR4_F_SETFD:
		cmd = F_SETFD;
		break;

	case SVR4_F_GETFL:
		cmd = F_GETFL;
		break;

	case SVR4_F_SETFL:
		/*
		 * we must save the O_ASYNC flag, as that is
		 * handled by ioctl(_, I_SETSIG, _) emulation.
		 */
		SCARG(&fa, cmd) = F_GETFL;
		if ((error = sys_fcntl(l, &fa, &flags)) != 0)
			return error;
		flags &= O_ASYNC;
		flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg));
		cmd = F_SETFL;
		SCARG(&fa, arg) = (void *) flags;
		break;

	case SVR4_F_GETLK:
		cmd = F_GETLK;
		goto lock32;
	case SVR4_F_SETLK:
		cmd = F_SETLK;
		goto lock32;
	case SVR4_F_SETLKW:
		cmd = F_SETLKW;
	    lock32:
		error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
		if (error)
			return error;
		svr4_to_bsd_flock(&ifl, &fl);

		error = do_fcntl_lock(SCARG(uap, fd), cmd, &fl);
		if (cmd != F_GETLK || error != 0)
			return error;

		bsd_to_svr4_flock(&fl, &ifl);
		return copyout(&ifl, SCARG(uap, arg), sizeof ifl);

	case SVR4_F_DUP2FD:
		{
			struct sys_dup2_args du;

			SCARG(&du, from) = SCARG(uap, fd);
			SCARG(&du, to) = (int)(u_long)SCARG(uap, arg);
			error = sys_dup2(l, &du, retval);
			if (error)
				return error;
			*retval = SCARG(&du, to);
			return 0;
		}

	case SVR4_F_FREESP:
		error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
		if (error)
			return error;
		svr4_to_bsd_flock(&ifl, &fl);
		return fd_truncate(l, SCARG(uap, fd), &fl, retval);

	case SVR4_F_GETLK64:
		cmd = F_GETLK;
		goto lock64;
	case SVR4_F_SETLK64:
		cmd = F_SETLK;
		goto lock64;
	case SVR4_F_SETLKW64:
		cmd = F_SETLKW;
	    lock64:
		error = copyin(SCARG(uap, arg), &ifl64, sizeof ifl64);
		if (error)
			return error;
		svr4_to_bsd_flock64(&ifl64, &fl);

		error = do_fcntl_lock(SCARG(uap, fd), cmd, &fl);
		if (cmd != F_GETLK || error != 0)
			return error;

		bsd_to_svr4_flock64(&fl, &ifl64);
		return copyout(&ifl64, SCARG(uap, arg), sizeof ifl64);

	case SVR4_F_FREESP64:
		error = copyin(SCARG(uap, arg), &ifl64, sizeof ifl64);
		if (error)
			return error;
		svr4_to_bsd_flock64(&ifl64, &fl);
		return fd_truncate(l, SCARG(uap, fd), &fl, retval);

	case SVR4_F_REVOKE:
		return fd_revoke(l, SCARG(uap, fd), retval);

	default:
		return ENOSYS;
	}

	SCARG(&fa, cmd) = cmd;

	error = sys_fcntl(l, &fa, retval);
	if (error != 0)
		return error;

	switch (SCARG(uap, cmd)) {

	case SVR4_F_GETFL:
		*retval = bsd_to_svr4_flags(*retval);
		break;
	}

	return 0;
}
コード例 #2
0
ファイル: svr4_32_sockio.c プロジェクト: ryo/netbsd-src
int
svr4_32_sock_ioctl(file_t *fp, struct lwp *l, register_t *retval, int fd, u_long cmd, void *data)
{
	int error;
	int (*ctl)(file_t *, u_long, void *) = fp->f_ops->fo_ioctl;

	*retval = 0;

	switch (cmd) {
	case SVR4_SIOCGIFNUM:
		{
			struct ifnet *ifp;
			int ifnum = 0;
			int s;

			/*
			 * This does not return the number of physical
			 * interfaces (if_index), but the number of interfaces
			 * + addresses like ifconf() does, because this number
			 * is used by code that will call SVR4_SIOCGIFCONF to
			 * find the space needed for SVR4_SIOCGIFCONF. So we
			 * count the number of ifreq entries that the next
			 * SVR4_SIOCGIFCONF will return. Maybe a more correct
			 * fix is to make SVR4_SIOCGIFCONF return only one
			 * entry per physical interface?
			 */

			s = pserialize_read_enter();
			IFNET_READER_FOREACH(ifp)
				ifnum += svr4_count_ifnum(ifp);
			pserialize_read_exit(s);

			DPRINTF(("SIOCGIFNUM %d\n", ifnum));
			return copyout(&ifnum, data, sizeof(ifnum));
		}

	case SVR4_32_SIOCGIFFLAGS:
		{
			struct oifreq br;
			struct svr4_32_ifreq sr;

			if ((error = copyin(data, &sr, sizeof(sr))) != 0)
				return error;

			(void) strncpy(br.ifr_name, sr.svr4_ifr_name,
			    sizeof(br.ifr_name));

			if ((error = (*ctl)(fp, SIOCGIFFLAGS, &br)) != 0) {
				DPRINTF(("SIOCGIFFLAGS %s: error %d\n",
					 sr.svr4_ifr_name, error));
				return error;
			}

			sr.svr4_ifr_flags = bsd_to_svr4_flags(br.ifr_flags);
			DPRINTF(("SIOCGIFFLAGS %s = %x\n",
				sr.svr4_ifr_name, sr.svr4_ifr_flags));
			return copyout(&sr, data, sizeof(sr));
		}

	case SVR4_32_SIOCGIFCONF:
		{
			struct svr4_32_ifconf sc;
			struct oifconf ifc;

			if ((error = copyin(data, &sc, sizeof(sc))) != 0)
				return error;

			DPRINTF(("ifreq %ld svr4_32_ifreq %ld ifc_len %d\n",
				(unsigned long)sizeof(struct oifreq),
				(unsigned long)sizeof(struct svr4_32_ifreq),
				sc.svr4_32_ifc_len));

			ifc.ifc_len = sc.svr4_32_ifc_len;
			ifc.ifc_buf = NETBSD32PTR64(sc.ifc_ifcu.ifcu_buf);

			if ((error = (*ctl)(fp, OOSIOCGIFCONF, &ifc)) != 0)
				return error;

			DPRINTF(("SIOCGIFCONF\n"));
			return 0;
		}


	default:
		DPRINTF(("Unknown svr4_32 sockio %lx\n", cmd));
		return 0;	/* ENOSYS really */
	}
}