/* ARGSUSED */ static int cnioctl(dev_t dev, int cmd, intptr_t arg, int flag, struct cred *cred, int *rvalp) { if (rconsvp == NULL) return (0); /* * In wc, VT_SET_CONSUSER which comes from minor node 0 * has two sources -- either /dev/console or /dev/vt/0 . * We need a way to differentiate them, so here we * change VT_SET_CONSUSER to a private VT_RESET_CONSUSER * ioctl. */ if (cmd == VT_SET_CONSUSER) cmd = VT_RESET_CONSUSER; if ((cmd & _CNIOC_MASK) == _CNIOC) return (cnprivateioc(dev, cmd, arg, flag, cred, rvalp)); if (rconsvp->v_stream != NULL) return (strioctl(rconsvp, cmd, arg, flag, U_TO_K, cred, rvalp)); return (cdev_ioctl(rconsdev, cmd, arg, flag, cred, rvalp)); }
int cnioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { int error; error = 0; /* * Superuser can always use this to wrest control of console * output from the "virtual" console. */ if (cmd == TIOCCONS && constty != NULL) { error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_VIRTUAL, constty); if (!error) constty = NULL; return (error); } /* * Redirect the ioctl, if that's appropriate. * Note that strange things can happen, if a program does * ioctls on /dev/console, then the console is redirected * out from under it. */ if (!cn_redirect(&dev, 0, &error)) return error; return cdev_ioctl(dev, cmd, data, flag, l); }
/** * @brief Shutdowns the system. */ PUBLIC int sys_shutdown(void) { /* Not allowed. */ if (!IS_SUPERUSER(curr_proc)) return (-EPERM); shutting_down = 1; cdev_ioctl(kout, TTY_CLEAR, 0); kprintf("system is going to shutdown NOW"); kprintf("synchronizing data..."); sys_sync(); kprintf("asking process to terminate..."); sys_kill(-1, SIGKILL); return (0); }
int ptyfs_ioctl(void *v) { struct vop_ioctl_args /* { struct vnode *a_vp; u_long a_command; void *a_data; int a_fflag; kauth_cred_t a_cred; } */ *ap = v; struct vnode *vp = ap->a_vp; struct ptyfsnode *ptyfs = VTOPTYFS(vp); switch (ptyfs->ptyfs_type) { case PTYFSpts: case PTYFSptc: return cdev_ioctl(vp->v_rdev, ap->a_command, ap->a_data, ap->a_fflag, curlwp); default: return EOPNOTSUPP; } }
/* ARGSUSED */ static int cnprivateioc(dev_t dev, int cmd, intptr_t arg, int flag, struct cred *cred, int *rvalp) { /* currently we only support one ioctl */ if (cmd != CONS_GETTERM) return (EINVAL); /* Confirm iwscn is immediate target of cn redirection */ if (rconsvp != wsconsvp) return (ENODEV); /* * If the redirection client is not wc, it should return * error upon receiving the CONS_GETTERM ioctl. * * if it is wc, we know that the target supports the CONS_GETTERM * ioctl, which very conviently has the exact same data * format as this ioctl... so let's just pass it on. */ return (cdev_ioctl(rconsdev, CONS_GETTERM, arg, flag, cred, rvalp)); }
/* * Verify that the disk in the drive is the same one that we * got the pcnode from. * MUST be called with node unlocked. */ int pc_verify(struct pcfs *fsp) { int fdstatus = 0; int error = 0; if (!fsp || fsp->pcfs_flags & PCFS_IRRECOV) return (EIO); if (!(fsp->pcfs_flags & PCFS_NOCHK) && fsp->pcfs_fatp) { /* * This "has it been removed" check should better be * modified for removeable media that are not floppies. * dkio-managed devices such as USB/firewire external * disks/memory sticks/floppies (gasp) do not understand * this ioctl. */ PC_DPRINTF1(4, "pc_verify fsp=0x%p\n", (void *)fsp); error = cdev_ioctl(fsp->pcfs_vfs->vfs_dev, FDGETCHANGE, (intptr_t)&fdstatus, FNATIVE | FKIOCTL, NULL, NULL); if (error) { if (error == ENOTTY || error == ENXIO) { /* * See comment above. This is a workaround * for removeable media that don't understand * floppy ioctls. */ error = 0; } else { PC_DPRINTF1(1, "pc_verify: FDGETCHANGE ioctl failed: %d\n", error); pc_mark_irrecov(fsp); } } else if (fsp->pcfs_fatjustread) { /* * Ignore the results of the ioctl if we just * read the FAT. There is a good chance that * the disk changed bit will be on, because * we've just mounted and we don't want to * give a false positive that the sky is falling. */ fsp->pcfs_fatjustread = 0; } else { /* * Oddly enough we can't check just one flag here. The * x86 floppy driver sets a different flag * (FDGC_DETECTED) than the sparc driver does. * I think this MAY be a bug, and I filed 4165938 * to get someone to look at the behavior * a bit more closely. In the meantime, my testing and * code examination seem to indicate it is safe to * check for either bit being set. */ if (fdstatus & (FDGC_HISTORY | FDGC_DETECTED)) { PC_DPRINTF0(1, "pc_verify: change detected\n"); pc_mark_irrecov(fsp); } } } if (error == 0 && fsp->pcfs_fatp == NULL) { error = pc_getfat(fsp); } return (error); }