pty.c revision 9626
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.13 1995/07/21 20:52:40 bde 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#include <sys/signalvar.h>
54
55#if NPTY == 1
56#undef NPTY
57#define	NPTY	32		/* crude XXX */
58#endif
59
60#define BUFSIZ 100		/* Chunk size iomoved to/from user */
61
62/*
63 * pts == /dev/tty[pqrs]?
64 * ptc == /dev/pty[pqrs]?
65 */
66struct	tty pt_tty[NPTY];	/* XXX */
67struct	pt_ioctl {
68	int	pt_flags;
69	struct	selinfo pt_selr, pt_selw;
70	u_char	pt_send;
71	u_char	pt_ucntl;
72} pt_ioctl[NPTY];		/* XXX */
73int	npty = NPTY;		/* for pstat -t */
74
75#define	PF_PKT		0x08		/* packet mode */
76#define	PF_STOPPED	0x10		/* user told stopped */
77#define	PF_REMOTE	0x20		/* remote and flow controlled input */
78#define	PF_NOSTOP	0x40
79#define PF_UCNTL	0x80		/* user control mode */
80
81void	ptsstop		__P((struct tty *, int));
82void	ptcwakeup	__P((struct tty *, int));
83
84/*
85 * Establish n (or default if n is 1) ptys in the system.
86 *
87 * XXX cdevsw & pstat require the array `pty[]' to be an array
88 */
89void
90ptyattach(n)
91	int n;
92{
93#ifdef notyet
94	char *mem;
95	register u_long ntb;
96#define	DEFAULT_NPTY	32
97
98	/* maybe should allow 0 => none? */
99	if (n <= 1)
100		n = DEFAULT_NPTY;
101	ntb = n * sizeof(struct tty);
102	mem = malloc(ntb + ALIGNBYTES + n * sizeof(struct pt_ioctl),
103	    M_DEVBUF, M_WAITOK);
104	pt_tty = (struct tty *)mem;
105	mem = (char *)ALIGN(mem + ntb);
106	pt_ioctl = (struct pt_ioctl *)mem;
107	npty = n;
108#endif
109}
110
111/*ARGSUSED*/
112int
113ptsopen(dev, flag, devtype, p)
114	dev_t dev;
115	int flag, devtype;
116	struct proc *p;
117{
118	register struct tty *tp;
119	int error;
120
121	if (minor(dev) >= npty)
122		return (ENXIO);
123	tp = &pt_tty[minor(dev)];
124	if ((tp->t_state & TS_ISOPEN) == 0) {
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		if (flag&FNONBLOCK)
138			break;
139		error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
140				 "ptsopn", 0);
141		if (error)
142			return (error);
143	}
144	error = (*linesw[tp->t_line].l_open)(dev, tp);
145	if (error == 0)
146		ptcwakeup(tp, FREAD|FWRITE);
147	return (error);
148}
149
150int
151ptsclose(dev, flag, mode, p)
152	dev_t dev;
153	int flag, mode;
154	struct proc *p;
155{
156	register struct tty *tp;
157	int err;
158
159	tp = &pt_tty[minor(dev)];
160	err = (*linesw[tp->t_line].l_close)(tp, flag);
161	ptsstop(tp, FREAD|FWRITE);
162	(void) ttyclose(tp);
163	return (err);
164}
165
166int
167ptsread(dev, uio, flag)
168	dev_t dev;
169	struct uio *uio;
170	int flag;
171{
172	struct proc *p = curproc;
173	register struct tty *tp = &pt_tty[minor(dev)];
174	register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
175	int error = 0;
176
177again:
178	if (pti->pt_flags & PF_REMOTE) {
179		while (isbackground(p, tp)) {
180			if ((p->p_sigignore & sigmask(SIGTTIN)) ||
181			    (p->p_sigmask & sigmask(SIGTTIN)) ||
182			    p->p_pgrp->pg_jobc == 0 ||
183			    p->p_flag & P_PPWAIT)
184				return (EIO);
185			pgsignal(p->p_pgrp, SIGTTIN, 1);
186			error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ptsbg",
187					 0);
188			if (error)
189				return (error);
190		}
191		if (tp->t_canq.c_cc == 0) {
192			if (flag & IO_NDELAY)
193				return (EWOULDBLOCK);
194			error = ttysleep(tp, &tp->t_canq, TTIPRI | PCATCH,
195					 "ptsin", 0);
196			if (error)
197				return (error);
198			goto again;
199		}
200		while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
201			if (ureadc(getc(&tp->t_canq), uio) < 0) {
202				error = EFAULT;
203				break;
204			}
205		if (tp->t_canq.c_cc == 1)
206			(void) getc(&tp->t_canq);
207		if (tp->t_canq.c_cc)
208			return (error);
209	} else
210		if (tp->t_oproc)
211			error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
212	ptcwakeup(tp, FWRITE);
213	return (error);
214}
215
216/*
217 * Write to pseudo-tty.
218 * Wakeups of controlling tty will happen
219 * indirectly, when tty driver calls ptsstart.
220 */
221int
222ptswrite(dev, uio, flag)
223	dev_t dev;
224	struct uio *uio;
225	int flag;
226{
227	register struct tty *tp;
228
229	tp = &pt_tty[minor(dev)];
230	if (tp->t_oproc == 0)
231		return (EIO);
232	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
233}
234
235/*
236 * Start output on pseudo-tty.
237 * Wake up process selecting or sleeping for input from controlling tty.
238 */
239void
240ptsstart(tp)
241	struct tty *tp;
242{
243	register struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
244
245	if (tp->t_state & TS_TTSTOP)
246		return;
247	if (pti->pt_flags & PF_STOPPED) {
248		pti->pt_flags &= ~PF_STOPPED;
249		pti->pt_send = TIOCPKT_START;
250	}
251	ptcwakeup(tp, FREAD);
252}
253
254void
255ptcwakeup(tp, flag)
256	struct tty *tp;
257	int flag;
258{
259	struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
260
261	if (flag & FREAD) {
262		selwakeup(&pti->pt_selr);
263		wakeup((caddr_t)&tp->t_outq.c_cf);
264	}
265	if (flag & FWRITE) {
266		selwakeup(&pti->pt_selw);
267		wakeup((caddr_t)&tp->t_rawq.c_cl);
268	}
269}
270
271/*ARGSUSED*/
272#ifdef __STDC__
273int
274ptcopen(dev_t dev, int flag, int devtype, struct proc *p)
275#else
276int
277ptcopen(dev, flag, devtype, p)
278	dev_t dev;
279	int flag, devtype;
280	struct proc *p;
281#endif
282{
283	register struct tty *tp;
284	struct pt_ioctl *pti;
285
286	if (minor(dev) >= npty)
287		return (ENXIO);
288	tp = &pt_tty[minor(dev)];
289	if (tp->t_oproc)
290		return (EIO);
291	tp->t_oproc = ptsstart;
292#ifdef sun4c
293	tp->t_stop = ptsstop;
294#endif
295	(void)(*linesw[tp->t_line].l_modem)(tp, 1);
296	tp->t_lflag &= ~EXTPROC;
297	pti = &pt_ioctl[minor(dev)];
298	pti->pt_flags = 0;
299	pti->pt_send = 0;
300	pti->pt_ucntl = 0;
301	return (0);
302}
303
304int
305ptcclose(dev)
306	dev_t dev;
307{
308	register struct tty *tp;
309
310	tp = &pt_tty[minor(dev)];
311	(void)(*linesw[tp->t_line].l_modem)(tp, 0);
312	tp->t_state &= ~TS_CARR_ON;
313	tp->t_oproc = 0;		/* mark closed */
314	tp->t_session = 0;
315	return (0);
316}
317
318int
319ptcread(dev, uio, flag)
320	dev_t dev;
321	struct uio *uio;
322	int flag;
323{
324	register struct tty *tp = &pt_tty[minor(dev)];
325	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
326	char buf[BUFSIZ];
327	int error = 0, cc;
328
329	/*
330	 * We want to block until the slave
331	 * is open, and there's something to read;
332	 * but if we lost the slave or we're NBIO,
333	 * then return the appropriate error instead.
334	 */
335	for (;;) {
336		if (tp->t_state&TS_ISOPEN) {
337			if (pti->pt_flags&PF_PKT && pti->pt_send) {
338				error = ureadc((int)pti->pt_send, uio);
339				if (error)
340					return (error);
341				if (pti->pt_send & TIOCPKT_IOCTL) {
342					cc = min(uio->uio_resid,
343						sizeof(tp->t_termios));
344					uiomove((caddr_t)&tp->t_termios, cc,
345						uio);
346				}
347				pti->pt_send = 0;
348				return (0);
349			}
350			if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
351				error = ureadc((int)pti->pt_ucntl, uio);
352				if (error)
353					return (error);
354				pti->pt_ucntl = 0;
355				return (0);
356			}
357			if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
358				break;
359		}
360		if ((tp->t_state&TS_CARR_ON) == 0)
361			return (0);	/* EOF */
362		if (flag & IO_NDELAY)
363			return (EWOULDBLOCK);
364		error = tsleep(&tp->t_outq.c_cf, TTIPRI | PCATCH, "ptcin", 0);
365		if (error)
366			return (error);
367	}
368	if (pti->pt_flags & (PF_PKT|PF_UCNTL))
369		error = ureadc(0, uio);
370	while (uio->uio_resid > 0 && error == 0) {
371		cc = q_to_b(&tp->t_outq, buf, min(uio->uio_resid, BUFSIZ));
372		if (cc <= 0)
373			break;
374		error = uiomove(buf, cc, uio);
375	}
376	ttwwakeup(tp);
377	return (error);
378}
379
380void
381ptsstop(tp, flush)
382	register struct tty *tp;
383	int flush;
384{
385	struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
386	int flag;
387
388	/* note: FLUSHREAD and FLUSHWRITE already ok */
389	if (flush == 0) {
390		flush = TIOCPKT_STOP;
391		pti->pt_flags |= PF_STOPPED;
392	} else
393		pti->pt_flags &= ~PF_STOPPED;
394	pti->pt_send |= flush;
395	/* change of perspective */
396	flag = 0;
397	if (flush & FREAD)
398		flag |= FWRITE;
399	if (flush & FWRITE)
400		flag |= FREAD;
401	ptcwakeup(tp, flag);
402}
403
404int
405ptcselect(dev, rw, p)
406	dev_t dev;
407	int rw;
408	struct proc *p;
409{
410	register struct tty *tp = &pt_tty[minor(dev)];
411	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
412	int s;
413
414	if ((tp->t_state&TS_CARR_ON) == 0)
415		return (1);
416	switch (rw) {
417
418	case FREAD:
419		/*
420		 * Need to block timeouts (ttrstart).
421		 */
422		s = spltty();
423		if ((tp->t_state&TS_ISOPEN) &&
424		     tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
425			splx(s);
426			return (1);
427		}
428		splx(s);
429		/* FALLTHROUGH */
430
431	case 0:					/* exceptional */
432		if ((tp->t_state&TS_ISOPEN) &&
433		    ((pti->pt_flags&PF_PKT && pti->pt_send) ||
434		     (pti->pt_flags&PF_UCNTL && pti->pt_ucntl)))
435			return (1);
436		selrecord(p, &pti->pt_selr);
437		break;
438
439
440	case FWRITE:
441		if (tp->t_state&TS_ISOPEN) {
442			if (pti->pt_flags & PF_REMOTE) {
443			    if (tp->t_canq.c_cc == 0)
444				return (1);
445			} else {
446			    if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2)
447				    return (1);
448			    if (tp->t_canq.c_cc == 0 && (tp->t_iflag&ICANON))
449				    return (1);
450			}
451		}
452		selrecord(p, &pti->pt_selw);
453		break;
454
455	}
456	return (0);
457}
458
459int
460ptcwrite(dev, uio, flag)
461	dev_t dev;
462	register struct uio *uio;
463	int flag;
464{
465	register struct tty *tp = &pt_tty[minor(dev)];
466	register u_char *cp = 0;
467	register int cc = 0;
468	u_char locbuf[BUFSIZ];
469	int cnt = 0;
470	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
471	int error = 0;
472
473again:
474	if ((tp->t_state&TS_ISOPEN) == 0)
475		goto block;
476	if (pti->pt_flags & PF_REMOTE) {
477		if (tp->t_canq.c_cc)
478			goto block;
479		while (uio->uio_resid > 0 && tp->t_canq.c_cc < TTYHOG - 1) {
480			if (cc == 0) {
481				cc = min(uio->uio_resid, BUFSIZ);
482				cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
483				cp = locbuf;
484				error = uiomove((caddr_t)cp, cc, uio);
485				if (error)
486					return (error);
487				/* check again for safety */
488				if ((tp->t_state&TS_ISOPEN) == 0)
489					return (EIO);
490			}
491			if (cc)
492				(void) b_to_q((char *)cp, cc, &tp->t_canq);
493			cc = 0;
494		}
495		(void) putc(0, &tp->t_canq);
496		ttwakeup(tp);
497		wakeup((caddr_t)&tp->t_canq);
498		return (0);
499	}
500	while (uio->uio_resid > 0) {
501		if (cc == 0) {
502			cc = min(uio->uio_resid, BUFSIZ);
503			cp = locbuf;
504			error = uiomove((caddr_t)cp, cc, uio);
505			if (error)
506				return (error);
507			/* check again for safety */
508			if ((tp->t_state&TS_ISOPEN) == 0)
509				return (EIO);
510		}
511		while (cc > 0) {
512			if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
513			   (tp->t_canq.c_cc > 0 || !(tp->t_iflag&ICANON))) {
514				wakeup((caddr_t)&tp->t_rawq);
515				goto block;
516			}
517			(*linesw[tp->t_line].l_rint)(*cp++, tp);
518			cnt++;
519			cc--;
520		}
521		cc = 0;
522	}
523	return (0);
524block:
525	/*
526	 * Come here to wait for slave to open, for space
527	 * in outq, or space in rawq.
528	 */
529	if ((tp->t_state&TS_CARR_ON) == 0)
530		return (EIO);
531	if (flag & IO_NDELAY) {
532		/* adjust for data copied in but not written */
533		uio->uio_resid += cc;
534		if (cnt == 0)
535			return (EWOULDBLOCK);
536		return (0);
537	}
538	error = tsleep(&tp->t_rawq.c_cl, TTOPRI | PCATCH, "ptcout", 0);
539	if (error) {
540		/* adjust for data copied in but not written */
541		uio->uio_resid += cc;
542		return (error);
543	}
544	goto again;
545}
546
547struct tty *
548ptydevtotty(dev)
549	dev_t		dev;
550{
551	if (minor(dev) >= npty)
552		return (NULL);
553
554	return &pt_tty[minor(dev)];
555}
556
557/*ARGSUSED*/
558int
559ptyioctl(dev, cmd, data, flag, p)
560	dev_t dev;
561	int cmd;
562	caddr_t data;
563	int flag;
564	struct proc *p;
565{
566	register struct tty *tp = &pt_tty[minor(dev)];
567	register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
568	register u_char *cc = tp->t_cc;
569	int stop, error;
570
571	/*
572	 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
573	 * ttywflush(tp) will hang if there are characters in the outq.
574	 */
575	if (cmd == TIOCEXT) {
576		/*
577		 * When the EXTPROC bit is being toggled, we need
578		 * to send an TIOCPKT_IOCTL if the packet driver
579		 * is turned on.
580		 */
581		if (*(int *)data) {
582			if (pti->pt_flags & PF_PKT) {
583				pti->pt_send |= TIOCPKT_IOCTL;
584				ptcwakeup(tp, FREAD);
585			}
586			tp->t_lflag |= EXTPROC;
587		} else {
588			if ((tp->t_state & EXTPROC) &&
589			    (pti->pt_flags & PF_PKT)) {
590				pti->pt_send |= TIOCPKT_IOCTL;
591				ptcwakeup(tp, FREAD);
592			}
593			tp->t_lflag &= ~EXTPROC;
594		}
595		return(0);
596	} else
597	if (cdevsw[major(dev)].d_open == ptcopen)
598		switch (cmd) {
599
600		case TIOCGPGRP:
601			/*
602			 * We aviod calling ttioctl on the controller since,
603			 * in that case, tp must be the controlling terminal.
604			 */
605			*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
606			return (0);
607
608		case TIOCPKT:
609			if (*(int *)data) {
610				if (pti->pt_flags & PF_UCNTL)
611					return (EINVAL);
612				pti->pt_flags |= PF_PKT;
613			} else
614				pti->pt_flags &= ~PF_PKT;
615			return (0);
616
617		case TIOCUCNTL:
618			if (*(int *)data) {
619				if (pti->pt_flags & PF_PKT)
620					return (EINVAL);
621				pti->pt_flags |= PF_UCNTL;
622			} else
623				pti->pt_flags &= ~PF_UCNTL;
624			return (0);
625
626		case TIOCREMOTE:
627			if (*(int *)data)
628				pti->pt_flags |= PF_REMOTE;
629			else
630				pti->pt_flags &= ~PF_REMOTE;
631			ttyflush(tp, FREAD|FWRITE);
632			return (0);
633
634#ifdef COMPAT_43
635		case TIOCSETP:
636		case TIOCSETN:
637#endif
638		case TIOCSETD:
639		case TIOCSETA:
640		case TIOCSETAW:
641		case TIOCSETAF:
642			ndflush(&tp->t_outq, tp->t_outq.c_cc);
643			break;
644
645		case TIOCSIG:
646			if (*(unsigned int *)data >= NSIG)
647				return(EINVAL);
648			if ((tp->t_lflag&NOFLSH) == 0)
649				ttyflush(tp, FREAD|FWRITE);
650			pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);
651			if ((*(unsigned int *)data == SIGINFO) &&
652			    ((tp->t_lflag&NOKERNINFO) == 0))
653				ttyinfo(tp);
654			return(0);
655		}
656	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
657	if (error < 0)
658		 error = ttioctl(tp, cmd, data, flag);
659	if (error < 0) {
660		if (pti->pt_flags & PF_UCNTL &&
661		    (cmd & ~0xff) == UIOCCMD(0)) {
662			if (cmd & 0xff) {
663				pti->pt_ucntl = (u_char)cmd;
664				ptcwakeup(tp, FREAD);
665			}
666			return (0);
667		}
668		error = ENOTTY;
669	}
670	/*
671	 * If external processing and packet mode send ioctl packet.
672	 */
673	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
674		switch(cmd) {
675		case TIOCSETA:
676		case TIOCSETAW:
677		case TIOCSETAF:
678#ifdef COMPAT_43
679		case TIOCSETP:
680		case TIOCSETN:
681#endif
682#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
683		case TIOCSETC:
684		case TIOCSLTC:
685		case TIOCLBIS:
686		case TIOCLBIC:
687		case TIOCLSET:
688#endif
689			pti->pt_send |= TIOCPKT_IOCTL;
690			ptcwakeup(tp, FREAD);
691		default:
692			break;
693		}
694	}
695	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
696		&& CCEQ(cc[VSTART], CTRL('q'));
697	if (pti->pt_flags & PF_NOSTOP) {
698		if (stop) {
699			pti->pt_send &= ~TIOCPKT_NOSTOP;
700			pti->pt_send |= TIOCPKT_DOSTOP;
701			pti->pt_flags &= ~PF_NOSTOP;
702			ptcwakeup(tp, FREAD);
703		}
704	} else {
705		if (!stop) {
706			pti->pt_send &= ~TIOCPKT_DOSTOP;
707			pti->pt_send |= TIOCPKT_NOSTOP;
708			pti->pt_flags |= PF_NOSTOP;
709			ptcwakeup(tp, FREAD);
710		}
711	}
712	return (error);
713}
714