Example #1
0
/*ARGSUSED*/
int
consioctl(__unused dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
	dev_t device;
	boolean_t funnel_state;
	int error;

	funnel_state = thread_funnel_set(kernel_flock, TRUE);

	if (constty)
	    device = constty->t_dev;
	else
	    device = cons.t_dev;
	/*
	 * Superuser can always use this to wrest control of console
	 * output from the "virtual" console.
	 */
	if ((unsigned int)cmd == TIOCCONS && constty) {
		error = proc_suser(p);
		if (error) {
			goto out;
		}
		constty = NULL;
		error = 0;
		goto out;
	}
	error =  (*cdevsw[major(device)].d_ioctl)(device, cmd, addr, flag, p);
out:
	thread_funnel_set(kernel_flock, funnel_state);

	return(error);
}
Example #2
0
/*
 * cdevsw interface to km driver.
 */
int 
kmopen(dev_t dev, int flag, __unused int devtype, struct proc *pp)
{
	int unit;
	struct tty *tp;
	struct winsize *wp;
	int ret;
	
	unit = minor(dev);
	if(unit >= 1)
		return (ENXIO);

	tp = (struct tty *)&cons;
	tp->t_oproc = kmstart;
	tp->t_param = NULL;
	tp->t_dev = dev;
	
	if ( !(tp->t_state & TS_ISOPEN) ) {
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = (CREAD | CS8 | CLOCAL);
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		termioschars(&tp->t_termios);
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && proc_suser(pp))
		return EBUSY;

	tp->t_state |= TS_CARR_ON; /* lie and say carrier exists and is on. */
	ret = ((*linesw[tp->t_line].l_open)(dev, tp));
	{
		PE_Video video;
		wp = &tp->t_winsize;
		/* Magic numbers.  These are CHARWIDTH and CHARHEIGHT
		 * from osfmk/ppc/POWERMAC/video_console.c
		 */
		wp->ws_xpixel = 8;
		wp->ws_ypixel = 16;

		if (flag & O_POPUP)
			PE_initialize_console(0, kPETextScreen);

		bzero(&video, sizeof(video));
		PE_current_console(&video);
		if( video.v_width != 0 && video.v_height != 0 ) {
			wp->ws_col = video.v_width / wp->ws_xpixel;
			wp->ws_row = video.v_height / wp->ws_ypixel;
		} else {
			wp->ws_col = 100;
			wp->ws_row = 36;
		}
	}
	return ret;
}
Example #3
0
/*
 * afs_suser() returns true if the caller is superuser, false otherwise.
 *
 * Note that it must NOT set errno.
 */
