xref: /openbsd-src/sys/kern/tty_pty.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /*	$OpenBSD: tty_pty.c,v 1.78 2016/05/24 16:09:07 deraadt Exp $	*/
2 /*	$NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $	*/
3 
4 /*
5  * Copyright (c) 1982, 1986, 1989, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	@(#)tty_pty.c	8.4 (Berkeley) 2/20/95
33  */
34 
35 /*
36  * Pseudo-teletype Driver
37  * (Actually two drivers, requiring two entries in 'cdevsw')
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/namei.h>
43 #include <sys/mount.h>
44 #include <sys/ioctl.h>
45 #include <sys/proc.h>
46 #include <sys/tty.h>
47 #include <sys/file.h>
48 #include <sys/filedesc.h>
49 #include <sys/uio.h>
50 #include <sys/kernel.h>
51 #include <sys/malloc.h>
52 #include <sys/vnode.h>
53 #include <sys/signalvar.h>
54 #include <sys/conf.h>
55 #include <sys/stat.h>
56 #include <sys/sysctl.h>
57 #include <sys/poll.h>
58 #include <sys/pledge.h>
59 #include <sys/rwlock.h>
60 
61 #define BUFSIZ 100		/* Chunk size iomoved to/from user */
62 
63 /*
64  * pts == /dev/tty[p-zP-T][0-9a-zA-Z]
65  * ptc == /dev/pty[p-zP-T][0-9a-zA-Z]
66  */
67 
68 /* XXX this needs to come from somewhere sane, and work with MAKEDEV */
69 #define TTY_LETTERS "pqrstuvwxyzPQRST"
70 #define TTY_SUFFIX "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
71 
72 static int pts_major;
73 
74 struct	pt_softc {
75 	struct	tty *pt_tty;
76 	int	pt_flags;
77 	struct	selinfo pt_selr, pt_selw;
78 	u_char	pt_send;
79 	u_char	pt_ucntl;
80 	char	pty_pn[11];
81 	char	pty_sn[11];
82 };
83 
84 #define	NPTY_MIN		8	/* number of initial ptys */
85 #define NPTY_MAX		992	/* maximum number of ptys supported */
86 
87 static struct pt_softc **pt_softc = NULL;	/* pty array */
88 static int npty = 0;				/* size of pty array */
89 static int maxptys = NPTY_MAX;			/* maximum number of ptys */
90 /* for pty array */
91 struct rwlock pt_softc_lock = RWLOCK_INITIALIZER("ptarrlk");
92 
93 #define	PF_PKT		0x08		/* packet mode */
94 #define	PF_STOPPED	0x10		/* user told stopped */
95 #define	PF_REMOTE	0x20		/* remote and flow controlled input */
96 #define	PF_NOSTOP	0x40
97 #define PF_UCNTL	0x80		/* user control mode */
98 
99 void	ptyattach(int);
100 void	ptcwakeup(struct tty *, int);
101 struct tty *ptytty(dev_t);
102 void	ptsstart(struct tty *);
103 int	sysctl_pty(int *, u_int, void *, size_t *, void *, size_t);
104 
105 void	filt_ptcrdetach(struct knote *);
106 int	filt_ptcread(struct knote *, long);
107 void	filt_ptcwdetach(struct knote *);
108 int	filt_ptcwrite(struct knote *, long);
109 
110 static struct pt_softc **ptyarralloc(int);
111 static int check_pty(int);
112 
113 static gid_t tty_gid = TTY_GID;
114 
115 void	ptydevname(int, struct pt_softc *);
116 dev_t	pty_getfree(void);
117 
118 void	ptmattach(int);
119 int	ptmopen(dev_t, int, int, struct proc *);
120 int	ptmclose(dev_t, int, int, struct proc *);
121 int	ptmioctl(dev_t, u_long, caddr_t, int, struct proc *p);
122 static int ptm_vn_open(struct nameidata *);
123 
124 void
125 ptydevname(int minor, struct pt_softc *pti)
126 {
127 	char buf[11] = "/dev/XtyXX";
128 	int i, j;
129 
130 	i = minor / (sizeof(TTY_SUFFIX) - 1);
131 	j = minor % (sizeof(TTY_SUFFIX) - 1);
132 	if (i >= sizeof(TTY_LETTERS) - 1) {
133 		pti->pty_pn[0] = '\0';
134 		pti->pty_sn[0] = '\0';
135 		return;
136 	}
137 	buf[5] = 'p';
138 	buf[8] = TTY_LETTERS[i];
139 	buf[9] = TTY_SUFFIX[j];
140 	memcpy(pti->pty_pn, buf, sizeof(buf));
141 	buf[5] = 't';
142 	memcpy(pti->pty_sn, buf, sizeof(buf));
143 }
144 
145 /*
146  * Allocate and zero array of nelem elements.
147  */
148 struct pt_softc **
149 ptyarralloc(int nelem)
150 {
151 	struct pt_softc **pt;
152 
153 	pt = mallocarray(nelem, sizeof(struct pt_softc *), M_DEVBUF,
154 	    M_WAITOK|M_ZERO);
155 	return pt;
156 }
157 
158 /*
159  * Check if the minor is correct and ensure necessary structures
160  * are properly allocated.
161  */
162 int
163 check_pty(int minor)
164 {
165 	struct pt_softc *pti;
166 
167 	rw_enter_write(&pt_softc_lock);
168 	if (minor >= npty) {
169 		struct pt_softc **newpt;
170 		int newnpty;
171 
172 		/* check if the requested pty can be granted */
173 		if (minor >= maxptys)
174 			goto limit_reached;
175 
176 		/* grow pty array by powers of two, up to maxptys */
177 		for (newnpty = npty; newnpty <= minor; newnpty *= 2)
178 			;
179 
180 		if (newnpty > maxptys)
181 			newnpty = maxptys;
182 		newpt = ptyarralloc(newnpty);
183 
184 		memcpy(newpt, pt_softc, npty * sizeof(struct pt_softc *));
185 		free(pt_softc, M_DEVBUF, npty * sizeof(struct pt_softc *));
186 		pt_softc = newpt;
187 		npty = newnpty;
188 	}
189 
190 	/*
191 	 * If the entry is not yet allocated, allocate one.
192 	 */
193 	if (!pt_softc[minor]) {
194 		pti = malloc(sizeof(struct pt_softc), M_DEVBUF,
195 		    M_WAITOK|M_ZERO);
196 		pti->pt_tty = ttymalloc(1000000);
197 		ptydevname(minor, pti);
198 		pt_softc[minor] = pti;
199 	}
200 	rw_exit_write(&pt_softc_lock);
201 	return (0);
202 limit_reached:
203 	rw_exit_write(&pt_softc_lock);
204 	tablefull("pty");
205 	return (ENXIO);
206 }
207 
208 /*
209  * Establish n (or default if n is 1) ptys in the system.
210  */
211 void
212 ptyattach(int n)
213 {
214 	/* maybe should allow 0 => none? */
215 	if (n <= 1)
216 		n = NPTY_MIN;
217 	pt_softc = ptyarralloc(n);
218 	npty = n;
219 
220 	/*
221 	 * If we have pty, we need ptm too.
222 	 */
223 	ptmattach(1);
224 }
225 
226 int
227 ptsopen(dev_t dev, int flag, int devtype, struct proc *p)
228 {
229 	struct pt_softc *pti;
230 	struct tty *tp;
231 	int error;
232 
233 	if ((error = check_pty(minor(dev))))
234 		return (error);
235 
236 	pti = pt_softc[minor(dev)];
237 	if (!pti->pt_tty) {
238 		tp = pti->pt_tty = ttymalloc(1000000);
239 	} else
240 		tp = pti->pt_tty;
241 	if ((tp->t_state & TS_ISOPEN) == 0) {
242 		tp->t_state |= TS_WOPEN;
243 		ttychars(tp);		/* Set up default chars */
244 		tp->t_iflag = TTYDEF_IFLAG;
245 		tp->t_oflag = TTYDEF_OFLAG;
246 		tp->t_lflag = TTYDEF_LFLAG;
247 		tp->t_cflag = TTYDEF_CFLAG;
248 		tp->t_ispeed = tp->t_ospeed = B115200;
249 		ttsetwater(tp);		/* would be done in xxparam() */
250 	} else if (tp->t_state&TS_XCLUDE && suser(p, 0) != 0)
251 		return (EBUSY);
252 	if (tp->t_oproc)			/* Ctrlr still around. */
253 		tp->t_state |= TS_CARR_ON;
254 	while ((tp->t_state & TS_CARR_ON) == 0) {
255 		tp->t_state |= TS_WOPEN;
256 		if (flag&FNONBLOCK)
257 			break;
258 		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
259 				 ttopen, 0);
260 		if (error)
261 			return (error);
262 	}
263 	error = (*linesw[tp->t_line].l_open)(dev, tp, p);
264 	ptcwakeup(tp, FREAD|FWRITE);
265 	return (error);
266 }
267 
268 int
269 ptsclose(dev_t dev, int flag, int mode, struct proc *p)
270 {
271 	struct pt_softc *pti = pt_softc[minor(dev)];
272 	struct tty *tp = pti->pt_tty;
273 	int error;
274 
275 	error = (*linesw[tp->t_line].l_close)(tp, flag, p);
276 	error |= ttyclose(tp);
277 	ptcwakeup(tp, FREAD|FWRITE);
278 	return (error);
279 }
280 
281 int
282 ptsread(dev_t dev, struct uio *uio, int flag)
283 {
284 	struct proc *p = curproc;
285 	struct process *pr = p->p_p;
286 	struct pt_softc *pti = pt_softc[minor(dev)];
287 	struct tty *tp = pti->pt_tty;
288 	int error = 0;
289 
290 again:
291 	if (pti->pt_flags & PF_REMOTE) {
292 		while (isbackground(pr, tp)) {
293 			if ((pr->ps_sigacts->ps_sigignore & sigmask(SIGTTIN)) ||
294 			    (p->p_sigmask & sigmask(SIGTTIN)) ||
295 			    pr->ps_pgrp->pg_jobc == 0 ||
296 			    pr->ps_flags & PS_PPWAIT)
297 				return (EIO);
298 			pgsignal(pr->ps_pgrp, SIGTTIN, 1);
299 			error = ttysleep(tp, &lbolt,
300 			    TTIPRI | PCATCH, ttybg, 0);
301 			if (error)
302 				return (error);
303 		}
304 		if (tp->t_canq.c_cc == 0) {
305 			if (flag & IO_NDELAY)
306 				return (EWOULDBLOCK);
307 			error = ttysleep(tp, &tp->t_canq,
308 			    TTIPRI | PCATCH, ttyin, 0);
309 			if (error)
310 				return (error);
311 			goto again;
312 		}
313 		while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
314 			if (ureadc(getc(&tp->t_canq), uio) < 0) {
315 				error = EFAULT;
316 				break;
317 			}
318 		if (tp->t_canq.c_cc == 1)
319 			(void) getc(&tp->t_canq);
320 		if (tp->t_canq.c_cc)
321 			return (error);
322 	} else
323 		if (tp->t_oproc)
324 			error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
325 	ptcwakeup(tp, FWRITE);
326 	return (error);
327 }
328 
329 /*
330  * Write to pseudo-tty.
331  * Wakeups of controlling tty will happen
332  * indirectly, when tty driver calls ptsstart.
333  */
334 int
335 ptswrite(dev_t dev, struct uio *uio, int flag)
336 {
337 	struct pt_softc *pti = pt_softc[minor(dev)];
338 	struct tty *tp = pti->pt_tty;
339 
340 	if (tp->t_oproc == 0)
341 		return (EIO);
342 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
343 }
344 
345 /*
346  * Start output on pseudo-tty.
347  * Wake up process polling or sleeping for input from controlling tty.
348  */
349 void
350 ptsstart(struct tty *tp)
351 {
352 	struct pt_softc *pti = pt_softc[minor(tp->t_dev)];
353 
354 	if (tp->t_state & TS_TTSTOP)
355 		return;
356 	if (pti->pt_flags & PF_STOPPED) {
357 		pti->pt_flags &= ~PF_STOPPED;
358 		pti->pt_send = TIOCPKT_START;
359 	}
360 	ptcwakeup(tp, FREAD);
361 }
362 
363 int
364 ptsstop(struct tty *tp, int flush)
365 {
366 	struct pt_softc *pti = pt_softc[minor(tp->t_dev)];
367 	int flag;
368 
369 	/* note: FLUSHREAD and FLUSHWRITE already ok */
370 	if (flush == 0) {
371 		flush = TIOCPKT_STOP;
372 		pti->pt_flags |= PF_STOPPED;
373 	} else
374 		pti->pt_flags &= ~PF_STOPPED;
375 	pti->pt_send |= flush;
376 	/* change of perspective */
377 	flag = 0;
378 	if (flush & FREAD)
379 		flag |= FWRITE;
380 	if (flush & FWRITE)
381 		flag |= FREAD;
382 	ptcwakeup(tp, flag);
383 	return 0;
384 }
385 
386 void
387 ptcwakeup(struct tty *tp, int flag)
388 {
389 	struct pt_softc *pti = pt_softc[minor(tp->t_dev)];
390 
391 	if (flag & FREAD) {
392 		selwakeup(&pti->pt_selr);
393 		wakeup(&tp->t_outq.c_cf);
394 	}
395 	if (flag & FWRITE) {
396 		selwakeup(&pti->pt_selw);
397 		wakeup(&tp->t_rawq.c_cf);
398 	}
399 }
400 
401 int ptcopen(dev_t, int, int, struct proc *);
402 
403 int
404 ptcopen(dev_t dev, int flag, int devtype, struct proc *p)
405 {
406 	struct pt_softc *pti;
407 	struct tty *tp;
408 	int error;
409 
410 	if ((error = check_pty(minor(dev))))
411 		return (error);
412 
413 	pti = pt_softc[minor(dev)];
414 	if (!pti->pt_tty) {
415 		tp = pti->pt_tty = ttymalloc(1000000);
416 	} else
417 		tp = pti->pt_tty;
418 	if (tp->t_oproc)
419 		return (EIO);
420 	tp->t_oproc = ptsstart;
421 	(void)(*linesw[tp->t_line].l_modem)(tp, 1);
422 	tp->t_lflag &= ~EXTPROC;
423 	pti->pt_flags = 0;
424 	pti->pt_send = 0;
425 	pti->pt_ucntl = 0;
426 	return (0);
427 }
428 
429 int
430 ptcclose(dev_t dev, int flag, int devtype, struct proc *p)
431 {
432 	struct pt_softc *pti = pt_softc[minor(dev)];
433 	struct tty *tp = pti->pt_tty;
434 
435 	(void)(*linesw[tp->t_line].l_modem)(tp, 0);
436 	tp->t_state &= ~TS_CARR_ON;
437 	tp->t_oproc = 0;		/* mark closed */
438 	return (0);
439 }
440 
441 int
442 ptcread(dev_t dev, struct uio *uio, int flag)
443 {
444 	struct pt_softc *pti = pt_softc[minor(dev)];
445 	struct tty *tp = pti->pt_tty;
446 	char buf[BUFSIZ];
447 	int error = 0, cc, bufcc = 0;
448 
449 	/*
450 	 * We want to block until the slave
451 	 * is open, and there's something to read;
452 	 * but if we lost the slave or we're NBIO,
453 	 * then return the appropriate error instead.
454 	 */
455 	for (;;) {
456 		if (tp->t_state&TS_ISOPEN) {
457 			if (pti->pt_flags&PF_PKT && pti->pt_send) {
458 				error = ureadc((int)pti->pt_send, uio);
459 				if (error)
460 					return (error);
461 				if (pti->pt_send & TIOCPKT_IOCTL) {
462 					cc = MIN(uio->uio_resid,
463 						sizeof(tp->t_termios));
464 					error = uiomove(&tp->t_termios, cc, uio);
465 					if (error)
466 						return (error);
467 				}
468 				pti->pt_send = 0;
469 				return (0);
470 			}
471 			if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
472 				error = ureadc((int)pti->pt_ucntl, uio);
473 				if (error)
474 					return (error);
475 				pti->pt_ucntl = 0;
476 				return (0);
477 			}
478 			if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
479 				break;
480 		}
481 		if ((tp->t_state&TS_CARR_ON) == 0)
482 			return (0);	/* EOF */
483 		if (flag & IO_NDELAY)
484 			return (EWOULDBLOCK);
485 		error = tsleep(&tp->t_outq.c_cf, TTIPRI | PCATCH,
486 		    ttyin, 0);
487 		if (error)
488 			return (error);
489 	}
490 	if (pti->pt_flags & (PF_PKT|PF_UCNTL))
491 		error = ureadc(0, uio);
492 	while (uio->uio_resid > 0 && error == 0) {
493 		cc = MIN(uio->uio_resid, BUFSIZ);
494 		cc = q_to_b(&tp->t_outq, buf, cc);
495 		if (cc > bufcc)
496 			bufcc = cc;
497 		if (cc <= 0)
498 			break;
499 		error = uiomove(buf, cc, uio);
500 	}
501 	ttwakeupwr(tp);
502 	if (bufcc)
503 		explicit_bzero(buf, bufcc);
504 	return (error);
505 }
506 
507 
508 int
509 ptcwrite(dev_t dev, struct uio *uio, int flag)
510 {
511 	struct pt_softc *pti = pt_softc[minor(dev)];
512 	struct tty *tp = pti->pt_tty;
513 	u_char *cp = NULL;
514 	int cc = 0, bufcc = 0;
515 	u_char buf[BUFSIZ];
516 	size_t cnt = 0;
517 	int error = 0;
518 
519 again:
520 	if ((tp->t_state&TS_ISOPEN) == 0)
521 		goto block;
522 	if (pti->pt_flags & PF_REMOTE) {
523 		if (tp->t_canq.c_cc)
524 			goto block;
525 		while (uio->uio_resid > 0 && tp->t_canq.c_cc < TTYHOG(tp) - 1) {
526 			if (cc == 0) {
527 				cc = MIN(uio->uio_resid, BUFSIZ);
528 				cc = min(cc, TTYHOG(tp) - 1 - tp->t_canq.c_cc);
529 				if (cc > bufcc)
530 					bufcc = cc;
531 				cp = buf;
532 				error = uiomove(cp, cc, uio);
533 				if (error)
534 					goto done;
535 				/* check again for safety */
536 				if ((tp->t_state&TS_ISOPEN) == 0) {
537 					error = EIO;
538 					goto done;
539 				}
540 			}
541 			if (cc)
542 				(void) b_to_q((char *)cp, cc, &tp->t_canq);
543 			cc = 0;
544 		}
545 		(void) putc(0, &tp->t_canq);
546 		ttwakeup(tp);
547 		wakeup(&tp->t_canq);
548 		goto done;
549 	}
550 	do {
551 		if (cc == 0) {
552 			cc = MIN(uio->uio_resid, BUFSIZ);
553 			if (cc > bufcc)
554 				bufcc = cc;
555 			cp = buf;
556 			error = uiomove(cp, cc, uio);
557 			if (error)
558 				goto done;
559 			/* check again for safety */
560 			if ((tp->t_state&TS_ISOPEN) == 0) {
561 				error = EIO;
562 				goto done;
563 			}
564 		}
565 		bufcc = cc;
566 		while (cc > 0) {
567 			if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG(tp) - 2 &&
568 			   (tp->t_canq.c_cc > 0 || !ISSET(tp->t_lflag, ICANON))) {
569 				wakeup(&tp->t_rawq);
570 				goto block;
571 			}
572 			(*linesw[tp->t_line].l_rint)(*cp++, tp);
573 			cnt++;
574 			cc--;
575 		}
576 		cc = 0;
577 	} while (uio->uio_resid > 0);
578 	goto done;
579 block:
580 	/*
581 	 * Come here to wait for slave to open, for space
582 	 * in outq, or space in rawq.
583 	 */
584 	if ((tp->t_state&TS_CARR_ON) == 0) {
585 		error = EIO;
586 		goto done;
587 	}
588 	if (flag & IO_NDELAY) {
589 		/* adjust for data copied in but not written */
590 		uio->uio_resid += cc;
591 		if (cnt == 0)
592 			error = EWOULDBLOCK;
593 		goto done;
594 	}
595 	error = tsleep(&tp->t_rawq.c_cf, TTOPRI | PCATCH,
596 	    ttyout, 0);
597 	if (error == 0)
598 		goto again;
599 
600 	/* adjust for data copied in but not written */
601 	uio->uio_resid += cc;
602 done:
603 	if (bufcc)
604 		explicit_bzero(buf, bufcc);
605 	return (error);
606 }
607 
608 int
609 ptcpoll(dev_t dev, int events, struct proc *p)
610 {
611 	struct pt_softc *pti = pt_softc[minor(dev)];
612 	struct tty *tp = pti->pt_tty;
613 	int revents = 0, s;
614 
615 	if (!ISSET(tp->t_state, TS_ISOPEN) && ISSET(tp->t_state, TS_CARR_ON))
616 		goto notopen;
617 
618 	if (events & (POLLIN | POLLRDNORM)) {
619 		/*
620 		 * Need to protect access to t_outq
621 		 */
622 		s = spltty();
623 		if ((tp->t_outq.c_cc && !ISSET(tp->t_state, TS_TTSTOP)) ||
624 		    ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
625 		    ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
626 			revents |= events & (POLLIN | POLLRDNORM);
627 		splx(s);
628 	}
629 	/* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */
630 	if (!ISSET(tp->t_state, TS_CARR_ON)) {
631 		revents |= POLLHUP;
632 	} else if (events & (POLLOUT | POLLWRNORM)) {
633 		if ((pti->pt_flags & PF_REMOTE) ?
634 		    (tp->t_canq.c_cc == 0) :
635 		    ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG(tp) - 2) ||
636 		    (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON))))
637 			revents |= events & (POLLOUT | POLLWRNORM);
638 	}
639 	if (events & (POLLPRI | POLLRDBAND)) {
640 		/* If in packet or user control mode, check for data. */
641 		if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
642 		    ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
643 			revents |= events & (POLLPRI | POLLRDBAND);
644 	}
645 
646 	if (revents == 0) {
647 notopen:
648 		if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND))
649 			selrecord(p, &pti->pt_selr);
650 		if (events & (POLLOUT | POLLWRNORM))
651 			selrecord(p, &pti->pt_selw);
652 	}
653 
654 	return (revents);
655 }
656 
657 void
658 filt_ptcrdetach(struct knote *kn)
659 {
660 	struct pt_softc *pti = (struct pt_softc *)kn->kn_hook;
661 	int s;
662 
663 	s = spltty();
664 	SLIST_REMOVE(&pti->pt_selr.si_note, kn, knote, kn_selnext);
665 	splx(s);
666 }
667 
668 int
669 filt_ptcread(struct knote *kn, long hint)
670 {
671 	struct pt_softc *pti = (struct pt_softc *)kn->kn_hook;
672 	struct tty *tp;
673 
674 	tp = pti->pt_tty;
675 	kn->kn_data = 0;
676 
677 	if (ISSET(tp->t_state, TS_ISOPEN)) {
678 		if (!ISSET(tp->t_state, TS_TTSTOP))
679 			kn->kn_data = tp->t_outq.c_cc;
680 		if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
681 		    ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
682 			kn->kn_data++;
683 	}
684 	return (kn->kn_data > 0);
685 }
686 
687 void
688 filt_ptcwdetach(struct knote *kn)
689 {
690 	struct pt_softc *pti = (struct pt_softc *)kn->kn_hook;
691 	int s;
692 
693 	s = spltty();
694 	SLIST_REMOVE(&pti->pt_selw.si_note, kn, knote, kn_selnext);
695 	splx(s);
696 }
697 
698 int
699 filt_ptcwrite(struct knote *kn, long hint)
700 {
701 	struct pt_softc *pti = (struct pt_softc *)kn->kn_hook;
702 	struct tty *tp;
703 
704 	tp = pti->pt_tty;
705 	kn->kn_data = 0;
706 
707 	if (ISSET(tp->t_state, TS_ISOPEN)) {
708 		if (ISSET(pti->pt_flags, PF_REMOTE)) {
709 			if (tp->t_canq.c_cc == 0)
710 				kn->kn_data = tp->t_canq.c_cn;
711 		} else if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG(tp)-2)
712 			kn->kn_data = tp->t_canq.c_cn -
713 			    (tp->t_rawq.c_cc + tp->t_canq.c_cc);
714 	}
715 
716 	return (kn->kn_data > 0);
717 }
718 
719 struct filterops ptcread_filtops =
720 	{ 1, NULL, filt_ptcrdetach, filt_ptcread };
721 struct filterops ptcwrite_filtops =
722 	{ 1, NULL, filt_ptcwdetach, filt_ptcwrite };
723 
724 int
725 ptckqfilter(dev_t dev, struct knote *kn)
726 {
727 	struct pt_softc *pti = pt_softc[minor(dev)];
728 	struct klist *klist;
729 	int s;
730 
731 	switch (kn->kn_filter) {
732 	case EVFILT_READ:
733 		klist = &pti->pt_selr.si_note;
734 		kn->kn_fop = &ptcread_filtops;
735 		break;
736 	case EVFILT_WRITE:
737 		klist = &pti->pt_selw.si_note;
738 		kn->kn_fop = &ptcwrite_filtops;
739 		break;
740 	default:
741 		return (EINVAL);
742 	}
743 
744 	kn->kn_hook = (caddr_t)pti;
745 
746 	s = spltty();
747 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
748 	splx(s);
749 
750 	return (0);
751 }
752 
753 struct tty *
754 ptytty(dev_t dev)
755 {
756 	struct pt_softc *pti = pt_softc[minor(dev)];
757 	struct tty *tp = pti->pt_tty;
758 
759 	return (tp);
760 }
761 
762 int
763 ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
764 {
765 	struct pt_softc *pti = pt_softc[minor(dev)];
766 	struct tty *tp = pti->pt_tty;
767 	u_char *cc = tp->t_cc;
768 	int stop, error;
769 
770 	/*
771 	 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
772 	 * ttywflush(tp) will hang if there are characters in the outq.
773 	 */
774 	if (cmd == TIOCEXT) {
775 		/*
776 		 * When the EXTPROC bit is being toggled, we need
777 		 * to send an TIOCPKT_IOCTL if the packet driver
778 		 * is turned on.
779 		 */
780 		if (*(int *)data) {
781 			if (pti->pt_flags & PF_PKT) {
782 				pti->pt_send |= TIOCPKT_IOCTL;
783 				ptcwakeup(tp, FREAD);
784 			}
785 			tp->t_lflag |= EXTPROC;
786 		} else {
787 			if ((tp->t_lflag & EXTPROC) &&
788 			    (pti->pt_flags & PF_PKT)) {
789 				pti->pt_send |= TIOCPKT_IOCTL;
790 				ptcwakeup(tp, FREAD);
791 			}
792 			tp->t_lflag &= ~EXTPROC;
793 		}
794 		return(0);
795 	} else if (cdevsw[major(dev)].d_open == ptcopen)
796 		switch (cmd) {
797 
798 		case TIOCGPGRP:
799 			/*
800 			 * We avoid calling ttioctl on the controller since,
801 			 * in that case, tp must be the controlling terminal.
802 			 */
803 			*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
804 			return (0);
805 
806 		case TIOCPKT:
807 			if (*(int *)data) {
808 				if (pti->pt_flags & PF_UCNTL)
809 					return (EINVAL);
810 				pti->pt_flags |= PF_PKT;
811 			} else
812 				pti->pt_flags &= ~PF_PKT;
813 			return (0);
814 
815 		case TIOCUCNTL:
816 			if (*(int *)data) {
817 				if (pti->pt_flags & PF_PKT)
818 					return (EINVAL);
819 				pti->pt_flags |= PF_UCNTL;
820 			} else
821 				pti->pt_flags &= ~PF_UCNTL;
822 			return (0);
823 
824 		case TIOCREMOTE:
825 			if (*(int *)data)
826 				pti->pt_flags |= PF_REMOTE;
827 			else
828 				pti->pt_flags &= ~PF_REMOTE;
829 			ttyflush(tp, FREAD|FWRITE);
830 			return (0);
831 
832 		case TIOCSETD:
833 		case TIOCSETA:
834 		case TIOCSETAW:
835 		case TIOCSETAF:
836 			ndflush(&tp->t_outq, tp->t_outq.c_cc);
837 			break;
838 
839 		case TIOCSIG:
840 			if (*(unsigned int *)data >= NSIG ||
841 			    *(unsigned int *)data == 0)
842 				return(EINVAL);
843 			if ((tp->t_lflag&NOFLSH) == 0)
844 				ttyflush(tp, FREAD|FWRITE);
845 			pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);
846 			if ((*(unsigned int *)data == SIGINFO) &&
847 			    ((tp->t_lflag&NOKERNINFO) == 0))
848 				ttyinfo(tp);
849 			return (0);
850 
851 		case FIONREAD:
852 			/*
853 			 * FIONREAD on the master side must return the amount
854 			 * in the output queue rather than the input.
855 			 */
856 			*(int *)data = tp->t_outq.c_cc;
857 			return (0);
858 		}
859 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
860 	if (error < 0)
861 		 error = ttioctl(tp, cmd, data, flag, p);
862 	if (error < 0) {
863 		if (pti->pt_flags & PF_UCNTL &&
864 		    (cmd & ~0xff) == UIOCCMD(0)) {
865 			if (cmd & 0xff) {
866 				pti->pt_ucntl = (u_char)cmd;
867 				ptcwakeup(tp, FREAD);
868 			}
869 			return (0);
870 		}
871 		error = ENOTTY;
872 	}
873 	/*
874 	 * If external processing and packet mode send ioctl packet.
875 	 */
876 	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
877 		switch (cmd) {
878 		case TIOCSETA:
879 		case TIOCSETAW:
880 		case TIOCSETAF:
881 			pti->pt_send |= TIOCPKT_IOCTL;
882 			ptcwakeup(tp, FREAD);
883 		default:
884 			break;
885 		}
886 	}
887 	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s')) &&
888 	    CCEQ(cc[VSTART], CTRL('q'));
889 	if (pti->pt_flags & PF_NOSTOP) {
890 		if (stop) {
891 			pti->pt_send &= ~TIOCPKT_NOSTOP;
892 			pti->pt_send |= TIOCPKT_DOSTOP;
893 			pti->pt_flags &= ~PF_NOSTOP;
894 			ptcwakeup(tp, FREAD);
895 		}
896 	} else {
897 		if (!stop) {
898 			pti->pt_send &= ~TIOCPKT_DOSTOP;
899 			pti->pt_send |= TIOCPKT_NOSTOP;
900 			pti->pt_flags |= PF_NOSTOP;
901 			ptcwakeup(tp, FREAD);
902 		}
903 	}
904 	return (error);
905 }
906 
907 /*
908  * Return pty-related information.
909  */
910 int
911 sysctl_pty(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
912     size_t newlen)
913 {
914 	if (namelen != 1)
915 		return (ENOTDIR);
916 
917 	switch (name[0]) {
918 	default:
919 		return (EOPNOTSUPP);
920 	}
921 	/* NOTREACHED */
922 }
923 
924 /*
925  * Check if a pty is free to use.
926  */
927 static int
928 pty_isfree_locked(int minor)
929 {
930 	struct pt_softc *pt = pt_softc[minor];
931 
932 	return (pt == NULL || pt->pt_tty == NULL ||
933 	    pt->pt_tty->t_oproc == NULL);
934 }
935 
936 static int
937 pty_isfree(int minor)
938 {
939 	int isfree;
940 
941 	rw_enter_read(&pt_softc_lock);
942 	isfree = pty_isfree_locked(minor);
943 	rw_exit_read(&pt_softc_lock);
944 	return(isfree);
945 }
946 
947 dev_t
948 pty_getfree(void)
949 {
950 	int i;
951 
952 	rw_enter_read(&pt_softc_lock);
953 	for (i = 0; i < npty; i++) {
954 		if (pty_isfree_locked(i))
955 			break;
956 	}
957 	rw_exit_read(&pt_softc_lock);
958 	return (makedev(pts_major, i));
959 }
960 
961 /*
962  * Hacked up version of vn_open. We _only_ handle ptys and only open
963  * them with FREAD|FWRITE and never deal with creat or stuff like that.
964  *
965  * We need it because we have to fake up root credentials to open the pty.
966  */
967 static int
968 ptm_vn_open(struct nameidata *ndp)
969 {
970 	struct proc *p = ndp->ni_cnd.cn_proc;
971 	struct ucred *cred;
972 	struct vattr vattr;
973 	struct vnode *vp;
974 	int error;
975 
976 	if ((error = namei(ndp)) != 0)
977 		return (error);
978 	vp = ndp->ni_vp;
979 	if (vp->v_type != VCHR) {
980 		error = EINVAL;
981 		goto bad;
982 	}
983 
984 	/*
985 	 * Get us a fresh cred with root privileges.
986 	 */
987 	cred = crget();
988 	error = VOP_OPEN(vp, FREAD|FWRITE, cred, p);
989 	if (!error) {
990 		/* update atime/mtime */
991 		VATTR_NULL(&vattr);
992 		getnanotime(&vattr.va_atime);
993 		vattr.va_mtime = vattr.va_atime;
994 		vattr.va_vaflags |= VA_UTIMES_NULL;
995 		(void)VOP_SETATTR(vp, &vattr, p->p_ucred, p);
996 	}
997 	crfree(cred);
998 
999 	if (error)
1000 		goto bad;
1001 
1002 	vp->v_writecount++;
1003 
1004 	return (0);
1005 bad:
1006 	vput(vp);
1007 	return (error);
1008 }
1009 
1010 void
1011 ptmattach(int n)
1012 {
1013 	/* find the major and minor of the pty devices */
1014 	int i;
1015 
1016 	for (i = 0; i < nchrdev; i++)
1017 		if (cdevsw[i].d_open == ptsopen)
1018 			break;
1019 
1020 	if (i == nchrdev)
1021 		panic("ptmattach: Can't find pty slave in cdevsw");
1022 
1023 	pts_major = i;
1024 }
1025 
1026 int
1027 ptmopen(dev_t dev, int flag, int mode, struct proc *p)
1028 {
1029 	return(0);
1030 }
1031 
1032 
1033 int
1034 ptmclose(dev_t dev, int flag, int mode, struct proc *p)
1035 {
1036 	return (0);
1037 }
1038 
1039 int
1040 ptmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
1041 {
1042 	dev_t newdev, error;
1043 	struct pt_softc * pti;
1044 	struct nameidata cnd, snd;
1045 	struct filedesc *fdp = p->p_fd;
1046 	struct file *cfp = NULL, *sfp = NULL;
1047 	int cindx, sindx;
1048 	uid_t uid;
1049 	gid_t gid;
1050 	struct vattr vattr;
1051 	struct ucred *cred;
1052 	struct ptmget *ptm = (struct ptmget *)data;
1053 
1054 	switch (cmd) {
1055 	case PTMGET:
1056 		fdplock(fdp);
1057 		/* Grab two filedescriptors. */
1058 		if ((error = falloc(p, &cfp, &cindx)) != 0) {
1059 			fdpunlock(fdp);
1060 			break;
1061 		}
1062 		if ((error = falloc(p, &sfp, &sindx)) != 0) {
1063 			fdremove(fdp, cindx);
1064 			closef(cfp, p);
1065 			fdpunlock(fdp);
1066 			break;
1067 		}
1068 
1069 retry:
1070 		/* Find and open a free master pty. */
1071 		newdev = pty_getfree();
1072 		if ((error = check_pty(minor(newdev))))
1073 			goto bad;
1074 		pti = pt_softc[minor(newdev)];
1075 		NDINIT(&cnd, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE,
1076 		    pti->pty_pn, p);
1077 		cnd.ni_pledge = PLEDGE_RPATH | PLEDGE_WPATH;
1078 		if ((error = ptm_vn_open(&cnd)) != 0) {
1079 			/*
1080 			 * Check if the master open failed because we lost
1081 			 * the race to grab it.
1082 			 */
1083 			if (error == EIO && !pty_isfree(minor(newdev)))
1084 				goto retry;
1085 			goto bad;
1086 		}
1087 		cfp->f_flag = FREAD|FWRITE;
1088 		cfp->f_type = DTYPE_VNODE;
1089 		cfp->f_ops = &vnops;
1090 		cfp->f_data = (caddr_t) cnd.ni_vp;
1091 		VOP_UNLOCK(cnd.ni_vp, p);
1092 
1093 		/*
1094 		 * Open the slave.
1095 		 * namei -> setattr -> unlock -> revoke -> vrele ->
1096 		 * namei -> open -> unlock
1097 		 * Three stage rocket:
1098 		 * 1. Change the owner and permissions on the slave.
1099 		 * 2. Revoke all the users of the slave.
1100 		 * 3. open the slave.
1101 		 */
1102 		NDINIT(&snd, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE,
1103 		    pti->pty_sn, p);
1104 		snd.ni_pledge = PLEDGE_RPATH | PLEDGE_WPATH;
1105 		if ((error = namei(&snd)) != 0)
1106 			goto bad;
1107 		if ((snd.ni_vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
1108 			gid = tty_gid;
1109 			/* get real uid */
1110 			uid = p->p_ucred->cr_ruid;
1111 
1112 			VATTR_NULL(&vattr);
1113 			vattr.va_uid = uid;
1114 			vattr.va_gid = gid;
1115 			vattr.va_mode = (S_IRUSR|S_IWUSR|S_IWGRP) & ALLPERMS;
1116 			/* Get a fake cred to pretend we're root. */
1117 			cred = crget();
1118 			error = VOP_SETATTR(snd.ni_vp, &vattr, cred, p);
1119 			crfree(cred);
1120 			if (error) {
1121 				vput(snd.ni_vp);
1122 				goto bad;
1123 			}
1124 		}
1125 		VOP_UNLOCK(snd.ni_vp, p);
1126 		if (snd.ni_vp->v_usecount > 1 ||
1127 		    (snd.ni_vp->v_flag & (VALIASED)))
1128 			VOP_REVOKE(snd.ni_vp, REVOKEALL);
1129 
1130 		/*
1131 		 * The vnode is useless after the revoke, we need to
1132 		 * namei again.
1133 		 */
1134 		vrele(snd.ni_vp);
1135 
1136 		NDINIT(&snd, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE,
1137 		    pti->pty_sn, p);
1138 		snd.ni_pledge = PLEDGE_RPATH | PLEDGE_WPATH;
1139 		/* now open it */
1140 		if ((error = ptm_vn_open(&snd)) != 0)
1141 			goto bad;
1142 		sfp->f_flag = FREAD|FWRITE;
1143 		sfp->f_type = DTYPE_VNODE;
1144 		sfp->f_ops = &vnops;
1145 		sfp->f_data = (caddr_t) snd.ni_vp;
1146 		VOP_UNLOCK(snd.ni_vp, p);
1147 
1148 		/* now, put the indexen and names into struct ptmget */
1149 		ptm->cfd = cindx;
1150 		ptm->sfd = sindx;
1151 		memcpy(ptm->cn, pti->pty_pn, sizeof(pti->pty_pn));
1152 		memcpy(ptm->sn, pti->pty_sn, sizeof(pti->pty_sn));
1153 
1154 		/* mark the files mature now that we've passed all errors */
1155 		FILE_SET_MATURE(cfp, p);
1156 		FILE_SET_MATURE(sfp, p);
1157 
1158 		fdpunlock(fdp);
1159 		break;
1160 	default:
1161 		error = EINVAL;
1162 		break;
1163 	}
1164 	return (error);
1165 bad:
1166 	fdremove(fdp, cindx);
1167 	closef(cfp, p);
1168 	fdremove(fdp, sindx);
1169 	closef(sfp, p);
1170 	fdpunlock(fdp);
1171 	return (error);
1172 }
1173