1/*
2 * Copyright (c) 1997-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * Copyright (c) 1982, 1986, 1989, 1993
30 *      The Regents of the University of California.  All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 *    notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 *    notice, this list of conditions and the following disclaimer in the
39 *    documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 *    must display the following acknowledgement:
42 *      This product includes software developed by the University of
43 *      California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 *    may be used to endorse or promote products derived from this software
46 *    without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 *	@(#)tty_pty.c	8.4 (Berkeley) 2/20/95
61 */
62
63/* Common callbacks for the pseudo-teletype driver (pty/tty)
64 * and cloning pseudo-teletype driver (ptmx/pts).
65 */
66
67#include <sys/param.h>
68#include <sys/systm.h>
69#include <sys/ioctl.h>
70#include <sys/proc_internal.h>
71#include <sys/kauth.h>
72#include <sys/tty.h>
73#include <sys/conf.h>
74#include <sys/file_internal.h>
75#include <sys/uio_internal.h>
76#include <sys/kernel.h>
77#include <sys/vnode.h>
78#include <sys/vnode_internal.h>		/* _devfs_setattr() */
79#include <sys/stat.h>			/* _devfs_setattr() */
80#include <sys/user.h>
81#include <sys/signalvar.h>
82#include <sys/sysctl.h>
83#include <miscfs/devfs/devfs.h>
84#include <miscfs/devfs/devfsdefs.h>	/* DEVFS_LOCK()/DEVFS_UNLOCK() */
85
86#if CONFIG_MACF
87#include <security/mac_framework.h>
88#endif
89
90#include "tty_dev.h"
91
92/* XXX belongs in devfs somewhere - LATER */
93static int _devfs_setattr(void *, unsigned short, uid_t, gid_t);
94
95/*
96 * Forward declarations
97 */
98static void ptcwakeup(struct tty *tp, int flag);
99__XNU_PRIVATE_EXTERN	d_open_t	ptsopen;
100__XNU_PRIVATE_EXTERN	d_close_t	ptsclose;
101__XNU_PRIVATE_EXTERN	d_read_t	ptsread;
102__XNU_PRIVATE_EXTERN	d_write_t	ptswrite;
103__XNU_PRIVATE_EXTERN	d_ioctl_t	ptyioctl;	/* common ioctl */
104__XNU_PRIVATE_EXTERN	d_stop_t	ptsstop;
105__XNU_PRIVATE_EXTERN	d_reset_t	ptsreset;
106__XNU_PRIVATE_EXTERN	d_select_t	ptsselect;
107__XNU_PRIVATE_EXTERN	d_open_t	ptcopen;
108__XNU_PRIVATE_EXTERN	d_close_t	ptcclose;
109__XNU_PRIVATE_EXTERN	d_read_t	ptcread;
110__XNU_PRIVATE_EXTERN	d_write_t	ptcwrite;
111__XNU_PRIVATE_EXTERN	d_stop_t	ptcstop;	/* NO-OP */
112__XNU_PRIVATE_EXTERN	d_reset_t	ptcreset;
113__XNU_PRIVATE_EXTERN	d_select_t	ptcselect;
114
115/*
116 * XXX Should be devfs function... and use VATTR mechanisms, per
117 * XXX vnode_setattr2(); only we maybe can't really get back to the
118 * XXX vnode here for cloning devices (but it works for *cloned* devices
119 * XXX that are not themselves cloning).
120 *
121 * Returns:	0			Success
122 *	namei:???
123 *	vnode_setattr:???
124 */
125static int
126_devfs_setattr(void * handle, unsigned short mode, uid_t uid, gid_t gid)
127{
128	devdirent_t		*direntp = (devdirent_t *)handle;
129	devnode_t		*devnodep;
130	int			error = EACCES;
131	vfs_context_t		ctx = vfs_context_current();;
132	struct vnode_attr	va;
133
134	VATTR_INIT(&va);
135	VATTR_SET(&va, va_uid, uid);
136	VATTR_SET(&va, va_gid, gid);
137	VATTR_SET(&va, va_mode, mode & ALLPERMS);
138
139	/*
140	 * If the TIOCPTYGRANT loses the race with the clone operation because
141	 * this function is not part of devfs, and therefore can't take the
142	 * devfs lock to protect the direntp update, then force user space to
143	 * redrive the grant request.
144	 */
145	if (direntp == NULL || (devnodep = direntp->de_dnp) == NULL) {
146		error = ERESTART;
147		goto out;
148	}
149
150	/*
151	 * Only do this if we are operating on device that doesn't clone
152	 * each time it's referenced.  We perform a lookup on the device
153	 * to insure we get the right instance.  We can't just use the call
154	 * to devfs_dntovn() to get the vp for the operation, because
155	 * dn_dvm may not have been initialized.
156	 */
157	if (devnodep->dn_clone == NULL) {
158		struct nameidata nd;
159		char name[128];
160
161		snprintf(name, sizeof(name), "/dev/%s", direntp->de_name);
162		NDINIT(&nd, LOOKUP, OP_SETATTR, FOLLOW, UIO_SYSSPACE, CAST_USER_ADDR_T(name), ctx);
163		error = namei(&nd);
164		if (error)
165			goto out;
166		error = vnode_setattr(nd.ni_vp, &va, ctx);
167		vnode_put(nd.ni_vp);
168		nameidone(&nd);
169		goto out;
170	}
171
172out:
173	return(error);
174}
175
176#define BUFSIZ 100		/* Chunk size iomoved to/from user */
177
178static struct tty_dev_t *tty_dev_head;
179
180__private_extern__ void
181tty_dev_register(struct tty_dev_t *driver)
182{
183	if (driver) {
184		driver->next = tty_dev_head;
185		tty_dev_head = driver;
186	}
187}
188
189/*
190 * Given a minor number, return the corresponding structure for that minor
191 * number.  If there isn't one, and the create flag is specified, we create
192 * one if possible.
193 *
194 * Parameters:	minor			Minor number of ptmx device
195 *		open_flag		PF_OPEN_M	First open of master
196 *					PF_OPEN_S	First open of slave
197 *					0		Just want ioctl struct
198 *
199 * Returns:	NULL			Did not exist/could not create
200 *		!NULL			structure corresponding minor number
201 *
202 * Locks:	tty_lock() on ptmx_ioctl->pt_tty NOT held on entry or exit.
203 */
204
205static struct tty_dev_t *
206pty_get_driver(dev_t dev)
207{
208	int major = major(dev);
209	struct tty_dev_t *driver;
210	for (driver = tty_dev_head; driver != NULL; driver = driver->next) {
211		if ((driver->master == major || driver->slave == major)) {
212			break;
213		}
214	}
215	return driver;
216}
217
218static struct ptmx_ioctl *
219pty_get_ioctl(dev_t dev, int open_flag, struct tty_dev_t **out_driver)
220{
221	struct tty_dev_t *driver = pty_get_driver(dev);
222	if (out_driver) {
223		*out_driver = driver;
224	}
225	if (driver && driver->open) {
226		return driver->open(minor(dev), open_flag);
227	}
228	return NULL;
229}
230
231/*
232 * Locks:	tty_lock() of old_ptmx_ioctl->pt_tty NOT held for this call.
233 */
234static int
235pty_free_ioctl(dev_t dev, int open_flag)
236{
237	struct tty_dev_t *driver = pty_get_driver(dev);
238	if (driver && driver->free) {
239		return driver->free(minor(dev), open_flag);
240	}
241	return 0;
242}
243
244static int
245pty_get_name(dev_t dev, char *buffer, size_t size)
246{
247	struct tty_dev_t *driver = pty_get_driver(dev);
248	if (driver && driver->name) {
249		return driver->name(minor(dev), buffer, size);
250	}
251	return 0;
252}
253
254__private_extern__ int
255ptsopen(dev_t dev, int flag, __unused int devtype, __unused struct proc *p)
256{
257	int error;
258	struct tty_dev_t *driver;
259	struct ptmx_ioctl *pti = pty_get_ioctl(dev, PF_OPEN_S, &driver);
260	if (pti == NULL) {
261		return ENXIO;
262	}
263	if (!(pti->pt_flags & PF_UNLOCKED)) {
264		return EAGAIN;
265	}
266
267	struct tty *tp = pti->pt_tty;
268	tty_lock(tp);
269
270	if ((tp->t_state & TS_ISOPEN) == 0) {
271		termioschars(&tp->t_termios);	/* Set up default chars */
272		tp->t_iflag = TTYDEF_IFLAG;
273		tp->t_oflag = TTYDEF_OFLAG;
274		tp->t_lflag = TTYDEF_LFLAG;
275		tp->t_cflag = TTYDEF_CFLAG;
276		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
277		ttsetwater(tp);		/* would be done in xxparam() */
278	} else if ((tp->t_state & TS_XCLUDE) && kauth_cred_issuser(kauth_cred_get())) {
279	        error = EBUSY;
280		goto out;
281	}
282	if (tp->t_oproc)			/* Ctrlr still around. */
283		(void)(*linesw[tp->t_line].l_modem)(tp, 1);
284	while ((tp->t_state & TS_CARR_ON) == 0) {
285		if (flag&FNONBLOCK)
286			break;
287		error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH, __FUNCTION__, 0);
288		if (error)
289			goto out;
290	}
291	error = (*linesw[tp->t_line].l_open)(dev, tp);
292	/* Successful open; mark as open by the slave */
293
294	pti->pt_flags |= PF_OPEN_S;
295	CLR(tp->t_state, TS_IOCTL_NOT_OK);
296	if (error == 0)
297		ptcwakeup(tp, FREAD|FWRITE);
298
299out:
300	tty_unlock(tp);
301	return (error);
302}
303
304__private_extern__ int
305ptsclose(dev_t dev, int flag, __unused int mode, __unused proc_t p)
306{
307	int err;
308
309	/*
310	 * This is temporary until the VSX conformance tests
311	 * are fixed.  They are hanging with a deadlock
312	 * where close() will not complete without t_timeout set
313	 */
314#define	FIX_VSX_HANG	1
315#ifdef	FIX_VSX_HANG
316	int save_timeout;
317#endif
318	struct tty_dev_t *driver;
319	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
320	struct tty *tp;
321
322	if (pti == NULL)
323		return (ENXIO);
324
325	tp = pti->pt_tty;
326	tty_lock(tp);
327#ifdef	FIX_VSX_HANG
328	save_timeout = tp->t_timeout;
329	tp->t_timeout = 60;
330#endif
331	err = (*linesw[tp->t_line].l_close)(tp, flag);
332	ptsstop(tp, FREAD|FWRITE);
333	(void) ttyclose(tp);
334#ifdef	FIX_VSX_HANG
335	tp->t_timeout = save_timeout;
336#endif
337	tty_unlock(tp);
338
339	if ((flag & IO_REVOKE) == IO_REVOKE && driver->revoke) {
340		driver->revoke(minor(dev), tp);
341	}
342	/* unconditional, just like ttyclose() */
343	pty_free_ioctl(dev, PF_OPEN_S);
344
345	return (err);
346}
347
348__private_extern__ int
349ptsread(dev_t dev, struct uio *uio, int flag)
350{
351	proc_t p = current_proc();
352	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, NULL);
353	struct tty *tp;
354	int error = 0;
355	struct uthread *ut;
356	struct pgrp *pg;
357
358	if (pti == NULL)
359		return (ENXIO);
360	tp = pti->pt_tty;
361	tty_lock(tp);
362
363	ut = (struct uthread *)get_bsdthread_info(current_thread());
364again:
365	if (pti->pt_flags & PF_REMOTE) {
366		while (isbackground(p, tp)) {
367			if ((p->p_sigignore & sigmask(SIGTTIN)) ||
368			    (ut->uu_sigmask & sigmask(SIGTTIN)) ||
369			    p->p_lflag & P_LPPWAIT) {
370				error = EIO;
371				goto out;
372			}
373
374
375			pg = proc_pgrp(p);
376			if (pg == PGRP_NULL) {
377				error = EIO;
378				goto out;
379			}
380			/*
381			 * SAFE: We about to drop the lock ourselves by
382			 * SAFE: erroring out or sleeping anyway.
383			 */
384			tty_unlock(tp);
385			if (pg->pg_jobc == 0) {
386				pg_rele(pg);
387				tty_lock(tp);
388				error = EIO;
389				goto out;
390			}
391			pgsignal(pg, SIGTTIN, 1);
392			pg_rele(pg);
393			tty_lock(tp);
394
395			error = ttysleep(tp, &ptsread, TTIPRI | PCATCH | PTTYBLOCK, __FUNCTION__, hz);
396			if (error)
397			        goto out;
398		}
399		if (tp->t_canq.c_cc == 0) {
400			if (flag & IO_NDELAY) {
401				error = EWOULDBLOCK;
402				goto out;
403			}
404			error = ttysleep(tp, TSA_PTS_READ(tp), TTIPRI | PCATCH, __FUNCTION__, 0);
405			if (error)
406			        goto out;
407			goto again;
408		}
409		while (tp->t_canq.c_cc > 1 && uio_resid(uio) > 0) {
410			int cc;
411			char buf[BUFSIZ];
412
413			cc = MIN((int)uio_resid(uio), BUFSIZ);
414			// Don't copy the very last byte
415			cc = MIN(cc, tp->t_canq.c_cc - 1);
416			cc = q_to_b(&tp->t_canq, (u_char *)buf, cc);
417			error = uiomove(buf, cc, uio);
418			if (error)
419				break;
420		}
421		if (tp->t_canq.c_cc == 1)
422			(void) getc(&tp->t_canq);
423		if (tp->t_canq.c_cc)
424		        goto out;
425	} else
426		if (tp->t_oproc)
427			error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
428	ptcwakeup(tp, FWRITE);
429out:
430	tty_unlock(tp);
431	return (error);
432}
433
434/*
435 * Write to pseudo-tty.
436 * Wakeups of controlling tty will happen
437 * indirectly, when tty driver calls ptsstart.
438 */
439__private_extern__ int
440ptswrite(dev_t dev, struct uio *uio, int flag)
441{
442	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, NULL);
443	struct tty *tp;
444	int error;
445
446	if (pti == NULL)
447		return (ENXIO);
448	tp = pti->pt_tty;
449	tty_lock(tp);
450
451	if (tp->t_oproc == 0)
452		error = EIO;
453	else
454	        error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
455
456	tty_unlock(tp);
457
458	return (error);
459}
460
461/*
462 * Start output on pseudo-tty.
463 * Wake up process selecting or sleeping for input from controlling tty.
464 *
465 * t_oproc for this driver; called from within the line discipline
466 *
467 * Locks:	Assumes tp is locked on entry, remains locked on exit
468 */
469static void
470ptsstart(struct tty *tp)
471{
472	struct ptmx_ioctl *pti = pty_get_ioctl(tp->t_dev, 0, NULL);
473	if (pti == NULL)
474		goto out;
475	if (tp->t_state & TS_TTSTOP)
476	        goto out;
477	if (pti->pt_flags & PF_STOPPED) {
478		pti->pt_flags &= ~PF_STOPPED;
479		pti->pt_send = TIOCPKT_START;
480	}
481	ptcwakeup(tp, FREAD);
482out:
483	return;
484}
485
486/*
487 * Locks:	Assumes tty_lock() is held over this call.
488 */
489static void
490ptcwakeup(struct tty *tp, int flag)
491{
492	struct ptmx_ioctl *pti = pty_get_ioctl(tp->t_dev, 0, NULL);
493	if (pti == NULL)
494		return;
495
496	if (flag & FREAD) {
497		selwakeup(&pti->pt_selr);
498		wakeup(TSA_PTC_READ(tp));
499	}
500	if (flag & FWRITE) {
501		selwakeup(&pti->pt_selw);
502		wakeup(TSA_PTC_WRITE(tp));
503	}
504}
505
506__private_extern__ int
507ptcopen(dev_t dev, __unused int flag, __unused int devtype, __unused proc_t p)
508{
509	struct tty_dev_t *driver;
510	struct ptmx_ioctl *pti = pty_get_ioctl(dev, PF_OPEN_M, &driver);
511	if (pti == NULL) {
512	        return (ENXIO);
513	} else if (pti == (struct ptmx_ioctl*)-1) {
514		return (EREDRIVEOPEN);
515	}
516
517	struct tty *tp = pti->pt_tty;
518	tty_lock(tp);
519
520	/* If master is open OR slave is still draining, pty is still busy */
521	if (tp->t_oproc || (tp->t_state & TS_ISOPEN)) {
522		tty_unlock(tp);
523		/*
524		 * If master is closed, we are the only reference, so we
525		 * need to clear the master open bit
526		 */
527		if (!tp->t_oproc) {
528			pty_free_ioctl(dev, PF_OPEN_M);
529		}
530		return EBUSY;
531	}
532	tp->t_oproc = ptsstart;
533	CLR(tp->t_state, TS_ZOMBIE);
534	SET(tp->t_state, TS_IOCTL_NOT_OK);
535#ifdef sun4c
536	tp->t_stop = ptsstop;
537#endif
538	(void)(*linesw[tp->t_line].l_modem)(tp, 1);
539	tp->t_lflag &= ~EXTPROC;
540
541	if (driver->open_reset) {
542		pti->pt_flags = PF_UNLOCKED;
543		pti->pt_send = 0;
544		pti->pt_ucntl = 0;
545	}
546
547	tty_unlock(tp);
548	return 0;
549}
550
551__private_extern__ int
552ptcclose(dev_t dev, __unused int flags, __unused int fmt, __unused proc_t p)
553{
554	struct tty_dev_t *driver;
555	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
556	struct tty *tp;
557
558	if (pti == NULL)
559		return (ENXIO);
560	tp = pti->pt_tty;
561	tty_lock(tp);
562
563	(void)(*linesw[tp->t_line].l_modem)(tp, 0);
564
565	/*
566	 * XXX MDMBUF makes no sense for ptys but would inhibit the above
567	 * l_modem().  CLOCAL makes sense but isn't supported.   Special
568	 * l_modem()s that ignore carrier drop make no sense for ptys but
569	 * may be in use because other parts of the line discipline make
570	 * sense for ptys.  Recover by doing everything that a normal
571	 * ttymodem() would have done except for sending a SIGHUP.
572	 */
573	if (tp->t_state & TS_ISOPEN) {
574		tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
575		tp->t_state |= TS_ZOMBIE;
576		ttyflush(tp, FREAD | FWRITE);
577	}
578
579	tp->t_oproc = 0;		/* mark closed */
580
581	tty_unlock(tp);
582
583	pty_free_ioctl(dev, PF_OPEN_M);
584#if CONFIG_MACF
585	if (driver->mac_notify) {
586		mac_pty_notify_close(p, tp, dev, NULL);
587	}
588#endif
589
590	return (0);
591}
592
593__private_extern__ int
594ptcread(dev_t dev, struct uio *uio, int flag)
595{
596	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, NULL);
597	struct tty *tp;
598	char buf[BUFSIZ];
599	int error = 0, cc;
600
601	if (pti == NULL)
602		return (ENXIO);
603	tp = pti->pt_tty;
604	tty_lock(tp);
605
606	/*
607	 * We want to block until the slave
608	 * is open, and there's something to read;
609	 * but if we lost the slave or we're NBIO,
610	 * then return the appropriate error instead.
611	 */
612	for (;;) {
613		if (tp->t_state & TS_ISOPEN) {
614			if (pti->pt_flags & PF_PKT && pti->pt_send) {
615				error = ureadc((int)pti->pt_send, uio);
616				if (error)
617					goto out;
618				if (pti->pt_send & TIOCPKT_IOCTL) {
619					cc = MIN((int)uio_resid(uio),
620						(int)sizeof(tp->t_termios));
621					uiomove((caddr_t)&tp->t_termios, cc,
622						uio);
623				}
624				pti->pt_send = 0;
625				goto out;
626			}
627			if (pti->pt_flags & PF_UCNTL && pti->pt_ucntl) {
628				error = ureadc((int)pti->pt_ucntl, uio);
629				if (error)
630					goto out;
631				pti->pt_ucntl = 0;
632				goto out;
633			}
634			if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
635				break;
636		}
637		if ((tp->t_state & TS_CONNECTED) == 0)
638			goto out;	/* EOF */
639		if (flag & IO_NDELAY) {
640			error = EWOULDBLOCK;
641			goto out;
642		}
643		error = ttysleep(tp, TSA_PTC_READ(tp), TTIPRI | PCATCH, __FUNCTION__, 0);
644		if (error)
645		        goto out;
646	}
647	if (pti->pt_flags & (PF_PKT|PF_UCNTL))
648		error = ureadc(0, uio);
649	while (uio_resid(uio) > 0 && error == 0) {
650		cc = q_to_b(&tp->t_outq, (u_char *)buf, MIN((int)uio_resid(uio), BUFSIZ));
651		if (cc <= 0)
652			break;
653		error = uiomove(buf, cc, uio);
654	}
655	(*linesw[tp->t_line].l_start)(tp);
656
657out:
658	tty_unlock(tp);
659
660	return (error);
661}
662
663/*
664 * Line discipline callback
665 *
666 * Locks:	tty_lock() is assumed held on entry and exit.
667 */
668__private_extern__ int
669ptsstop(struct tty* tp, int flush)
670{
671	struct ptmx_ioctl *pti = pty_get_ioctl(tp->t_dev, 0, NULL);
672	int flag;
673
674	if (pti == NULL)
675		return (ENXIO);
676
677	/* note: FLUSHREAD and FLUSHWRITE already ok */
678	if (flush == 0) {
679		flush = TIOCPKT_STOP;
680		pti->pt_flags |= PF_STOPPED;
681	} else
682		pti->pt_flags &= ~PF_STOPPED;
683	pti->pt_send |= flush;
684	/* change of perspective */
685	flag = 0;
686	if (flush & FREAD)
687		flag |= FWRITE;
688	if (flush & FWRITE)
689		flag |= FREAD;
690	ptcwakeup(tp, flag);
691	return 0;
692}
693
694__private_extern__ int
695ptsreset(__unused int uban)
696{
697	return (0);
698}
699
700int
701ptsselect(dev_t dev, int rw, void *wql, proc_t p)
702{
703	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, NULL);
704	struct tty *tp;
705	int retval = 0;
706
707	if (pti == NULL)
708		return (ENXIO);
709	tp = pti->pt_tty;
710	if (tp == NULL)
711		return (ENXIO);
712
713	tty_lock(tp);
714
715	switch (rw) {
716	case FREAD:
717		if (ISSET(tp->t_state, TS_ZOMBIE)) {
718			retval = 1;
719			break;
720		}
721
722		retval = ttnread(tp);
723		if (retval > 0) {
724			break;
725		}
726
727		selrecord(p, &tp->t_rsel, wql);
728		break;
729	case FWRITE:
730		if (ISSET(tp->t_state, TS_ZOMBIE)) {
731			retval = 1;
732			break;
733		}
734
735		if ((tp->t_outq.c_cc <= tp->t_lowat) &&
736				ISSET(tp->t_state, TS_CONNECTED)) {
737			retval = tp->t_hiwat - tp->t_outq.c_cc;
738			break;
739		}
740
741		selrecord(p, &tp->t_wsel, wql);
742		break;
743	}
744
745	tty_unlock(tp);
746	return (retval);
747}
748
749__private_extern__ int
750ptcselect(dev_t dev, int rw, void *wql, proc_t p)
751{
752	struct tty_dev_t *driver;
753	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
754	struct tty *tp;
755	int retval = 0;
756
757	if (pti == NULL)
758		return (ENXIO);
759	tp = pti->pt_tty;
760	tty_lock(tp);
761
762	if ((tp->t_state & TS_CONNECTED) == 0) {
763		retval = 1;
764		goto out;
765	}
766	switch (rw) {
767
768	case FREAD:
769		/*
770		 * Need to block timeouts (ttrstart).
771		 */
772		if ((tp->t_state&TS_ISOPEN) &&
773		     tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
774			retval = (driver->fix_7828447) ? tp->t_outq.c_cc : 1;
775			break;
776		}
777		/* FALLTHROUGH */
778
779	case 0:					/* exceptional */
780		if ((tp->t_state&TS_ISOPEN) &&
781		    ((pti->pt_flags & PF_PKT && pti->pt_send) ||
782		     (pti->pt_flags & PF_UCNTL && pti->pt_ucntl))) {
783			retval = 1;
784			break;
785		}
786		selrecord(p, &pti->pt_selr, wql);
787		break;
788
789
790	case FWRITE:
791		if (tp->t_state&TS_ISOPEN) {
792			if (pti->pt_flags & PF_REMOTE) {
793			    if (tp->t_canq.c_cc == 0) {
794				retval = (driver->fix_7828447) ? (TTYHOG - 1) : 1;
795				break;
796			    }
797			} else {
798			    retval = (TTYHOG - 2) - (tp->t_rawq.c_cc + tp->t_canq.c_cc);
799			    if (retval > 0) {
800				    retval = (driver->fix_7828447) ? retval : 1;
801				    break;
802			    }
803			    if (tp->t_canq.c_cc == 0 && (tp->t_lflag&ICANON)) {
804				    retval = 1;
805				    break;
806			    }
807			    retval = 0;
808			}
809		}
810		selrecord(p, &pti->pt_selw, wql);
811		break;
812
813	}
814out:
815	tty_unlock(tp);
816
817	return (retval);
818}
819
820__private_extern__ int
821ptcstop(__unused struct tty *tp, __unused int flush)
822{
823	return (0);
824}
825
826__private_extern__ int
827ptcreset(__unused int uban)
828{
829	return (0);
830}
831
832__private_extern__ int
833ptcwrite(dev_t dev, struct uio *uio, int flag)
834{
835	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, NULL);
836	struct tty *tp;
837	u_char *cp = NULL;
838	int cc = 0;
839	u_char locbuf[BUFSIZ];
840	int wcnt = 0;
841	int error = 0;
842
843	if (pti == NULL)
844		return (ENXIO);
845	tp = pti->pt_tty;
846	tty_lock(tp);
847
848again:
849	if ((tp->t_state & TS_ISOPEN) == 0)
850		goto block;
851	if (pti->pt_flags & PF_REMOTE) {
852		if (tp->t_canq.c_cc)
853			goto block;
854		while ((uio_resid(uio) > 0 || cc > 0) &&
855		       tp->t_canq.c_cc < TTYHOG - 1) {
856			if (cc == 0) {
857				cc = MIN((int)uio_resid(uio), BUFSIZ);
858				cc = MIN(cc, TTYHOG - 1 - tp->t_canq.c_cc);
859				cp = locbuf;
860				error = uiomove((caddr_t)cp, cc, uio);
861				if (error)
862					goto out;
863				/* check again for safety */
864				if ((tp->t_state & TS_ISOPEN) == 0) {
865					/* adjust as usual */
866					uio_setresid(uio, (uio_resid(uio) + cc));
867					error = EIO;
868					goto out;
869				}
870			}
871			if (cc > 0) {
872				cc = b_to_q((u_char *)cp, cc, &tp->t_canq);
873				/*
874				 * XXX we don't guarantee that the canq size
875				 * is >= TTYHOG, so the above b_to_q() may
876				 * leave some bytes uncopied.  However, space
877				 * is guaranteed for the null terminator if
878				 * we don't fail here since (TTYHOG - 1) is
879				 * not a multiple of CBSIZE.
880				 */
881				if (cc > 0)
882					break;
883			}
884		}
885		/* adjust for data copied in but not written */
886		uio_setresid(uio, (uio_resid(uio) + cc));
887		(void) putc(0, &tp->t_canq);
888		ttwakeup(tp);
889		wakeup(TSA_PTS_READ(tp));
890		goto out;
891	}
892	while (uio_resid(uio) > 0 || cc > 0) {
893		if (cc == 0) {
894			cc = MIN((int)uio_resid(uio), BUFSIZ);
895			cp = locbuf;
896			error = uiomove((caddr_t)cp, cc, uio);
897			if (error)
898				goto out;
899			/* check again for safety */
900			if ((tp->t_state & TS_ISOPEN) == 0) {
901				/* adjust for data copied in but not written */
902				uio_setresid(uio, (uio_resid(uio) + cc));
903				error = EIO;
904				goto out;
905			}
906		}
907		while (cc > 0) {
908			if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
909			   (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
910				wakeup(TSA_HUP_OR_INPUT(tp));
911				goto block;
912			}
913			(*linesw[tp->t_line].l_rint)(*cp++, tp);
914			wcnt++;
915			cc--;
916		}
917		cc = 0;
918	}
919out:
920	tty_unlock(tp);
921
922	return (error);
923
924block:
925	/*
926	 * Come here to wait for slave to open, for space
927	 * in outq, or space in rawq, or an empty canq.
928	 */
929	if ((tp->t_state & TS_CONNECTED) == 0) {
930		/* adjust for data copied in but not written */
931		uio_setresid(uio, (uio_resid(uio) + cc));
932		error = EIO;
933		goto out;
934	}
935	if (flag & IO_NDELAY) {
936		/* adjust for data copied in but not written */
937		uio_setresid(uio, (uio_resid(uio) + cc));
938		if (wcnt == 0)
939			error = EWOULDBLOCK;
940		goto out;
941	}
942	error = ttysleep(tp, TSA_PTC_WRITE(tp), TTOPRI | PCATCH, __FUNCTION__, 0);
943	if (error) {
944		/* adjust for data copied in but not written */
945		uio_setresid(uio, (uio_resid(uio) + cc));
946		goto out;
947	}
948	goto again;
949}
950
951__private_extern__ int
952ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
953{
954	struct tty_dev_t *driver;
955	struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
956	struct tty *tp;
957	int stop, error = 0;
958	int allow_ext_ioctl = 1;
959
960	if (pti == NULL)
961		return (ENXIO);
962	tp = pti->pt_tty;
963	tty_lock(tp);
964
965	u_char *cc = tp->t_cc;
966
967	/*
968	 * Do not permit extended ioctls on the master side of the pty unless
969	 * the slave side has been successfully opened and initialized.
970	 */
971	if (major(dev) == driver->master &&
972	    driver->fix_7070978 &&
973	    ISSET(tp->t_state, TS_IOCTL_NOT_OK)) {
974		allow_ext_ioctl = 0;
975	}
976
977	/*
978	 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
979	 * ttywflush(tp) will hang if there are characters in the outq.
980	 */
981	if (cmd == TIOCEXT && allow_ext_ioctl) {
982		/*
983		 * When the EXTPROC bit is being toggled, we need
984		 * to send an TIOCPKT_IOCTL if the packet driver
985		 * is turned on.
986		 */
987		if (*(int *)data) {
988			if (pti->pt_flags & PF_PKT) {
989				pti->pt_send |= TIOCPKT_IOCTL;
990				ptcwakeup(tp, FREAD);
991			}
992			tp->t_lflag |= EXTPROC;
993		} else {
994			if ((tp->t_lflag & EXTPROC) &&
995			    (pti->pt_flags & PF_PKT)) {
996				pti->pt_send |= TIOCPKT_IOCTL;
997				ptcwakeup(tp, FREAD);
998			}
999			tp->t_lflag &= ~EXTPROC;
1000		}
1001		goto out;
1002	} else
1003	if (cdevsw[major(dev)].d_open == ptcopen) {
1004		switch (cmd) {
1005
1006		case TIOCGPGRP:
1007			/*
1008			 * We aviod calling ttioctl on the controller since,
1009			 * in that case, tp must be the controlling terminal.
1010			 */
1011			*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
1012			goto out;
1013
1014		case TIOCPKT:
1015			if (*(int *)data) {
1016			        if (pti->pt_flags & PF_UCNTL) {
1017					error = EINVAL;
1018					goto out;
1019				}
1020				pti->pt_flags |= PF_PKT;
1021			} else
1022				pti->pt_flags &= ~PF_PKT;
1023			goto out;
1024
1025		case TIOCUCNTL:
1026			if (*(int *)data) {
1027			        if (pti->pt_flags & PF_PKT) {
1028					error = EINVAL;
1029					goto out;
1030				}
1031				pti->pt_flags |= PF_UCNTL;
1032			} else
1033				pti->pt_flags &= ~PF_UCNTL;
1034			goto out;
1035
1036		case TIOCREMOTE:
1037			if (*(int *)data)
1038				pti->pt_flags |= PF_REMOTE;
1039			else
1040				pti->pt_flags &= ~PF_REMOTE;
1041			ttyflush(tp, FREAD|FWRITE);
1042			goto out;
1043
1044		case TIOCSETP:
1045		case TIOCSETN:
1046		case TIOCSETD:
1047		case TIOCSETA_32:
1048		case TIOCSETAW_32:
1049		case TIOCSETAF_32:
1050		case TIOCSETA_64:
1051		case TIOCSETAW_64:
1052		case TIOCSETAF_64:
1053			ndflush(&tp->t_outq, tp->t_outq.c_cc);
1054			break;
1055
1056		case TIOCSIG:
1057			if (*(unsigned int *)data >= NSIG ||
1058			    *(unsigned int *)data == 0) {
1059				error = EINVAL;
1060				goto out;
1061			}
1062			if ((tp->t_lflag&NOFLSH) == 0)
1063				ttyflush(tp, FREAD|FWRITE);
1064			if ((*(unsigned int *)data == SIGINFO) &&
1065			    ((tp->t_lflag&NOKERNINFO) == 0))
1066				ttyinfo_locked(tp);
1067			/*
1068			 * SAFE: All callers drop the lock on return and
1069			 * SAFE: the linesw[] will short circut this call
1070			 * SAFE: if the ioctl() is eaten before the lower
1071			 * SAFE: level code gets to see it.
1072			 */
1073			tty_unlock(tp);
1074			tty_pgsignal(tp, *(unsigned int *)data, 1);
1075			tty_lock(tp);
1076			goto out;
1077
1078		case TIOCPTYGRANT:	/* grantpt(3) */
1079			/*
1080			 * Change the uid of the slave to that of the calling
1081			 * thread, change the gid of the slave to GID_TTY,
1082			 * change the mode to 0620 (rw--w----).
1083			 */
1084			{
1085				error = _devfs_setattr(pti->pt_devhandle, 0620, kauth_getuid(), GID_TTY);
1086				if (major(dev) == driver->master) {
1087					if (driver->mac_notify) {
1088#if CONFIG_MACF
1089						if (!error) {
1090							tty_unlock(tp);
1091							mac_pty_notify_grant(p, tp, dev, NULL);
1092							tty_lock(tp);
1093						}
1094#endif
1095					} else {
1096						error = 0;
1097					}
1098				}
1099				goto out;
1100			}
1101
1102		case TIOCPTYGNAME:	/* ptsname(3) */
1103			/*
1104			 * Report the name of the slave device in *data
1105			 * (128 bytes max.).  Use the same template string
1106			 * used for calling devfs_make_node() to create it.
1107			 */
1108			pty_get_name(dev, data, 128);
1109			error = 0;
1110			goto out;
1111
1112		case TIOCPTYUNLK:	/* unlockpt(3) */
1113			/*
1114			 * Unlock the slave device so that it can be opened.
1115			 */
1116			if (major(dev) == driver->master) {
1117				pti->pt_flags |= PF_UNLOCKED;
1118			}
1119			error = 0;
1120			goto out;
1121		}
1122
1123		/*
1124		 * Fail all other calls; pty masters are not serial devices;
1125		 * we only pretend they are when the slave side of the pty is
1126		 * already open.
1127		 */
1128		if (!allow_ext_ioctl) {
1129			error = ENOTTY;
1130			goto out;
1131		}
1132	}
1133	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1134	if (error == ENOTTY) {
1135		error = ttioctl_locked(tp, cmd, data, flag, p);
1136		if (error == ENOTTY) {
1137			if (pti->pt_flags & PF_UCNTL && (cmd & ~0xff) == UIOCCMD(0)) {
1138				/* Process the UIOCMD ioctl group */
1139				if (cmd & 0xff) {
1140					pti->pt_ucntl = (u_char)cmd;
1141					ptcwakeup(tp, FREAD);
1142				}
1143				error = 0;
1144				goto out;
1145			} else if (cmd == TIOCSBRK || cmd == TIOCCBRK) {
1146				/*
1147				 * POSIX conformance; rdar://3936338
1148				 *
1149				 * Clear ENOTTY in the case of setting or
1150				 * clearing a break failing because pty's
1151				 * don't support break like real serial
1152				 * ports.
1153				 */
1154				error = 0;
1155				goto out;
1156			}
1157		}
1158	}
1159
1160	/*
1161	 * If external processing and packet mode send ioctl packet.
1162	 */
1163	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
1164		switch(cmd) {
1165		case TIOCSETA_32:
1166		case TIOCSETAW_32:
1167		case TIOCSETAF_32:
1168		case TIOCSETA_64:
1169		case TIOCSETAW_64:
1170		case TIOCSETAF_64:
1171		case TIOCSETP:
1172		case TIOCSETN:
1173		case TIOCSETC:
1174		case TIOCSLTC:
1175		case TIOCLBIS:
1176		case TIOCLBIC:
1177		case TIOCLSET:
1178			pti->pt_send |= TIOCPKT_IOCTL;
1179			ptcwakeup(tp, FREAD);
1180		default:
1181			break;
1182		}
1183	}
1184	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1185		&& CCEQ(cc[VSTART], CTRL('q'));
1186	if (pti->pt_flags & PF_NOSTOP) {
1187		if (stop) {
1188			pti->pt_send &= ~TIOCPKT_NOSTOP;
1189			pti->pt_send |= TIOCPKT_DOSTOP;
1190			pti->pt_flags &= ~PF_NOSTOP;
1191			ptcwakeup(tp, FREAD);
1192		}
1193	} else {
1194		if (!stop) {
1195			pti->pt_send &= ~TIOCPKT_DOSTOP;
1196			pti->pt_send |= TIOCPKT_NOSTOP;
1197			pti->pt_flags |= PF_NOSTOP;
1198			ptcwakeup(tp, FREAD);
1199		}
1200	}
1201out:
1202	tty_unlock(tp);
1203
1204	return (error);
1205}
1206