+ pti->pt_flags |= PF_LIOC | PF_BLOCK;
+ while (pti->pt_ioc.c_cc)
+ (void) getc(&pti->pt_ioc);
+ (void) b_to_q(&cmd, sizeof cmd, &pti->pt_ioc);
+ if (cmd & IOC_IN)
+ (void) b_to_q(data, IOCPARM_LEN(cmd), &pti->pt_ioc);
+ ptcwakeup(tp, FREAD);
+ switch (tsleep((caddr_t)&pti->pt_ioc, TTIPRI-1, 5*hz)) {
+ case TS_SIG:
+ case TS_TIME:
+ while (pti->pt_ioc.c_cc)
+ (void) getc(&pti->pt_ioc);
+ if (pti->pt_flags & PF_WIOC)
+ wakeup((caddr_t)&pti->pt_flags);
+ if (pti->pt_flags & PF_OWAIT)
+ wakeup((caddr_t)pti + 1);
+ pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT);
+ ptswake(tp);
+ return (EBUSY);
+ case TS_OK:
+ break;
+ }
+ if (pti->pt_ioc.c_cc == 0) {
+ if (pti->pt_flags & PF_WIOC)
+ wakeup((caddr_t)&pti->pt_flags);
+ if (pti->pt_flags & PF_OWAIT)
+ wakeup((caddr_t)pti + 1);
+ pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT);
+ ptswake(tp);
+ goto doioctl;
+ }
+ if (q_to_b(&pti->pt_ioc, &error, sizeof error) != sizeof error)
+ error = EINVAL;
+ if (error == 0 && cmd & IOC_OUT) {
+ if (IOCPARM_LEN(cmd) != pti->pt_ioc.c_cc)
+ error = EINVAL;
+ else
+ (void) q_to_b(&pti->pt_ioc, data,
+ pti->pt_ioc.c_cc);
+ }
+ while (pti->pt_ioc.c_cc)
+ (void) getc(&pti->pt_ioc);
+ if (pti->pt_flags & PF_WIOC)
+ wakeup((caddr_t)&pti->pt_flags);
+ if (pti->pt_flags & PF_OWAIT)
+ wakeup((caddr_t)pti + 1);
+ pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT);
+ ptswake(tp);
+ return (error);
+ }
+
+ doioctl:
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
+ if (error < 0)
+ error = ttioctl(tp, cmd, data, flag);