int
afs_suser(void *credp)
{
    int error;
    struct proc *p = current_proc();

#ifdef AFS_DARWIN80_ENV
    if ((error = proc_suser(p)) == 0) {
	return (1);
    }
    return (0);
#else
    if ((error = suser(p->p_ucred, &p->p_acflag)) == 0) {
	return (1);
    }
    return (0);
#endif
}
Example #4
0
int
cnioctl(__unused dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
	dev = cndev();

	/*
	 * XXX This check prevents the cons.c code from being shared between
	 * XXX all architectures; it is probably not needed on ARM, either,
	 * XXX but I have no test platforms or ability to run a kernel.
	 *
	 * Superuser can always use this to wrest control of console
	 * output from the "virtual" console.
	 */
	if ((unsigned) cmd == TIOCCONS && constty) {
		int             error = proc_suser(p);
		if (error)
			return (error);
		constty = NULL;
		return (0);
	}
	return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, addr, flag, p));
}
Example #5
0
/* ARGSUSED */
static	int
vnioctl(dev_t dev, u_long cmd, caddr_t data,
	__unused int flag, proc_t p,
	int is_char)
{
	struct vn_softc *vn;
	struct vn_ioctl_64 *viop;
	int error;
	u_int32_t *f;
	u_int64_t * o;
	int unit;
	struct vfsioattr ioattr;
	struct vn_ioctl_64 user_vnio;
	struct vfs_context  	context;

	unit = vnunit(dev);
	if (vnunit(dev) >= NVNDEVICE) {
		return (ENXIO);
	}

	vn = vn_table + unit;
	error = proc_suser(p);
	if (error) {
		goto done;
	}

	context.vc_thread = current_thread();
	context.vc_ucred = vn->sc_cred;

	viop = (struct vn_ioctl_64 *)data;
	f = (u_int32_t *)data;
	o = (u_int64_t *)data;
	switch (cmd) {
#ifdef __LP64__
	case VNIOCDETACH32:
	case VNIOCDETACH:
#else
	case VNIOCDETACH:
	case VNIOCDETACH64:
#endif
	case DKIOCGETBLOCKSIZE:
	case DKIOCSETBLOCKSIZE:
	case DKIOCGETMAXBLOCKCOUNTREAD:
	case DKIOCGETMAXBLOCKCOUNTWRITE:
	case DKIOCGETMAXSEGMENTCOUNTREAD:
	case DKIOCGETMAXSEGMENTCOUNTWRITE:
	case DKIOCGETMAXSEGMENTBYTECOUNTREAD:
	case DKIOCGETMAXSEGMENTBYTECOUNTWRITE:
	case DKIOCGETBLOCKCOUNT:
	case DKIOCGETBLOCKCOUNT32:
		if ((vn->sc_flags & VNF_INITED) == 0) {
			error = ENXIO;
			goto done;
		}
		break;
	default:
		break;
	}

	if (vn->sc_vp != NULL)
		vfs_ioattr(vnode_mount(vn->sc_vp), &ioattr);
	else
		bzero(&ioattr, sizeof(ioattr));

	switch (cmd) {
	case DKIOCISVIRTUAL:
		*f = 1;
		break;
	case DKIOCGETMAXBLOCKCOUNTREAD:
		*o = ioattr.io_maxreadcnt / vn->sc_secsize;
		break;
	case DKIOCGETMAXBLOCKCOUNTWRITE:
		*o = ioattr.io_maxwritecnt / vn->sc_secsize;
		break;
	case DKIOCGETMAXBYTECOUNTREAD:
		*o = ioattr.io_maxreadcnt;
		break;
	case DKIOCGETMAXBYTECOUNTWRITE:
		*o = ioattr.io_maxwritecnt;
		break;
	case DKIOCGETMAXSEGMENTCOUNTREAD:
		*o = ioattr.io_segreadcnt;
		break;
	case DKIOCGETMAXSEGMENTCOUNTWRITE:
		*o = ioattr.io_segwritecnt;
		break;
	case DKIOCGETMAXSEGMENTBYTECOUNTREAD:
		*o = ioattr.io_maxsegreadsize;
		break;
	case DKIOCGETMAXSEGMENTBYTECOUNTWRITE:
		*o = ioattr.io_maxsegwritesize;
		break;
	case DKIOCGETBLOCKSIZE:
	        *f = vn->sc_secsize;
		break;
	case DKIOCSETBLOCKSIZE:
		if (is_char) {
			/* can only set block size on block device */
			error = ENODEV;
			break;
		}
		if (*f < DEV_BSIZE) {
			error = EINVAL;
			break;
		}
		if (vn->sc_shadow_vp != NULL) {
			if (*f == (unsigned)vn->sc_secsize) {
				break;
			}
			/* can't change the block size if already shadowing */
			error = EBUSY;
			break;
		}
		vn->sc_secsize = *f;
		/* recompute the size in terms of the new blocksize */
		vn->sc_size = vn->sc_fsize / vn->sc_secsize;
		break;
	case DKIOCISWRITABLE:
		*f = 1;
		break;
	case DKIOCGETBLOCKCOUNT32:
		*f = vn->sc_size;
		break;
	case DKIOCGETBLOCKCOUNT:
		*o = vn->sc_size;
		break;
#ifdef __LP64__
	case VNIOCSHADOW32:
	case VNIOCSHADOW:
#else
	case VNIOCSHADOW:
	case VNIOCSHADOW64:
#endif
		if (vn->sc_shadow_vp != NULL) {
			error = EBUSY;
			break;
		}
		if (vn->sc_vp == NULL) {
			/* much be attached before we can shadow */
			error = EINVAL;
			break;
		}
		if (!proc_is64bit(p)) {
			/* downstream code expects LP64 version of vn_ioctl structure */
			vn_ioctl_to_64((struct vn_ioctl_32 *)viop, &user_vnio);
			viop = &user_vnio;
		}
		if (viop->vn_file == USER_ADDR_NULL) {
			error = EINVAL;
			break;
		}
		error = vniocattach_shadow(vn, viop, dev, 0, p);
		break;

#ifdef __LP64__
	case VNIOCATTACH32:
	case VNIOCATTACH:
#else
	case VNIOCATTACH:
	case VNIOCATTACH64:
#endif
		if (is_char) {
			/* attach only on block device */
			error = ENODEV;
			break;
		}
		if (vn->sc_flags & VNF_INITED) {
			error = EBUSY;
			break;
		}
		if (!proc_is64bit(p)) {
			/* downstream code expects LP64 version of vn_ioctl structure */
			vn_ioctl_to_64((struct vn_ioctl_32 *)viop, &user_vnio);
			viop = &user_vnio;
		}
		if (viop->vn_file == USER_ADDR_NULL) {
			error = EINVAL;
			break;
		}
		error = vniocattach_file(vn, viop, dev, 0, p);
		break;

#ifdef __LP64__
	case VNIOCDETACH32:
	case VNIOCDETACH:
#else
	case VNIOCDETACH:
	case VNIOCDETACH64:
#endif
		if (is_char) {
			/* detach only on block device */
			error = ENODEV;
			break;
		}
		/* Note: spec_open won't open a mounted block device */

		/*
		 * XXX handle i/o in progress.  Return EBUSY, or wait, or
		 * flush the i/o.
		 * XXX handle multiple opens of the device.  Return EBUSY,
		 * or revoke the fd's.
		 * How are these problems handled for removable and failing
		 * hardware devices? (Hint: They are not)
		 */
		vnclear(vn, &context);
		break;

	case VNIOCGSET:
		vn_options |= *f;
		*f = vn_options;
		break;

	case VNIOCGCLEAR:
		vn_options &= ~(*f);
		*f = vn_options;
		break;

	case VNIOCUSET:
		vn->sc_options |= *f;
		*f = vn->sc_options;
		break;

	case VNIOCUCLEAR:
		vn->sc_options &= ~(*f);
		*f = vn->sc_options;
		break;

	default:
		error = ENOTTY;
		break;
	}
 done:
	return(error);
}
Example #6
0
/*
 * cdevsw interface to km driver.
 */
