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