xref: /original-bsd/sys/kern/tty_pty.c (revision 86ed09e7)
1 /*
2  * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)tty_pty.c	7.16 (Berkeley) 09/11/90
8  */
9 
10 /*
11  * Pseudo-teletype Driver
12  * (Actually two drivers, requiring two entries in 'cdevsw')
13  */
14 #include "pty.h"
15 
16 #if NPTY > 0
17 #include "param.h"
18 #include "systm.h"
19 #include "ioctl.h"
20 #include "tty.h"
21 #include "user.h"
22 #include "conf.h"
23 #include "file.h"
24 #include "proc.h"
25 #include "uio.h"
26 #include "kernel.h"
27 #include "vnode.h"
28 
29 #if NPTY == 1
30 #undef NPTY
31 #define	NPTY	32		/* crude XXX */
32 #endif
33 
34 #define BUFSIZ 100		/* Chunk size iomoved to/from user */
35 
36 /*
37  * pts == /dev/tty[pqrs]?
38  * ptc == /dev/pty[pqrs]?
39  */
40 struct	tty pt_tty[NPTY];
41 struct	pt_ioctl {
42 	int	pt_flags;
43 	struct	proc *pt_selr, *pt_selw;
44 	u_char	pt_send;
45 	u_char	pt_ucntl;
46 } pt_ioctl[NPTY];
47 int	npty = NPTY;		/* for pstat -t */
48 
49 int ptydebug = 0;
50 
51 #define	PF_RCOLL	0x01
52 #define	PF_WCOLL	0x02
53 #define	PF_NBIO		0x04
54 #define	PF_PKT		0x08		/* packet mode */
55 #define	PF_STOPPED	0x10		/* user told stopped */
56 #define	PF_REMOTE	0x20		/* remote and flow controlled input */
57 #define	PF_NOSTOP	0x40
58 #define PF_UCNTL	0x80		/* user control mode */
59 
60 /*ARGSUSED*/
61 ptsopen(dev, flag)
62 	dev_t dev;
63 {
64 	register struct tty *tp;
65 	int error;
66 
67 #ifdef lint
68 	npty = npty;
69 #endif
70 	if (minor(dev) >= NPTY)
71 		return (ENXIO);
72 	tp = &pt_tty[minor(dev)];
73 	if ((tp->t_state & TS_ISOPEN) == 0) {
74 		tp->t_state |= TS_WOPEN;
75 		ttychars(tp);		/* Set up default chars */
76 		tp->t_iflag = TTYDEF_IFLAG;
77 		tp->t_oflag = TTYDEF_OFLAG;
78 		tp->t_lflag = TTYDEF_LFLAG;
79 		tp->t_cflag = TTYDEF_CFLAG;
80 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
81 		ttsetwater(tp);		/* would be done in xxparam() */
82 	} else if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
83 		return (EBUSY);
84 	if (tp->t_oproc)			/* Ctrlr still around. */
85 		tp->t_state |= TS_CARR_ON;
86 	while ((tp->t_state & TS_CARR_ON) == 0) {
87 		tp->t_state |= TS_WOPEN;
88 		if (flag&FNDELAY)
89 			break;
90 		if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
91 		    ttopen, 0))
92 			return (error);
93 	}
94 	error = (*linesw[tp->t_line].l_open)(dev, tp, flag);
95 	ptcwakeup(tp, FREAD|FWRITE);
96 	return (error);
97 }
98 
99 ptsclose(dev)
100 	dev_t dev;
101 {
102 	register struct tty *tp;
103 
104 	tp = &pt_tty[minor(dev)];
105 	(*linesw[tp->t_line].l_close)(tp);
106 	ttyclose(tp);
107 	ptcwakeup(tp, FREAD|FWRITE);
108 }
109 
110 ptsread(dev, uio, flag)
111 	dev_t dev;
112 	struct uio *uio;
113 {
114 	register struct tty *tp = &pt_tty[minor(dev)];
115 	register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
116 	int error = 0;
117 
118 again:
119 	if (pti->pt_flags & PF_REMOTE) {
120 		while (isbackground(u.u_procp, tp)) {
121 			if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) ||
122 			    (u.u_procp->p_sigmask & sigmask(SIGTTIN)) ||
123 			    u.u_procp->p_pgrp->pg_jobc == 0 ||
124 			    u.u_procp->p_flag&SVFORK)
125 				return (EIO);
126 			pgsignal(u.u_procp->p_pgrp, SIGTTIN, 1);
127 			if (error = ttysleep(tp, (caddr_t)&lbolt,
128 			    TTIPRI | PCATCH, ttybg, 0))
129 				return (error);
130 		}
131 		if (tp->t_canq.c_cc == 0) {
132 			if (flag & IO_NDELAY)
133 				return (EWOULDBLOCK);
134 			if (error = ttysleep(tp, (caddr_t)&tp->t_canq,
135 			    TTIPRI | PCATCH, ttyin, 0))
136 				return (error);
137 			goto again;
138 		}
139 		while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
140 			if (ureadc(getc(&tp->t_canq), uio) < 0) {
141 				error = EFAULT;
142 				break;
143 			}
144 		if (tp->t_canq.c_cc == 1)
145 			(void) getc(&tp->t_canq);
146 		if (tp->t_canq.c_cc)
147 			return (error);
148 	} else
149 		if (tp->t_oproc)
150 			error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
151 	ptcwakeup(tp, FWRITE);
152 	return (error);
153 }
154 
155 /*
156  * Write to pseudo-tty.
157  * Wakeups of controlling tty will happen
158  * indirectly, when tty driver calls ptsstart.
159  */
160 ptswrite(dev, uio, flag)
161 	dev_t dev;
162 	struct uio *uio;
163 {
164 	register struct tty *tp;
165 
166 	tp = &pt_tty[minor(dev)];
167 	if (tp->t_oproc == 0)
168 		return (EIO);
169 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
170 }
171 
172 /*
173  * Start output on pseudo-tty.
174  * Wake up process selecting or sleeping for input from controlling tty.
175  */
176 ptsstart(tp)
177 	struct tty *tp;
178 {
179 	register struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
180 
181 	if (tp->t_state & TS_TTSTOP)
182 		return;
183 	if (pti->pt_flags & PF_STOPPED) {
184 		pti->pt_flags &= ~PF_STOPPED;
185 		pti->pt_send = TIOCPKT_START;
186 	}
187 	ptcwakeup(tp, FREAD);
188 }
189 
190 ptcwakeup(tp, flag)
191 	struct tty *tp;
192 {
193 	struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
194 
195 	if (flag & FREAD) {
196 		if (pti->pt_selr) {
197 			selwakeup(pti->pt_selr, pti->pt_flags & PF_RCOLL);
198 			pti->pt_selr = 0;
199 			pti->pt_flags &= ~PF_RCOLL;
200 		}
201 		wakeup((caddr_t)&tp->t_outq.c_cf);
202 	}
203 	if (flag & FWRITE) {
204 		if (pti->pt_selw) {
205 			selwakeup(pti->pt_selw, pti->pt_flags & PF_WCOLL);
206 			pti->pt_selw = 0;
207 			pti->pt_flags &= ~PF_WCOLL;
208 		}
209 if (ptydebug) printf("WAKEUP c_cf %d\n", u.u_procp->p_pid);
210 		wakeup((caddr_t)&tp->t_rawq.c_cf);
211 	}
212 }
213 
214 /*ARGSUSED*/
215 ptcopen(dev, flag)
216 	dev_t dev;
217 	int flag;
218 {
219 	register struct tty *tp;
220 	struct pt_ioctl *pti;
221 
222 	if (minor(dev) >= NPTY)
223 		return (ENXIO);
224 	tp = &pt_tty[minor(dev)];
225 	if (tp->t_oproc)
226 		return (EIO);
227 	tp->t_oproc = ptsstart;
228 	(void)(*linesw[tp->t_line].l_modem)(tp, 1);
229 	tp->t_lflag &= ~EXTPROC;
230 	pti = &pt_ioctl[minor(dev)];
231 	pti->pt_flags = 0;
232 	pti->pt_send = 0;
233 	pti->pt_ucntl = 0;
234 	return (0);
235 }
236 
237 ptcclose(dev)
238 	dev_t dev;
239 {
240 	register struct tty *tp;
241 
242 	tp = &pt_tty[minor(dev)];
243 	(void)(*linesw[tp->t_line].l_modem)(tp, 0);
244 	tp->t_state &= ~TS_CARR_ON;
245 	tp->t_oproc = 0;		/* mark closed */
246 	tp->t_session = 0;
247 }
248 
249 ptcread(dev, uio, flag)
250 	dev_t dev;
251 	struct uio *uio;
252 {
253 	register struct tty *tp = &pt_tty[minor(dev)];
254 	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
255 	char buf[BUFSIZ];
256 	int error = 0, cc;
257 
258 	/*
259 	 * We want to block until the slave
260 	 * is open, and there's something to read;
261 	 * but if we lost the slave or we're NBIO,
262 	 * then return the appropriate error instead.
263 	 */
264 	for (;;) {
265 		if (tp->t_state&TS_ISOPEN) {
266 			if (pti->pt_flags&PF_PKT && pti->pt_send) {
267 				error = ureadc((int)pti->pt_send, uio);
268 				if (error)
269 					return (error);
270 				if (pti->pt_send & TIOCPKT_IOCTL) {
271 					cc = MIN(uio->uio_resid,
272 						sizeof(tp->t_termios));
273 					uiomove(&tp->t_termios, cc, uio);
274 				}
275 				pti->pt_send = 0;
276 				return (0);
277 			}
278 			if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
279 				error = ureadc((int)pti->pt_ucntl, uio);
280 				if (error)
281 					return (error);
282 				pti->pt_ucntl = 0;
283 				return (0);
284 			}
285 			if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
286 				break;
287 		}
288 		if ((tp->t_state&TS_CARR_ON) == 0)
289 			return (0);	/* EOF */
290 		if (flag & IO_NDELAY)
291 			return (EWOULDBLOCK);
292 		if (error = tsleep((caddr_t)&tp->t_outq.c_cf, TTIPRI | PCATCH,
293 		    ttyin, 0))
294 			return (error);
295 	}
296 	if (pti->pt_flags & (PF_PKT|PF_UCNTL))
297 		error = ureadc(0, uio);
298 	while (uio->uio_resid > 0 && error == 0) {
299 		cc = q_to_b(&tp->t_outq, buf, MIN(uio->uio_resid, BUFSIZ));
300 		if (cc <= 0)
301 			break;
302 		error = uiomove(buf, cc, uio);
303 	}
304 	if (tp->t_outq.c_cc <= tp->t_lowat) {
305 		if (tp->t_state&TS_ASLEEP) {
306 			tp->t_state &= ~TS_ASLEEP;
307 			wakeup((caddr_t)&tp->t_outq);
308 		}
309 		if (tp->t_wsel) {
310 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
311 			tp->t_wsel = 0;
312 			tp->t_state &= ~TS_WCOLL;
313 		}
314 	}
315 	return (error);
316 }
317 
318 ptsstop(tp, flush)
319 	register struct tty *tp;
320 	int flush;
321 {
322 	struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
323 	int flag;
324 
325 	/* note: FLUSHREAD and FLUSHWRITE already ok */
326 	if (flush == 0) {
327 		flush = TIOCPKT_STOP;
328 		pti->pt_flags |= PF_STOPPED;
329 	} else
330 		pti->pt_flags &= ~PF_STOPPED;
331 	pti->pt_send |= flush;
332 	/* change of perspective */
333 	flag = 0;
334 	if (flush & FREAD)
335 		flag |= FWRITE;
336 	if (flush & FWRITE)
337 		flag |= FREAD;
338 	ptcwakeup(tp, flag);
339 }
340 
341 ptcselect(dev, rw)
342 	dev_t dev;
343 	int rw;
344 {
345 	register struct tty *tp = &pt_tty[minor(dev)];
346 	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
347 	struct proc *p;
348 	int s;
349 
350 	if ((tp->t_state&TS_CARR_ON) == 0)
351 		return (1);
352 	switch (rw) {
353 
354 	case FREAD:
355 		/*
356 		 * Need to block timeouts (ttrstart).
357 		 */
358 		s = spltty();
359 		if ((tp->t_state&TS_ISOPEN) &&
360 		     tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
361 			splx(s);
362 			return (1);
363 		}
364 		splx(s);
365 		/* FALLTHROUGH */
366 
367 	case 0:					/* exceptional */
368 		if ((tp->t_state&TS_ISOPEN) &&
369 		    (pti->pt_flags&PF_PKT && pti->pt_send ||
370 		     pti->pt_flags&PF_UCNTL && pti->pt_ucntl))
371 			return (1);
372 		if ((p = pti->pt_selr) && p->p_wchan == (caddr_t)&selwait)
373 			pti->pt_flags |= PF_RCOLL;
374 		else
375 			pti->pt_selr = u.u_procp;
376 		break;
377 
378 
379 	case FWRITE:
380 		if (tp->t_state&TS_ISOPEN) {
381 			if (pti->pt_flags & PF_REMOTE) {
382 			    if (tp->t_canq.c_cc == 0)
383 				return (1);
384 			} else {
385 			    if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2)
386 				    return (1);
387 			    if (tp->t_canq.c_cc == 0 && (tp->t_iflag&ICANON))
388 				    return (1);
389 			}
390 		}
391 		if ((p = pti->pt_selw) && p->p_wchan == (caddr_t)&selwait)
392 			pti->pt_flags |= PF_WCOLL;
393 		else
394 			pti->pt_selw = u.u_procp;
395 		break;
396 
397 	}
398 	return (0);
399 }
400 
401 ptcwrite(dev, uio, flag)
402 	dev_t dev;
403 	register struct uio *uio;
404 {
405 	register struct tty *tp = &pt_tty[minor(dev)];
406 	register struct iovec *iov;
407 	register char *cp;
408 	register int cc = 0;
409 	char locbuf[BUFSIZ];
410 	int cnt = 0;
411 	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
412 	int error = 0;
413 
414 again:
415 	if ((tp->t_state&TS_ISOPEN) == 0)
416 		goto block;
417 	if (pti->pt_flags & PF_REMOTE) {
418 		if (tp->t_canq.c_cc)
419 			goto block;
420 		while (uio->uio_iovcnt > 0 && tp->t_canq.c_cc < TTYHOG - 1) {
421 			iov = uio->uio_iov;
422 			if (iov->iov_len == 0) {
423 				uio->uio_iovcnt--;
424 				uio->uio_iov++;
425 				continue;
426 			}
427 			if (cc == 0) {
428 				cc = MIN(iov->iov_len, BUFSIZ);
429 				cc = MIN(cc, TTYHOG - 1 - tp->t_canq.c_cc);
430 				cp = locbuf;
431 				error = uiomove(cp, cc, uio);
432 				if (error)
433 					return (error);
434 				/* check again for safety */
435 				if ((tp->t_state&TS_ISOPEN) == 0)
436 					return (EIO);
437 			}
438 			if (cc)
439 				(void) b_to_q(cp, cc, &tp->t_canq);
440 			cc = 0;
441 		}
442 		(void) putc(0, &tp->t_canq);
443 		ttwakeup(tp);
444 		wakeup((caddr_t)&tp->t_canq);
445 		return (0);
446 	}
447 	while (uio->uio_iovcnt > 0) {
448 		iov = uio->uio_iov;
449 		if (cc == 0) {
450 			if (iov->iov_len == 0) {
451 				uio->uio_iovcnt--;
452 				uio->uio_iov++;
453 				continue;
454 			}
455 			cc = MIN(iov->iov_len, BUFSIZ);
456 			cp = locbuf;
457 			error = uiomove(cp, cc, uio);
458 			if (error)
459 				return (error);
460 			/* check again for safety */
461 			if ((tp->t_state&TS_ISOPEN) == 0)
462 				return (EIO);
463 		}
464 		while (cc > 0) {
465 			if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
466 			   (tp->t_canq.c_cc > 0 || !(tp->t_iflag&ICANON))) {
467 				wakeup((caddr_t)&tp->t_rawq);
468 				goto block;
469 			}
470 			(*linesw[tp->t_line].l_rint)(*cp++&0377, tp);
471 			cnt++;
472 			cc--;
473 		}
474 		cc = 0;
475 	}
476 	return (0);
477 block:
478 	/*
479 	 * Come here to wait for slave to open, for space
480 	 * in outq, or space in rawq.
481 	 */
482 	if ((tp->t_state&TS_CARR_ON) == 0)
483 		return (EIO);
484 	if ((pti->pt_flags & PF_NBIO) || (flag & IO_NDELAY)) {
485 		iov->iov_base -= cc;
486 		iov->iov_len += cc;
487 		uio->uio_resid += cc;
488 		uio->uio_offset -= cc;
489 		if (cnt == 0)
490 			return (EWOULDBLOCK);
491 		return (0);
492 	}
493 	if (error = tsleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI | PCATCH,
494 	    ttyout, 0))
495 		return (error);
496 	goto again;
497 }
498 
499 /*ARGSUSED*/
500 ptyioctl(dev, cmd, data, flag)
501 	caddr_t data;
502 	dev_t dev;
503 {
504 	register struct tty *tp = &pt_tty[minor(dev)];
505 	register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
506 	register u_char *cc = tp->t_cc;
507 	int stop, error;
508 	extern ttyinput();
509 
510 	/*
511 	 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
512 	 * ttywflush(tp) will hang if there are characters in the outq.
513 	 */
514 	if (cmd == TIOCEXT) {
515 		/*
516 		 * When the EXTPROC bit is being toggled, we need
517 		 * to send an TIOCPKT_IOCTL if the packet driver
518 		 * is turned on.
519 		 */
520 		if (*(int *)data) {
521 			if (pti->pt_flags & PF_PKT) {
522 				pti->pt_send |= TIOCPKT_IOCTL;
523 				ptcwakeup(tp);
524 			}
525 			tp->t_lflag |= EXTPROC;
526 		} else {
527 			if ((tp->t_state & EXTPROC) &&
528 			    (pti->pt_flags & PF_PKT)) {
529 				pti->pt_send |= TIOCPKT_IOCTL;
530 				ptcwakeup(tp);
531 			}
532 			tp->t_lflag &= ~EXTPROC;
533 		}
534 		return(0);
535 	} else
536 	if (cdevsw[major(dev)].d_open == ptcopen)
537 		switch (cmd) {
538 
539 		case TIOCGPGRP:
540 			/*
541 			 * We aviod calling ttioctl on the controller since,
542 			 * in that case, tp must be the controlling terminal.
543 			 */
544 			*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
545 			return (0);
546 
547 		case TIOCPKT:
548 			if (*(int *)data) {
549 				if (pti->pt_flags & PF_UCNTL)
550 					return (EINVAL);
551 				pti->pt_flags |= PF_PKT;
552 			} else
553 				pti->pt_flags &= ~PF_PKT;
554 			return (0);
555 
556 		case TIOCUCNTL:
557 			if (*(int *)data) {
558 				if (pti->pt_flags & PF_PKT)
559 					return (EINVAL);
560 				pti->pt_flags |= PF_UCNTL;
561 			} else
562 				pti->pt_flags &= ~PF_UCNTL;
563 			return (0);
564 
565 		case TIOCREMOTE:
566 			if (*(int *)data)
567 				pti->pt_flags |= PF_REMOTE;
568 			else
569 				pti->pt_flags &= ~PF_REMOTE;
570 			ttyflush(tp, FREAD|FWRITE);
571 			return (0);
572 
573 		case FIONBIO:
574 			if (*(int *)data)
575 				pti->pt_flags |= PF_NBIO;
576 			else
577 				pti->pt_flags &= ~PF_NBIO;
578 			return (0);
579 
580 		case TIOCSETP:
581 		case TIOCSETN:
582 		case TIOCSETD:
583 		case TIOCSETA:
584 		case TIOCSETAW:
585 		case TIOCSETAF:
586 		case JUNK_TIOCSETAS:
587 		case JUNK_TIOCSETAWS:
588 		case JUNK_TIOCSETAFS:
589 			while (getc(&tp->t_outq) >= 0)
590 				;
591 			break;
592 
593 		case TIOCSIG:
594 			if (*(unsigned int *)data >= NSIG)
595 				return(EINVAL);
596 			if ((tp->t_lflag&NOFLSH) == 0)
597 				ttyflush(tp, FREAD|FWRITE);
598 			pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);
599 			if ((*(unsigned int *)data == SIGINFO) &&
600 			    ((tp->t_lflag&NOKERNINFO) == 0))
601 				ttyinfo(tp);
602 			return(0);
603 		}
604 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
605 	if (error < 0)
606 		 error = ttioctl(tp, cmd, data, flag);
607 	/*
608 	 * Since we use the tty queues internally,
609 	 * pty's can't be switched to disciplines which overwrite
610 	 * the queues.  We can't tell anything about the discipline
611 	 * from here...
612 	 */
613 	if (linesw[tp->t_line].l_rint != ttyinput) {
614 		(*linesw[tp->t_line].l_close)(tp);
615 		tp->t_line = 0;
616 		(void)(*linesw[tp->t_line].l_open)(dev, tp, flag);
617 		error = ENOTTY;
618 	}
619 	if (error < 0) {
620 		if (pti->pt_flags & PF_UCNTL &&
621 		    (cmd & ~0xff) == UIOCCMD(0)) {
622 			if (cmd & 0xff) {
623 				pti->pt_ucntl = (u_char)cmd;
624 				ptcwakeup(tp, FREAD);
625 			}
626 			return (0);
627 		}
628 		error = ENOTTY;
629 	}
630 	/*
631 	 * If external processing and packet mode send ioctl packet.
632 	 */
633 	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
634 		switch(cmd) {
635 		case TIOCSETA:
636 		case TIOCSETAW:
637 		case TIOCSETAF:
638 		case JUNK_TIOCSETAS:
639 		case JUNK_TIOCSETAWS:
640 		case JUNK_TIOCSETAFS:
641 		case TIOCSETP:
642 		case TIOCSETN:
643 #ifdef	COMPAT_43
644 		case TIOCSETC:
645 		case TIOCSLTC:
646 		case TIOCLBIS:
647 		case TIOCLBIC:
648 		case TIOCLSET:
649 #endif
650 			pti->pt_send |= TIOCPKT_IOCTL;
651 		default:
652 			break;
653 		}
654 	}
655 	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
656 		&& CCEQ(cc[VSTART], CTRL('q'));
657 	if (pti->pt_flags & PF_NOSTOP) {
658 		if (stop) {
659 			pti->pt_send &= ~TIOCPKT_NOSTOP;
660 			pti->pt_send |= TIOCPKT_DOSTOP;
661 			pti->pt_flags &= ~PF_NOSTOP;
662 			ptcwakeup(tp, FREAD);
663 		}
664 	} else {
665 		if (!stop) {
666 			pti->pt_send &= ~TIOCPKT_DOSTOP;
667 			pti->pt_send |= TIOCPKT_NOSTOP;
668 			pti->pt_flags |= PF_NOSTOP;
669 			ptcwakeup(tp, FREAD);
670 		}
671 	}
672 	return (error);
673 }
674 #endif
675