int
kmopen(dev_t dev, int flag, __unused int devtype, proc_t pp)
{
	int             unit;
	struct tty     *tp;
	struct winsize *wp;
	int             ret;

	unit = minor(dev);
	if (unit >= 1)
		return (ENXIO);

	tp = km_tty[unit];

	tty_lock(tp);

	tp->t_oproc = kmstart;
	tp->t_param = NULL;
	tp->t_dev = dev;

	if (!(tp->t_state & TS_ISOPEN)) {
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = (CREAD | CS8 | CLOCAL);
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		termioschars(&tp->t_termios);
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && proc_suser(pp)) {
		ret = EBUSY;
		goto out;
	}

	tp->t_state |= TS_CARR_ON;	/* lie and say carrier exists and is
					 * on. */
	ret = ((*linesw[tp->t_line].l_open) (dev, tp));
	{
		PE_Video        video;
		wp = &tp->t_winsize;
		/*
		 * Magic numbers.  These are CHARWIDTH and CHARHEIGHT from
		 * pexpert/i386/video_console.c
		 */
		wp->ws_xpixel = 8;
		wp->ws_ypixel = 16;

		tty_unlock(tp);		/* XXX race window */

		if (flag & O_POPUP)
			PE_initialize_console(0, kPETextScreen);

		bzero(&video, sizeof(video));
		PE_current_console(&video);

		tty_lock(tp);

		if (serialmode & SERIALMODE_OUTPUT) {
			wp->ws_col = 80;
			wp->ws_row = 24;
		} else if (video.v_width != 0 && video.v_height != 0) {
			wp->ws_col = video.v_width / wp->ws_xpixel;
			wp->ws_row = video.v_height / wp->ws_ypixel;
		} else {
			wp->ws_col = 100;
			wp->ws_row = 36;
		}
	}

out:
	tty_unlock(tp);

	return ret;
}