xref: /dflybsd-src/sys/kern/tty_pty.c (revision a9656fbcd49c376aba5e04370d8b0f1fa96e063c)
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.4 (Berkeley) 2/20/95
34  * $FreeBSD: src/sys/kern/tty_pty.c,v 1.74.2.4 2002/02/20 19:58:13 dillon Exp $
35  * $DragonFly: src/sys/kern/tty_pty.c,v 1.21 2008/08/13 10:29:38 swildner Exp $
36  */
37 
38 /*
39  * Pseudo-teletype Driver
40  * (Actually two drivers, requiring two dev_ops structures)
41  */
42 #include "use_pty.h"		/* XXX */
43 #include "opt_compat.h"
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
48 #include <sys/ioctl_compat.h>
49 #endif
50 #include <sys/proc.h>
51 #include <sys/priv.h>
52 #include <sys/tty.h>
53 #include <sys/conf.h>
54 #include <sys/fcntl.h>
55 #include <sys/kernel.h>
56 #include <sys/vnode.h>
57 #include <sys/signalvar.h>
58 #include <sys/malloc.h>
59 #include <sys/device.h>
60 #include <sys/thread2.h>
61 #include <sys/devfs.h>
62 #include <sys/stat.h>
63 #include <sys/sysctl.h>
64 
65 #define	UNIX98_PTYS	1
66 
67 MALLOC_DEFINE(M_PTY, "ptys", "pty data structures");
68 
69 static void ptsstart (struct tty *tp);
70 static void ptsstop (struct tty *tp, int rw);
71 static void ptcwakeup (struct tty *tp, int flag);
72 static void ptyinit (int n);
73 static int  filt_ptcread (struct knote *kn, long hint);
74 static void filt_ptcrdetach (struct knote *kn);
75 static int  filt_ptcwrite (struct knote *kn, long hint);
76 static void filt_ptcwdetach (struct knote *kn);
77 
78 static	d_open_t	ptsopen;
79 static	d_close_t	ptsclose;
80 static	d_read_t	ptsread;
81 static	d_write_t	ptswrite;
82 static	d_ioctl_t	ptyioctl;
83 static	d_open_t	ptcopen;
84 static	d_close_t	ptcclose;
85 static	d_read_t	ptcread;
86 static	d_write_t	ptcwrite;
87 static	d_kqfilter_t	ptckqfilter;
88 
89 #ifdef UNIX98_PTYS
90 DEVFS_DECLARE_CLONE_BITMAP(pty);
91 
92 static	d_clone_t 	ptyclone;
93 
94 static int	pty_debug_level = 0;
95 
96 static struct dev_ops pts98_ops = {
97 	{ "pts98", 0, D_TTY | D_KQFILTER },
98 	.d_open =	ptsopen,
99 	.d_close =	ptsclose,
100 	.d_read =	ptsread,
101 	.d_write =	ptswrite,
102 	.d_ioctl =	ptyioctl,
103 	.d_kqfilter =	ttykqfilter,
104 	.d_revoke =	ttyrevoke
105 };
106 
107 static struct dev_ops ptc98_ops = {
108 	{ "ptc98", 0, D_TTY | D_KQFILTER | D_MASTER },
109 	.d_open =	ptcopen,
110 	.d_close =	ptcclose,
111 	.d_read =	ptcread,
112 	.d_write =	ptcwrite,
113 	.d_ioctl =	ptyioctl,
114 	.d_kqfilter =	ptckqfilter,
115 	.d_revoke =	ttyrevoke
116 };
117 #endif
118 
119 #define	CDEV_MAJOR_S	5
120 static struct dev_ops pts_ops = {
121 	{ "pts", CDEV_MAJOR_S, D_TTY | D_KQFILTER },
122 	.d_open =	ptsopen,
123 	.d_close =	ptsclose,
124 	.d_read =	ptsread,
125 	.d_write =	ptswrite,
126 	.d_ioctl =	ptyioctl,
127 	.d_kqfilter =	ttykqfilter,
128 	.d_revoke =	ttyrevoke
129 };
130 
131 #define	CDEV_MAJOR_C	6
132 static struct dev_ops ptc_ops = {
133 	{ "ptc", CDEV_MAJOR_C, D_TTY | D_KQFILTER | D_MASTER },
134 	.d_open =	ptcopen,
135 	.d_close =	ptcclose,
136 	.d_read =	ptcread,
137 	.d_write =	ptcwrite,
138 	.d_ioctl =	ptyioctl,
139 	.d_kqfilter =	ptckqfilter,
140 	.d_revoke =	ttyrevoke
141 };
142 
143 #define BUFSIZ 100		/* Chunk size iomoved to/from user */
144 
145 struct	pt_ioctl {
146 	int	pt_flags;
147 	int	pt_flags2;
148 	int	pt_refs;	/* Structural references interlock S/MOPEN */
149 	int	pt_uminor;
150 	struct	kqinfo pt_kqr, pt_kqw;
151 	u_char	pt_send;
152 	u_char	pt_ucntl;
153 	struct tty pt_tty;
154 	cdev_t	devs, devc;
155 	struct	prison *pt_prison;
156 };
157 
158 #define	PF_PKT		0x08		/* packet mode */
159 #define	PF_STOPPED	0x10		/* user told stopped */
160 #define	PF_REMOTE	0x20		/* remote and flow controlled input */
161 #define	PF_NOSTOP	0x40
162 #define PF_UCNTL	0x80		/* user control mode */
163 
164 #define	PF_UNIX98	0x01
165 #define	PF_SOPEN	0x02
166 #define	PF_MOPEN	0x04
167 #define PF_TERMINATED	0x08
168 
169 static int
170 ptydebug(int level, char *fmt, ...)
171 {
172 	__va_list ap;
173 
174 	__va_start(ap, fmt);
175 	if (level <= pty_debug_level)
176 		kvprintf(fmt, ap);
177 	__va_end(ap);
178 
179 	return 0;
180 }
181 
182 /*
183  * This function creates and initializes a pts/ptc pair
184  *
185  * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv]
186  * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv]
187  *
188  * XXX: define and add mapping of upper minor bits to allow more
189  *      than 256 ptys.
190  */
191 static void
192 ptyinit(int n)
193 {
194 	cdev_t devs, devc;
195 	char *names = "pqrsPQRS";
196 	struct pt_ioctl *pt;
197 
198 	/* For now we only map the lower 8 bits of the minor */
199 	if (n & ~0xff)
200 		return;
201 
202 	pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
203 	pt->devs = devs = make_dev(&pts_ops, n,
204 	    0, 0, 0666, "tty%c%r", names[n / 32], n % 32);
205 	pt->devc = devc = make_dev(&ptc_ops, n,
206 	    0, 0, 0666, "pty%c%r", names[n / 32], n % 32);
207 
208 	devs->si_drv1 = devc->si_drv1 = pt;
209 	devs->si_tty = devc->si_tty = &pt->pt_tty;
210 	devs->si_flags |= SI_OVERRIDE;	/* uid, gid, perms from dev */
211 	devc->si_flags |= SI_OVERRIDE;	/* uid, gid, perms from dev */
212 	pt->pt_tty.t_dev = devs;
213 	pt->pt_uminor = n;
214 	ttyregister(&pt->pt_tty);
215 }
216 
217 #ifdef UNIX98_PTYS
218 static int
219 ptyclone(struct dev_clone_args *ap)
220 {
221 	int unit;
222 	struct pt_ioctl *pt;
223 
224 	/*
225 	 * Limit the number of unix98 pty (slave) devices to 1000, as
226 	 * the utmp(5) format only allows for 8 bytes for the tty,
227 	 * "pts/XXX".
228 	 * If this limit is reached, we don't clone and return error
229 	 * to devfs.
230 	 */
231 	unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), 1000);
232 
233 	if (unit < 0) {
234 		ap->a_dev = NULL;
235 		return 1;
236 	}
237 
238 	pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
239 
240 	pt->devc = make_only_dev(&ptc98_ops, unit,
241 				 ap->a_cred->cr_ruid,
242 				 0, 0600, "ptm/%d", unit);
243 	pt->devs = make_dev(&pts98_ops, unit,
244 			    ap->a_cred->cr_ruid,
245 			    GID_TTY, 0620, "pts/%d", unit);
246 	ap->a_dev = pt->devc;
247 
248 	pt->devs->si_flags |= SI_OVERRIDE;	/* uid, gid, perms from dev */
249 	pt->devc->si_flags |= SI_OVERRIDE;	/* uid, gid, perms from dev */
250 
251 	pt->devs->si_drv1 = pt->devc->si_drv1 = pt;
252 	pt->devs->si_tty = pt->devc->si_tty = &pt->pt_tty;
253 	pt->pt_tty.t_dev = pt->devs;
254 	pt->pt_flags2 |= PF_UNIX98;
255 	pt->pt_uminor = unit;
256 
257 	ttyregister(&pt->pt_tty);
258 
259 	return 0;
260 }
261 #endif
262 
263 /*
264  * pti_hold() prevents the pti from being destroyed due to a termination
265  * while a pt*open() is blocked.
266  *
267  * This function returns non-zero if we cannot hold due to a termination
268  * interlock.
269  */
270 static int
271 pti_hold(struct pt_ioctl *pti)
272 {
273 	if (pti->pt_flags2 & PF_TERMINATED)
274 		return(ENXIO);
275 	++pti->pt_refs;
276 	return(0);
277 }
278 
279 /*
280  * pti_done() releases the reference and checks to see if both sides have
281  * been closed on a unix98 pty, allowing us to destroy the device and
282  * release resources.
283  *
284  * We do not release resources on non-unix98 ptys.  Those are left
285  * statically allocated.
286  */
287 static void
288 pti_done(struct pt_ioctl *pti)
289 {
290 	if (--pti->pt_refs == 0) {
291 #ifdef UNIX98_PTYS
292 		cdev_t dev;
293 		int uminor_no;
294 
295 		/*
296 		 * Only unix09 ptys are freed up
297 		 */
298 		if ((pti->pt_flags2 & PF_UNIX98) == 0)
299 			return;
300 
301 		/*
302 		 * Interlock open attempts against termination by setting
303 		 * PF_TERMINATED.  This allows us to block while cleaning
304 		 * out the device infrastructure.
305 		 */
306 		if ((pti->pt_flags2 & (PF_SOPEN|PF_MOPEN)) == 0) {
307 			pti->pt_flags2 |= PF_TERMINATED;
308 			uminor_no = pti->pt_uminor;
309 
310 			if ((dev = pti->devs) != NULL) {
311 				dev->si_drv1 = NULL;
312 				pti->devs = NULL;
313 				destroy_dev(dev);
314 			}
315 			if ((dev = pti->devc) != NULL) {
316 				dev->si_drv1 = NULL;
317 				pti->devc = NULL;
318 				destroy_dev(dev);
319 			}
320 			ttyunregister(&pti->pt_tty);
321 			devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty),
322 					       uminor_no);
323 			kfree(pti, M_PTY);
324 		}
325 #endif
326 	}
327 }
328 
329 /*ARGSUSED*/
330 static	int
331 ptsopen(struct dev_open_args *ap)
332 {
333 	cdev_t dev = ap->a_head.a_dev;
334 	struct tty *tp;
335 	int error;
336 	struct pt_ioctl *pti;
337 
338 	/*
339 	 * The pti will already be assigned by the clone code or
340 	 * pre-created if a non-unix 98 pty.  If si_drv1 is NULL
341 	 * we are somehow racing a unix98 termination.
342 	 */
343 	if (dev->si_drv1 == NULL)
344 		return(ENXIO);
345 	pti = dev->si_drv1;
346 	if (pti_hold(pti))
347 		return(ENXIO);
348 	tp = dev->si_tty;
349 	if ((tp->t_state & TS_ISOPEN) == 0) {
350 		ttychars(tp);		/* Set up default chars */
351 		tp->t_iflag = TTYDEF_IFLAG;
352 		tp->t_oflag = TTYDEF_OFLAG;
353 		tp->t_lflag = TTYDEF_LFLAG;
354 		tp->t_cflag = TTYDEF_CFLAG;
355 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
356 	} else if ((tp->t_state & TS_XCLUDE) && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
357 		pti_done(pti);
358 		return (EBUSY);
359 	} else if (pti->pt_prison != ap->a_cred->cr_prison) {
360 		pti_done(pti);
361 		return (EBUSY);
362 	}
363 	if (tp->t_oproc)			/* Ctrlr still around. */
364 		(void)(*linesw[tp->t_line].l_modem)(tp, 1);
365 	while ((tp->t_state & TS_CARR_ON) == 0) {
366 		if (ap->a_oflags & FNONBLOCK)
367 			break;
368 		error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ptsopn", 0);
369 		if (error) {
370 			pti_done(pti);
371 			return (error);
372 		}
373 	}
374 	tp->t_state &= ~TS_ZOMBIE;
375 	error = (*linesw[tp->t_line].l_open)(dev, tp);
376 	if (error == 0)
377 		ptcwakeup(tp, FREAD|FWRITE);
378 
379 #ifdef UNIX98_PTYS
380 	/*
381 	 * Unix98 pty stuff.
382 	 * On open of the slave, we set the corresponding flag in the common
383 	 * struct.
384 	 */
385 	ptydebug(1, "ptsopen=%s | unix98? %s\n", dev->si_name,
386 	    (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
387 
388 	if (error == 0 && (pti->pt_flags2 & PF_UNIX98)) {
389 		pti->pt_flags2 |= PF_SOPEN;
390 	}
391 #endif
392 	pti_done(pti);
393 
394 	return (error);
395 }
396 
397 static	int
398 ptsclose(struct dev_close_args *ap)
399 {
400 	cdev_t dev = ap->a_head.a_dev;
401 	struct tty *tp;
402 	struct pt_ioctl *pti = dev->si_drv1;
403 	int err;
404 
405 	if (pti_hold(pti))
406 		panic("ptsclose on terminated pti");
407 	tp = dev->si_tty;
408 	err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
409 	ptsstop(tp, FREAD|FWRITE);
410 	(void) ttyclose(tp); /* clears t_state */
411 	tp->t_state |= TS_ZOMBIE;
412 
413 #ifdef UNIX98_PTYS
414 	/*
415 	 * Unix98 pty stuff.
416 	 * On close of the slave, we unset the corresponding flag, and if the master
417 	 * isn't open anymore, we destroy the slave and unset the unit.
418 	 */
419 	ptydebug(1, "ptsclose=%s | unix98? %s\n", dev->si_name,
420 	    (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
421 
422 	if (pti->pt_flags2 & PF_UNIX98) {
423 		pti->pt_flags2 &= ~PF_SOPEN;
424 		KKASSERT((pti->pt_flags2 & PF_SOPEN) == 0);
425 		ptydebug(1, "master open? %s\n",
426 		    (pti->pt_flags2 & PF_MOPEN)?"yes":"no");
427 	}
428 #endif
429 	pti_done(pti);
430 	return (err);
431 }
432 
433 static	int
434 ptsread(struct dev_read_args *ap)
435 {
436 	cdev_t dev = ap->a_head.a_dev;
437 	struct proc *p = curproc;
438 	struct tty *tp = dev->si_tty;
439 	struct pt_ioctl *pti = dev->si_drv1;
440 	struct lwp *lp;
441 
442 	int error = 0;
443 
444 	lp = curthread->td_lwp;
445 
446 again:
447 	if (pti->pt_flags & PF_REMOTE) {
448 		while (isbackground(p, tp)) {
449 			if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
450 			    SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
451 			    p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT)
452 				return (EIO);
453 			pgsignal(p->p_pgrp, SIGTTIN, 1);
454 			error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0);
455 			if (error)
456 				return (error);
457 		}
458 		if (tp->t_canq.c_cc == 0) {
459 			if (ap->a_ioflag & IO_NDELAY)
460 				return (EWOULDBLOCK);
461 			error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH,
462 					 "ptsin", 0);
463 			if (error)
464 				return (error);
465 			goto again;
466 		}
467 		while (tp->t_canq.c_cc > 1 && ap->a_uio->uio_resid > 0)
468 			if (ureadc(clist_getc(&tp->t_canq), ap->a_uio) < 0) {
469 				error = EFAULT;
470 				break;
471 			}
472 		if (tp->t_canq.c_cc == 1)
473 			clist_getc(&tp->t_canq);
474 		if (tp->t_canq.c_cc)
475 			return (error);
476 	} else
477 		if (tp->t_oproc)
478 			error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
479 	ptcwakeup(tp, FWRITE);
480 	return (error);
481 }
482 
483 /*
484  * Write to pseudo-tty.
485  * Wakeups of controlling tty will happen
486  * indirectly, when tty driver calls ptsstart.
487  */
488 static	int
489 ptswrite(struct dev_write_args *ap)
490 {
491 	cdev_t dev = ap->a_head.a_dev;
492 	struct tty *tp;
493 
494 	tp = dev->si_tty;
495 	if (tp->t_oproc == 0)
496 		return (EIO);
497 	return ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
498 }
499 
500 /*
501  * Start output on pseudo-tty.
502  * Wake up process selecting or sleeping for input from controlling tty.
503  */
504 static void
505 ptsstart(struct tty *tp)
506 {
507 	struct pt_ioctl *pti = tp->t_dev->si_drv1;
508 
509 	if (tp->t_state & TS_TTSTOP)
510 		return;
511 	if (pti) {
512 		if (pti->pt_flags & PF_STOPPED) {
513 			pti->pt_flags &= ~PF_STOPPED;
514 			pti->pt_send = TIOCPKT_START;
515 		}
516 	}
517 	ptcwakeup(tp, FREAD);
518 }
519 
520 static void
521 ptcwakeup(struct tty *tp, int flag)
522 {
523 	if (flag & FREAD) {
524 		wakeup(TSA_PTC_READ(tp));
525 		KNOTE(&tp->t_rkq.ki_note, 0);
526 	}
527 	if (flag & FWRITE) {
528 		wakeup(TSA_PTC_WRITE(tp));
529 		KNOTE(&tp->t_wkq.ki_note, 0);
530 	}
531 }
532 
533 static	int
534 ptcopen(struct dev_open_args *ap)
535 {
536 	cdev_t dev = ap->a_head.a_dev;
537 	struct tty *tp;
538 	struct pt_ioctl *pti;
539 
540 	/*
541 	 * The pti will already be assigned by the clone code or
542 	 * pre-created if a non-unix 98 pty.  If si_drv1 is NULL
543 	 * we are somehow racing a unix98 termination.
544 	 */
545 	if (dev->si_drv1 == NULL)
546 		return(ENXIO);
547 	pti = dev->si_drv1;
548 	if (pti_hold(pti))
549 		return(ENXIO);
550 	if (pti->pt_prison && pti->pt_prison != ap->a_cred->cr_prison) {
551 		pti_done(pti);
552 		return(EBUSY);
553 	}
554 	tp = dev->si_tty;
555 	if (tp->t_oproc) {
556 		pti_done(pti);
557 		return (EIO);
558 	}
559 	tp->t_oproc = ptsstart;
560 	tp->t_stop = ptsstop;
561 	(void)(*linesw[tp->t_line].l_modem)(tp, 1);
562 	tp->t_lflag &= ~EXTPROC;
563 	pti->pt_prison = ap->a_cred->cr_prison;
564 	pti->pt_flags = 0;
565 	pti->pt_send = 0;
566 	pti->pt_ucntl = 0;
567 
568 	pti->devs->si_uid = ap->a_cred->cr_uid;
569 	pti->devs->si_gid = 0;
570 	pti->devs->si_perms = 0600;
571 	pti->devc->si_uid = ap->a_cred->cr_uid;
572 	pti->devc->si_gid = 0;
573 	pti->devc->si_perms = 0600;
574 
575 #ifdef UNIX98_PTYS
576 	/*
577 	 * Unix98 pty stuff.
578 	 * On open of the master, we set the corresponding flag in the common
579 	 * struct.
580 	 */
581 	ptydebug(1, "ptcopen=%s (master) | unix98? %s\n", dev->si_name,
582 	    (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
583 
584 	if (pti->pt_flags2 & PF_UNIX98) {
585 		pti->pt_flags2 |= PF_MOPEN;
586 	}
587 #endif
588 	pti_done(pti);
589 
590 	return (0);
591 }
592 
593 static	int
594 ptcclose(struct dev_close_args *ap)
595 {
596 	cdev_t dev = ap->a_head.a_dev;
597 	struct tty *tp;
598 	struct pt_ioctl *pti = dev->si_drv1;
599 
600 	if (pti_hold(pti))
601 		panic("ptcclose on terminated pti");
602 
603 	tp = dev->si_tty;
604 	(void)(*linesw[tp->t_line].l_modem)(tp, 0);
605 
606 	/*
607 	 * XXX MDMBUF makes no sense for ptys but would inhibit the above
608 	 * l_modem().  CLOCAL makes sense but isn't supported.   Special
609 	 * l_modem()s that ignore carrier drop make no sense for ptys but
610 	 * may be in use because other parts of the line discipline make
611 	 * sense for ptys.  Recover by doing everything that a normal
612 	 * ttymodem() would have done except for sending a SIGHUP.
613 	 */
614 	if (tp->t_state & TS_ISOPEN) {
615 		tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
616 		tp->t_state |= TS_ZOMBIE;
617 		ttyflush(tp, FREAD | FWRITE);
618 	}
619 	tp->t_oproc = 0;		/* mark closed */
620 
621 #ifdef UNIX98_PTYS
622 	/*
623 	 * Unix98 pty stuff.
624 	 * On close of the master, we unset the corresponding flag in the common
625 	 * struct asap.
626 	 */
627 	pti->pt_flags2 &= ~PF_MOPEN;
628 #endif
629 
630 	pti->pt_prison = NULL;
631 	pti->devs->si_uid = 0;
632 	pti->devs->si_gid = 0;
633 	pti->devs->si_perms = 0666;
634 	pti->devc->si_uid = 0;
635 	pti->devc->si_gid = 0;
636 	pti->devc->si_perms = 0666;
637 
638 	pti_done(pti);
639 	return (0);
640 }
641 
642 static	int
643 ptcread(struct dev_read_args *ap)
644 {
645 	cdev_t dev = ap->a_head.a_dev;
646 	struct tty *tp = dev->si_tty;
647 	struct pt_ioctl *pti = dev->si_drv1;
648 	char buf[BUFSIZ];
649 	int error = 0, cc;
650 
651 	/*
652 	 * We want to block until the slave
653 	 * is open, and there's something to read;
654 	 * but if we lost the slave or we're NBIO,
655 	 * then return the appropriate error instead.
656 	 */
657 	for (;;) {
658 		if (tp->t_state&TS_ISOPEN) {
659 			if (pti->pt_flags&PF_PKT && pti->pt_send) {
660 				error = ureadc((int)pti->pt_send, ap->a_uio);
661 				if (error)
662 					return (error);
663 				if (pti->pt_send & TIOCPKT_IOCTL) {
664 					cc = (int)szmin(ap->a_uio->uio_resid,
665 							sizeof(tp->t_termios));
666 					uiomove((caddr_t)&tp->t_termios, cc,
667 						ap->a_uio);
668 				}
669 				pti->pt_send = 0;
670 				return (0);
671 			}
672 			if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
673 				error = ureadc((int)pti->pt_ucntl, ap->a_uio);
674 				if (error)
675 					return (error);
676 				pti->pt_ucntl = 0;
677 				return (0);
678 			}
679 			if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
680 				break;
681 		}
682 		if ((tp->t_state & TS_CONNECTED) == 0)
683 			return (0);	/* EOF */
684 		if (ap->a_ioflag & IO_NDELAY)
685 			return (EWOULDBLOCK);
686 		error = tsleep(TSA_PTC_READ(tp), PCATCH, "ptcin", 0);
687 		if (error)
688 			return (error);
689 	}
690 	if (pti->pt_flags & (PF_PKT|PF_UCNTL))
691 		error = ureadc(0, ap->a_uio);
692 	while (ap->a_uio->uio_resid > 0 && error == 0) {
693 		cc = q_to_b(&tp->t_outq, buf,
694 			    (int)szmin(ap->a_uio->uio_resid, BUFSIZ));
695 		if (cc <= 0)
696 			break;
697 		error = uiomove(buf, (size_t)cc, ap->a_uio);
698 	}
699 	ttwwakeup(tp);
700 	return (error);
701 }
702 
703 static	void
704 ptsstop(struct tty *tp, int flush)
705 {
706 	struct pt_ioctl *pti = tp->t_dev->si_drv1;
707 	int flag;
708 
709 	/* note: FLUSHREAD and FLUSHWRITE already ok */
710 	if (pti) {
711 		if (flush == 0) {
712 			flush = TIOCPKT_STOP;
713 			pti->pt_flags |= PF_STOPPED;
714 		} else {
715 			pti->pt_flags &= ~PF_STOPPED;
716 		}
717 		pti->pt_send |= flush;
718 		/* change of perspective */
719 	}
720 	flag = 0;
721 	if (flush & FREAD)
722 		flag |= FWRITE;
723 	if (flush & FWRITE)
724 		flag |= FREAD;
725 	ptcwakeup(tp, flag);
726 }
727 
728 /*
729  * kqueue ops for pseudo-terminals.
730  */
731 static struct filterops ptcread_filtops =
732 	{ FILTEROP_ISFD, NULL, filt_ptcrdetach, filt_ptcread };
733 static struct filterops ptcwrite_filtops =
734 	{ FILTEROP_ISFD, NULL, filt_ptcwdetach, filt_ptcwrite };
735 
736 static	int
737 ptckqfilter(struct dev_kqfilter_args *ap)
738 {
739 	cdev_t dev = ap->a_head.a_dev;
740 	struct knote *kn = ap->a_kn;
741 	struct tty *tp = dev->si_tty;
742 	struct klist *klist;
743 
744 	ap->a_result = 0;
745 	switch (kn->kn_filter) {
746 	case EVFILT_READ:
747 		klist = &tp->t_rkq.ki_note;
748 		kn->kn_fop = &ptcread_filtops;
749 		break;
750 	case EVFILT_WRITE:
751 		klist = &tp->t_wkq.ki_note;
752 		kn->kn_fop = &ptcwrite_filtops;
753 		break;
754 	default:
755 		ap->a_result = EOPNOTSUPP;
756 		return (0);
757 	}
758 
759 	kn->kn_hook = (caddr_t)dev;
760 	knote_insert(klist, kn);
761 	return (0);
762 }
763 
764 static int
765 filt_ptcread (struct knote *kn, long hint)
766 {
767 	struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
768 	struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
769 
770 	if (tp->t_state & TS_ZOMBIE) {
771 		kn->kn_flags |= EV_EOF;
772 		return (1);
773 	}
774 
775 	if ((tp->t_state & TS_ISOPEN) &&
776 	    ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) ||
777 	     ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
778 	     ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) {
779 		kn->kn_data = tp->t_outq.c_cc;
780 		return(1);
781 	} else {
782 		return(0);
783 	}
784 }
785 
786 static int
787 filt_ptcwrite (struct knote *kn, long hint)
788 {
789 	struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
790 	struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
791 
792 	if (tp->t_state & TS_ZOMBIE) {
793 		kn->kn_flags |= EV_EOF;
794 		return (1);
795 	}
796 
797 	if (tp->t_state & TS_ISOPEN &&
798 	    ((pti->pt_flags & PF_REMOTE) ?
799 	     (tp->t_canq.c_cc == 0) :
800 	     ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
801 	      (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) {
802 		kn->kn_data = tp->t_canq.c_cc + tp->t_rawq.c_cc;
803 		return(1);
804 	} else {
805 		return(0);
806 	}
807 }
808 
809 static void
810 filt_ptcrdetach (struct knote *kn)
811 {
812 	struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
813 
814 	knote_remove(&tp->t_rkq.ki_note, kn);
815 }
816 
817 static void
818 filt_ptcwdetach (struct knote *kn)
819 {
820 	struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
821 
822 	knote_remove(&tp->t_wkq.ki_note, kn);
823 }
824 
825 /*
826  * I/O ops
827  */
828 static	int
829 ptcwrite(struct dev_write_args *ap)
830 {
831 	cdev_t dev = ap->a_head.a_dev;
832 	struct tty *tp = dev->si_tty;
833 	u_char *cp = 0;
834 	int cc = 0;
835 	u_char locbuf[BUFSIZ];
836 	int cnt = 0;
837 	struct pt_ioctl *pti = dev->si_drv1;
838 	int error = 0;
839 
840 again:
841 	if ((tp->t_state&TS_ISOPEN) == 0)
842 		goto block;
843 	if (pti->pt_flags & PF_REMOTE) {
844 		if (tp->t_canq.c_cc)
845 			goto block;
846 		while ((ap->a_uio->uio_resid > 0 || cc > 0) &&
847 		       tp->t_canq.c_cc < TTYHOG - 1) {
848 			if (cc == 0) {
849 				cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
850 				cc = imin(cc, TTYHOG - 1 - tp->t_canq.c_cc);
851 				cp = locbuf;
852 				error = uiomove(cp, (size_t)cc, ap->a_uio);
853 				if (error)
854 					return (error);
855 				/* check again for safety */
856 				if ((tp->t_state & TS_ISOPEN) == 0) {
857 					/* adjust as usual */
858 					ap->a_uio->uio_resid += cc;
859 					return (EIO);
860 				}
861 			}
862 			if (cc > 0) {
863 				cc = b_to_q((char *)cp, cc, &tp->t_canq);
864 				/*
865 				 * XXX we don't guarantee that the canq size
866 				 * is >= TTYHOG, so the above b_to_q() may
867 				 * leave some bytes uncopied.  However, space
868 				 * is guaranteed for the null terminator if
869 				 * we don't fail here since (TTYHOG - 1) is
870 				 * not a multiple of CBSIZE.
871 				 */
872 				if (cc > 0)
873 					break;
874 			}
875 		}
876 		/* adjust for data copied in but not written */
877 		ap->a_uio->uio_resid += cc;
878 		clist_putc(0, &tp->t_canq);
879 		ttwakeup(tp);
880 		wakeup(TSA_PTS_READ(tp));
881 		return (0);
882 	}
883 	while (ap->a_uio->uio_resid > 0 || cc > 0) {
884 		if (cc == 0) {
885 			cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
886 			cp = locbuf;
887 			error = uiomove(cp, (size_t)cc, ap->a_uio);
888 			if (error)
889 				return (error);
890 			/* check again for safety */
891 			if ((tp->t_state & TS_ISOPEN) == 0) {
892 				/* adjust for data copied in but not written */
893 				ap->a_uio->uio_resid += cc;
894 				return (EIO);
895 			}
896 		}
897 		while (cc > 0) {
898 			if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
899 			   (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
900 				wakeup(TSA_HUP_OR_INPUT(tp));
901 				goto block;
902 			}
903 			(*linesw[tp->t_line].l_rint)(*cp++, tp);
904 			cnt++;
905 			cc--;
906 		}
907 		cc = 0;
908 	}
909 	return (0);
910 block:
911 	/*
912 	 * Come here to wait for slave to open, for space
913 	 * in outq, or space in rawq, or an empty canq.
914 	 */
915 	if ((tp->t_state & TS_CONNECTED) == 0) {
916 		/* adjust for data copied in but not written */
917 		ap->a_uio->uio_resid += cc;
918 		return (EIO);
919 	}
920 	if (ap->a_ioflag & IO_NDELAY) {
921 		/* adjust for data copied in but not written */
922 		ap->a_uio->uio_resid += cc;
923 		if (cnt == 0)
924 			return (EWOULDBLOCK);
925 		return (0);
926 	}
927 	error = tsleep(TSA_PTC_WRITE(tp), PCATCH, "ptcout", 0);
928 	if (error) {
929 		/* adjust for data copied in but not written */
930 		ap->a_uio->uio_resid += cc;
931 		return (error);
932 	}
933 	goto again;
934 }
935 
936 /*ARGSUSED*/
937 static	int
938 ptyioctl(struct dev_ioctl_args *ap)
939 {
940 	cdev_t dev = ap->a_head.a_dev;
941 	struct tty *tp = dev->si_tty;
942 	struct pt_ioctl *pti = dev->si_drv1;
943 	u_char *cc = tp->t_cc;
944 	int stop, error;
945 
946 	if (dev_dflags(dev) & D_MASTER) {
947 		switch (ap->a_cmd) {
948 
949 		case TIOCGPGRP:
950 			/*
951 			 * We avoid calling ttioctl on the controller since,
952 			 * in that case, tp must be the controlling terminal.
953 			 */
954 			*(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
955 			return (0);
956 
957 		case TIOCPKT:
958 			if (*(int *)ap->a_data) {
959 				if (pti->pt_flags & PF_UCNTL)
960 					return (EINVAL);
961 				pti->pt_flags |= PF_PKT;
962 			} else
963 				pti->pt_flags &= ~PF_PKT;
964 			return (0);
965 
966 		case TIOCUCNTL:
967 			if (*(int *)ap->a_data) {
968 				if (pti->pt_flags & PF_PKT)
969 					return (EINVAL);
970 				pti->pt_flags |= PF_UCNTL;
971 			} else
972 				pti->pt_flags &= ~PF_UCNTL;
973 			return (0);
974 
975 		case TIOCREMOTE:
976 			if (*(int *)ap->a_data)
977 				pti->pt_flags |= PF_REMOTE;
978 			else
979 				pti->pt_flags &= ~PF_REMOTE;
980 			ttyflush(tp, FREAD|FWRITE);
981 			return (0);
982 
983 		case TIOCISPTMASTER:
984 			if ((pti->pt_flags2 & PF_UNIX98) && (pti->devc == dev))
985 				return (0);
986 			else
987 				return (EINVAL);
988 		}
989 
990 		/*
991 		 * The rest of the ioctls shouldn't be called until
992 		 * the slave is open.
993 		 */
994 		if ((tp->t_state & TS_ISOPEN) == 0)
995 			return (EAGAIN);
996 
997 		switch (ap->a_cmd) {
998 #ifdef COMPAT_43
999 		case TIOCSETP:
1000 		case TIOCSETN:
1001 #endif
1002 		case TIOCSETD:
1003 		case TIOCSETA:
1004 		case TIOCSETAW:
1005 		case TIOCSETAF:
1006 			/*
1007 			 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
1008 			 * ttywflush(tp) will hang if there are characters in
1009 			 * the outq.
1010 			 */
1011 			ndflush(&tp->t_outq, tp->t_outq.c_cc);
1012 			break;
1013 
1014 		case TIOCSIG:
1015 			if (*(unsigned int *)ap->a_data >= NSIG ||
1016 			    *(unsigned int *)ap->a_data == 0)
1017 				return(EINVAL);
1018 			if ((tp->t_lflag&NOFLSH) == 0)
1019 				ttyflush(tp, FREAD|FWRITE);
1020 			pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1);
1021 			if ((*(unsigned int *)ap->a_data == SIGINFO) &&
1022 			    ((tp->t_lflag&NOKERNINFO) == 0))
1023 				ttyinfo(tp);
1024 			return(0);
1025 		}
1026 	}
1027 	if (ap->a_cmd == TIOCEXT) {
1028 		/*
1029 		 * When the EXTPROC bit is being toggled, we need
1030 		 * to send an TIOCPKT_IOCTL if the packet driver
1031 		 * is turned on.
1032 		 */
1033 		if (*(int *)ap->a_data) {
1034 			if (pti->pt_flags & PF_PKT) {
1035 				pti->pt_send |= TIOCPKT_IOCTL;
1036 				ptcwakeup(tp, FREAD);
1037 			}
1038 			tp->t_lflag |= EXTPROC;
1039 		} else {
1040 			if ((tp->t_lflag & EXTPROC) &&
1041 			    (pti->pt_flags & PF_PKT)) {
1042 				pti->pt_send |= TIOCPKT_IOCTL;
1043 				ptcwakeup(tp, FREAD);
1044 			}
1045 			tp->t_lflag &= ~EXTPROC;
1046 		}
1047 		return(0);
1048 	}
1049 	error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
1050 					      ap->a_fflag, ap->a_cred);
1051 	if (error == ENOIOCTL)
1052 		 error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
1053 	if (error == ENOIOCTL) {
1054 		if (pti->pt_flags & PF_UCNTL &&
1055 		    (ap->a_cmd & ~0xff) == UIOCCMD(0)) {
1056 			if (ap->a_cmd & 0xff) {
1057 				pti->pt_ucntl = (u_char)ap->a_cmd;
1058 				ptcwakeup(tp, FREAD);
1059 			}
1060 			return (0);
1061 		}
1062 		error = ENOTTY;
1063 	}
1064 	/*
1065 	 * If external processing and packet mode send ioctl packet.
1066 	 */
1067 	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
1068 		switch(ap->a_cmd) {
1069 		case TIOCSETA:
1070 		case TIOCSETAW:
1071 		case TIOCSETAF:
1072 #ifdef COMPAT_43
1073 		case TIOCSETP:
1074 		case TIOCSETN:
1075 #endif
1076 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1077 		case TIOCSETC:
1078 		case TIOCSLTC:
1079 		case TIOCLBIS:
1080 		case TIOCLBIC:
1081 		case TIOCLSET:
1082 #endif
1083 			pti->pt_send |= TIOCPKT_IOCTL;
1084 			ptcwakeup(tp, FREAD);
1085 		default:
1086 			break;
1087 		}
1088 	}
1089 	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1090 		&& CCEQ(cc[VSTART], CTRL('q'));
1091 	if (pti->pt_flags & PF_NOSTOP) {
1092 		if (stop) {
1093 			pti->pt_send &= ~TIOCPKT_NOSTOP;
1094 			pti->pt_send |= TIOCPKT_DOSTOP;
1095 			pti->pt_flags &= ~PF_NOSTOP;
1096 			ptcwakeup(tp, FREAD);
1097 		}
1098 	} else {
1099 		if (!stop) {
1100 			pti->pt_send &= ~TIOCPKT_DOSTOP;
1101 			pti->pt_send |= TIOCPKT_NOSTOP;
1102 			pti->pt_flags |= PF_NOSTOP;
1103 			ptcwakeup(tp, FREAD);
1104 		}
1105 	}
1106 	return (error);
1107 }
1108 
1109 
1110 static void ptc_drvinit (void *unused);
1111 
1112 #ifdef UNIX98_PTYS
1113 SYSCTL_INT(_kern, OID_AUTO, pty_debug, CTLFLAG_RW, &pty_debug_level,
1114 		0, "Change pty debug level");
1115 #endif
1116 
1117 static void
1118 ptc_drvinit(void *unused)
1119 {
1120 	int i;
1121 
1122 #ifdef UNIX98_PTYS
1123 	/*
1124 	 * Unix98 pty stuff.
1125 	 * Create the clonable base device.
1126 	 */
1127 	make_autoclone_dev(&ptc_ops, &DEVFS_CLONE_BITMAP(pty), ptyclone,
1128 	    0, 0, 0666, "ptmx");
1129 #endif
1130 
1131 	for (i = 0; i < 256; i++) {
1132 		ptyinit(i);
1133 	}
1134 }
1135 
1136 SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL)
1137