]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty_ptmx.c
xnu-2050.7.9.tar.gz
[apple/xnu.git] / bsd / kern / tty_ptmx.c
1 /*
2 * Copyright (c) 1997-2010 Apple Computer, 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 /*
64 * Pseudo-teletype Driver
65 * (Actually two drivers, requiring two entries in 'cdevsw')
66 */
67 #include "pty.h" /* XXX */
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/ioctl.h>
72 #include <sys/proc_internal.h>
73 #include <sys/kauth.h>
74 #include <sys/tty.h>
75 #include <sys/conf.h>
76 #include <sys/file_internal.h>
77 #include <sys/uio_internal.h>
78 #include <sys/kernel.h>
79 #include <sys/vnode.h>
80 #include <sys/vnode_internal.h> /* _devfs_setattr() */
81 #include <sys/stat.h> /* _devfs_setattr() */
82 #include <sys/user.h>
83 #include <sys/signalvar.h>
84 #include <sys/sysctl.h>
85 #include <miscfs/devfs/devfs.h>
86 #include <miscfs/devfs/devfsdefs.h> /* DEVFS_LOCK()/DEVFS_UNLOCK() */
87
88 /* XXX belongs in devfs somewhere - LATER */
89 int _devfs_setattr(void *, unsigned short, uid_t, gid_t);
90
91
92 #define FREE_BSDSTATIC __private_extern__
93 #define d_devtotty_t struct tty **
94
95 /*
96 * Forward declarations
97 */
98 int ptmx_init(int n_ptys);
99 static void ptsd_start(struct tty *tp);
100 static void ptmx_wakeup(struct tty *tp, int flag);
101 FREE_BSDSTATIC d_open_t ptsd_open;
102 FREE_BSDSTATIC d_close_t ptsd_close;
103 FREE_BSDSTATIC d_read_t ptsd_read;
104 FREE_BSDSTATIC d_write_t ptsd_write;
105 FREE_BSDSTATIC d_ioctl_t cptyioctl; /* common ioctl */
106 FREE_BSDSTATIC d_stop_t ptsd_stop;
107 FREE_BSDSTATIC d_reset_t ptsd_reset;
108 FREE_BSDSTATIC d_devtotty_t ptydevtotty;
109 FREE_BSDSTATIC d_open_t ptmx_open;
110 FREE_BSDSTATIC d_close_t ptmx_close;
111 FREE_BSDSTATIC d_read_t ptmx_read;
112 FREE_BSDSTATIC d_write_t ptmx_write;
113 FREE_BSDSTATIC d_stop_t ptmx_stop; /* NO-OP */
114 FREE_BSDSTATIC d_reset_t ptmx_reset;
115 FREE_BSDSTATIC d_select_t ptmx_select;
116 FREE_BSDSTATIC d_select_t ptsd_select;
117
118 static int ptmx_major; /* dynamically assigned major number */
119 static struct cdevsw ptmx_cdev = {
120 ptmx_open, ptmx_close, ptmx_read, ptmx_write,
121 cptyioctl, ptmx_stop, ptmx_reset, 0,
122 ptmx_select, eno_mmap, eno_strat, eno_getc,
123 eno_putc, D_TTY
124 };
125
126 static int ptsd_major; /* dynamically assigned major number */
127 static struct cdevsw ptsd_cdev = {
128 ptsd_open, ptsd_close, ptsd_read, ptsd_write,
129 cptyioctl, ptsd_stop, ptsd_reset, 0,
130 ptsd_select, eno_mmap, eno_strat, eno_getc,
131 eno_putc, D_TTY
132 };
133
134 /*
135 * XXX Should be devfs function... and use VATTR mechanisms, per
136 * XXX vnode_setattr2(); only we maybe can't really get back to the
137 * XXX vnode here for cloning devices (but it works for *cloned* devices
138 * XXX that are not themselves cloning).
139 *
140 * Returns: 0 Success
141 * namei:???
142 * vnode_setattr:???
143 */
144 int
145 _devfs_setattr(void * handle, unsigned short mode, uid_t uid, gid_t gid)
146 {
147 devdirent_t *direntp = (devdirent_t *)handle;
148 devnode_t *devnodep;
149 int error = EACCES;
150 vfs_context_t ctx = vfs_context_current();;
151 struct vnode_attr va;
152
153 VATTR_INIT(&va);
154 VATTR_SET(&va, va_uid, uid);
155 VATTR_SET(&va, va_gid, gid);
156 VATTR_SET(&va, va_mode, mode & ALLPERMS);
157
158 /*
159 * If the TIOCPTYGRANT loses the race with the clone operation because
160 * this function is not part of devfs, and therefore can't take the
161 * devfs lock to protect the direntp update, then force user space to
162 * redrive the grant request.
163 */
164 if (direntp == NULL || (devnodep = direntp->de_dnp) == NULL) {
165 error = ERESTART;
166 goto out;
167 }
168
169 /*
170 * Only do this if we are operating on device that doesn't clone
171 * each time it's referenced. We perform a lookup on the device
172 * to insure we get the right instance. We can't just use the call
173 * to devfs_dntovn() to get the vp for the operation, because
174 * dn_dvm may not have been initialized.
175 */
176 if (devnodep->dn_clone == NULL) {
177 struct nameidata nd;
178 char name[128];
179
180 snprintf(name, sizeof(name), "/dev/%s", direntp->de_name);
181 NDINIT(&nd, LOOKUP, OP_SETATTR, FOLLOW, UIO_SYSSPACE, CAST_USER_ADDR_T(name), ctx);
182 error = namei(&nd);
183 if (error)
184 goto out;
185 error = vnode_setattr(nd.ni_vp, &va, ctx);
186 vnode_put(nd.ni_vp);
187 nameidone(&nd);
188 goto out;
189 }
190
191 out:
192 return(error);
193 }
194
195
196
197 #define BUFSIZ 100 /* Chunk size iomoved to/from user */
198
199 /*
200 * ptmx == /dev/ptmx
201 * ptsd == /dev/pts[0123456789]{3}
202 */
203 #define PTMX_TEMPLATE "ptmx"
204 #define PTSD_TEMPLATE "ttys%03d"
205
206 /*
207 * System-wide limit on the max number of cloned ptys
208 */
209 #define PTMX_MAX_DEFAULT 127 /* 128 entries */
210 #define PTMX_MAX_HARD 999 /* 1000 entries, due to PTSD_TEMPLATE */
211
212 static int ptmx_max = PTMX_MAX_DEFAULT; /* default # of clones we allow */
213
214 /* Range enforcement for the sysctl */
215 static int
216 sysctl_ptmx_max(__unused struct sysctl_oid *oidp, __unused void *arg1,
217 __unused int arg2, struct sysctl_req *req)
218 {
219 int new_value, changed;
220 int error = sysctl_io_number(req, ptmx_max, sizeof(int), &new_value, &changed);
221 if (changed) {
222 if (new_value > 0 && new_value <= PTMX_MAX_HARD)
223 ptmx_max = new_value;
224 else
225 error = EINVAL;
226 }
227 return(error);
228 }
229
230 SYSCTL_NODE(_kern, KERN_TTY, tty, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "TTY");
231 SYSCTL_PROC(_kern_tty, OID_AUTO, ptmx_max,
232 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
233 &ptmx_max, 0, &sysctl_ptmx_max, "I", "ptmx_max");
234
235
236 /*
237 * ptmx_ioctl is a pointer to a list of pointers to tty structures which is
238 * grown, as necessary, copied, and replaced, but never shrunk. The ioctl
239 * structures themselves pointed to from this list come and go as needed.
240 */
241 struct ptmx_ioctl {
242 struct tty *pt_tty; /* pointer to ttymalloc()'ed data */
243 int pt_flags;
244 struct selinfo pt_selr;
245 struct selinfo pt_selw;
246 u_char pt_send;
247 u_char pt_ucntl;
248 void *pt_devhandle; /* cloned slave device handle */
249 };
250
251 #define PF_PKT 0x0008 /* packet mode */
252 #define PF_STOPPED 0x0010 /* user told stopped */
253 #define PF_REMOTE 0x0020 /* remote and flow controlled input */
254 #define PF_NOSTOP 0x0040
255 #define PF_UCNTL 0x0080 /* user control mode */
256 #define PF_UNLOCKED 0x0100 /* slave unlock (master open resets) */
257 #define PF_OPEN_M 0x0200 /* master is open */
258 #define PF_OPEN_S 0x0400 /* slave is open */
259
260 static int ptmx_clone(dev_t dev, int minor);
261
262 /*
263 * Set of locks to keep the interaction between kevents and revoke
264 * from causing havoc.
265 */
266
267 #define LOG2_PTSD_KE_NLCK 2
268 #define PTSD_KE_NLCK (1l << LOG2_PTSD_KE_NLCK)
269 #define PTSD_KE_LOCK_INDEX(x) ((x) & (PTSD_KE_NLCK - 1))
270
271 static lck_mtx_t ptsd_kevent_lock[PTSD_KE_NLCK];
272
273 static void
274 ptsd_kevent_lock_init(void)
275 {
276 int i;
277 lck_grp_t *lgrp = lck_grp_alloc_init("ptsd kevent", LCK_GRP_ATTR_NULL);
278
279 for (i = 0; i < PTSD_KE_NLCK; i++)
280 lck_mtx_init(&ptsd_kevent_lock[i], lgrp, LCK_ATTR_NULL);
281 }
282
283 static void
284 ptsd_kevent_mtx_lock(int minor)
285 {
286 lck_mtx_lock(&ptsd_kevent_lock[PTSD_KE_LOCK_INDEX(minor)]);
287 }
288
289 static void
290 ptsd_kevent_mtx_unlock(int minor)
291 {
292 lck_mtx_unlock(&ptsd_kevent_lock[PTSD_KE_LOCK_INDEX(minor)]);
293 }
294
295 int
296 ptmx_init( __unused int config_count)
297 {
298 /*
299 * We start looking at slot 10, since there are inits that will
300 * stomp explicit slots (e.g. vndevice stomps 1) below that.
301 */
302
303 /* Get a major number for /dev/ptmx */
304 if((ptmx_major = cdevsw_add(-15, &ptmx_cdev)) == -1) {
305 printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
306 return (ENOENT);
307 }
308
309 if (cdevsw_setkqueueok(ptmx_major, &ptmx_cdev, 0) == -1) {
310 panic("Failed to set flags on ptmx cdevsw entry.");
311 }
312
313 /* Get a major number for /dev/pts/nnn */
314 if ((ptsd_major = cdevsw_add(-15, &ptsd_cdev)) == -1) {
315 (void)cdevsw_remove(ptmx_major, &ptmx_cdev);
316 printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
317 return (ENOENT);
318 }
319
320 if (cdevsw_setkqueueok(ptsd_major, &ptsd_cdev, 0) == -1) {
321 panic("Failed to set flags on ptmx cdevsw entry.");
322 }
323
324 /*
325 * Locks to guard against races between revoke and kevents
326 */
327 ptsd_kevent_lock_init();
328
329 /* Create the /dev/ptmx device {<major>,0} */
330 (void)devfs_make_node_clone(makedev(ptmx_major, 0),
331 DEVFS_CHAR, UID_ROOT, GID_TTY, 0666,
332 ptmx_clone, PTMX_TEMPLATE);
333 return (0);
334 }
335
336
337 static struct _ptmx_ioctl_state {
338 struct ptmx_ioctl **pis_ioctl_list; /* pointer vector */
339 int pis_total; /* total slots */
340 int pis_free; /* free slots */
341 } _state;
342 #define PTMX_GROW_VECTOR 16 /* Grow by this many slots at a time */
343
344 /*
345 * Given a minor number, return the corresponding structure for that minor
346 * number. If there isn't one, and the create flag is specified, we create
347 * one if possible.
348 *
349 * Parameters: minor Minor number of ptmx device
350 * open_flag PF_OPEN_M First open of master
351 * PF_OPEN_S First open of slave
352 * 0 Just want ioctl struct
353 *
354 * Returns: NULL Did not exist/could not create
355 * !NULL structure corresponding minor number
356 *
357 * Locks: tty_lock() on ptmx_ioctl->pt_tty NOT held on entry or exit.
358 */
359 static struct ptmx_ioctl *
360 ptmx_get_ioctl(int minor, int open_flag)
361 {
362 struct ptmx_ioctl *new_ptmx_ioctl;
363
364 if (open_flag & PF_OPEN_M) {
365
366 /*
367 * If we are about to allocate more memory, but we have
368 * already hit the administrative limit, then fail the
369 * operation.
370 *
371 * Note: Subtract free from total when making this
372 * check to allow unit increments, rather than
373 * snapping to the nearest PTMX_GROW_VECTOR...
374 */
375 if ((_state.pis_total - _state.pis_free) >= ptmx_max) {
376 return (NULL);
377 }
378
379 MALLOC(new_ptmx_ioctl, struct ptmx_ioctl *, sizeof(struct ptmx_ioctl), M_TTYS, M_WAITOK|M_ZERO);
380 if (new_ptmx_ioctl == NULL) {
381 return (NULL);
382 }
383
384 if ((new_ptmx_ioctl->pt_tty = ttymalloc()) == NULL) {
385 FREE(new_ptmx_ioctl, M_TTYS);
386 return (NULL);
387 }
388
389 /*
390 * Hold the DEVFS_LOCK() over this whole operation; devfs
391 * itself does this over malloc/free as well, so this should
392 * be safe to do. We hold it longer than we want to, but
393 * doing so avoids a reallocation race on the minor number.
394 */
395 DEVFS_LOCK();
396 /* Need to allocate a larger vector? */
397 if (_state.pis_free == 0) {
398 struct ptmx_ioctl **new_pis_ioctl_list;
399 struct ptmx_ioctl **old_pis_ioctl_list = NULL;
400
401 /* Yes. */
402 MALLOC(new_pis_ioctl_list, struct ptmx_ioctl **, sizeof(struct ptmx_ioctl *) * (_state.pis_total + PTMX_GROW_VECTOR), M_TTYS, M_WAITOK|M_ZERO);
403 if (new_pis_ioctl_list == NULL) {
404 ttyfree(new_ptmx_ioctl->pt_tty);
405 DEVFS_UNLOCK();
406 FREE(new_ptmx_ioctl, M_TTYS);
407 return (NULL);
408 }
409
410 /* If this is not the first time, copy the old over */
411 bcopy(_state.pis_ioctl_list, new_pis_ioctl_list, sizeof(struct ptmx_ioctl *) * _state.pis_total);
412 old_pis_ioctl_list = _state.pis_ioctl_list;
413 _state.pis_ioctl_list = new_pis_ioctl_list;
414 _state.pis_free += PTMX_GROW_VECTOR;
415 _state.pis_total += PTMX_GROW_VECTOR;
416 if (old_pis_ioctl_list)
417 FREE(old_pis_ioctl_list, M_TTYS);
418 }
419
420 if (_state.pis_ioctl_list[minor] != NULL) {
421 ttyfree(new_ptmx_ioctl->pt_tty);
422 DEVFS_UNLOCK();
423 FREE(new_ptmx_ioctl, M_TTYS);
424
425 /* Special error value so we know to redrive the open, we've been raced */
426 return (struct ptmx_ioctl*)-1;
427
428 }
429
430 /* Vector is large enough; grab a new ptmx_ioctl */
431
432 /* Now grab a free slot... */
433 _state.pis_ioctl_list[minor] = new_ptmx_ioctl;
434
435 /* reduce free count */
436 _state.pis_free--;
437
438 _state.pis_ioctl_list[minor]->pt_flags |= PF_OPEN_M;
439 DEVFS_UNLOCK();
440
441 /* Create the /dev/ttysXXX device {<major>,XXX} */
442 _state.pis_ioctl_list[minor]->pt_devhandle = devfs_make_node(
443 makedev(ptsd_major, minor),
444 DEVFS_CHAR, UID_ROOT, GID_TTY, 0620,
445 PTSD_TEMPLATE, minor);
446 if (_state.pis_ioctl_list[minor]->pt_devhandle == NULL) {
447 printf("devfs_make_node() call failed for ptmx_get_ioctl()!!!!\n");
448 }
449 } else if (open_flag & PF_OPEN_S) {
450 DEVFS_LOCK();
451 _state.pis_ioctl_list[minor]->pt_flags |= PF_OPEN_S;
452 DEVFS_UNLOCK();
453 }
454 return (_state.pis_ioctl_list[minor]);
455 }
456
457 /*
458 * Locks: tty_lock() of old_ptmx_ioctl->pt_tty NOT held for this call.
459 */
460 static int
461 ptmx_free_ioctl(int minor, int open_flag)
462 {
463 struct ptmx_ioctl *old_ptmx_ioctl = NULL;
464
465 DEVFS_LOCK();
466 _state.pis_ioctl_list[minor]->pt_flags &= ~(open_flag);
467
468 /*
469 * Was this the last close? We will recognize it because we only get
470 * a notification on the last close of a device, and we will have
471 * cleared both the master and the slave open bits in the flags.
472 */
473 if (!(_state.pis_ioctl_list[minor]->pt_flags & (PF_OPEN_M|PF_OPEN_S))) {
474 /* Mark as free so it can be reallocated later */
475 old_ptmx_ioctl = _state.pis_ioctl_list[ minor];
476 }
477 DEVFS_UNLOCK();
478
479 /* Free old after dropping lock */
480 if (old_ptmx_ioctl != NULL) {
481 /*
482 * XXX See <rdar://5348651> and <rdar://4854638>
483 *
484 * XXX Conditional to be removed when/if tty/pty reference
485 * XXX counting and mutex implemented.
486 */
487 if (old_ptmx_ioctl->pt_devhandle != NULL)
488 devfs_remove(old_ptmx_ioctl->pt_devhandle);
489 ttyfree(old_ptmx_ioctl->pt_tty);
490 FREE(old_ptmx_ioctl, M_TTYS);
491
492 /* Don't remove the entry until the devfs slot is free */
493 DEVFS_LOCK();
494 _state.pis_ioctl_list[ minor] = NULL;
495 _state.pis_free++;
496 DEVFS_UNLOCK();
497 }
498
499 return (0); /* Success */
500 }
501
502
503
504
505 /*
506 * Given the dev entry that's being opened, we clone the device. This driver
507 * doesn't actually use the dev entry, since we alreaqdy know who we are by
508 * being called from this code. This routine is a callback registered from
509 * devfs_make_node_clone() in ptmx_init(); it's purpose is to provide a new
510 * minor number, or to return -1, if one can't be provided.
511 *
512 * Parameters: dev The device we are cloning from
513 *
514 * Returns: >= 0 A new minor device number
515 * -1 Error: ENOMEM ("Can't alloc device")
516 *
517 * NOTE: Called with DEVFS_LOCK() held
518 */
519 static int
520 ptmx_clone(__unused dev_t dev, int action)
521 {
522 int i;
523
524 if (action == DEVFS_CLONE_ALLOC) {
525 /* First one */
526 if (_state.pis_total == 0)
527 return (0);
528
529 /*
530 * Note: We can add hinting on free slots, if this linear search
531 * ends up being a performance bottleneck...
532 */
533 for(i = 0; i < _state.pis_total; i++) {
534 if (_state.pis_ioctl_list[ i] == NULL)
535 break;
536 }
537
538 /*
539 * XXX We fall off the end here; if we did this twice at the
540 * XXX same time, we could return the same minor to two
541 * XXX callers; we should probably exand the pointer vector
542 * XXX here, but I need more information on the MALLOC/FREE
543 * XXX locking to ensure against a deadlock. Maybe we can
544 * XXX just high watermark it at 1/2 of PTMX_GROW_VECTOR?
545 * XXX That would require returning &minor as implict return
546 * XXX and an error code ("EAGAIN/ERESTART") or 0 as our
547 * XXX explicit return.
548 */
549
550 return (i); /* empty slot or next slot */
551 }
552 return(-1);
553 }
554
555 FREE_BSDSTATIC int
556 ptsd_open(dev_t dev, int flag, __unused int devtype, __unused proc_t p)
557 {
558 struct tty *tp;
559 struct ptmx_ioctl *pti;
560 int error;
561
562 if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
563 return (ENXIO);
564 }
565
566 if (!(pti->pt_flags & PF_UNLOCKED)) {
567 return (EAGAIN);
568 }
569
570 tp = pti->pt_tty;
571 tty_lock(tp);
572
573 if ((tp->t_state & TS_ISOPEN) == 0) {
574 termioschars(&tp->t_termios); /* Set up default chars */
575 tp->t_iflag = TTYDEF_IFLAG;
576 tp->t_oflag = TTYDEF_OFLAG;
577 tp->t_lflag = TTYDEF_LFLAG;
578 tp->t_cflag = TTYDEF_CFLAG;
579 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
580 ttsetwater(tp); /* would be done in xxparam() */
581 } else if (tp->t_state&TS_XCLUDE && suser(kauth_cred_get(), NULL)) {
582 error = EBUSY;
583 goto out;
584 }
585 if (tp->t_oproc) /* Ctrlr still around. */
586 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
587 while ((tp->t_state & TS_CARR_ON) == 0) {
588 if (flag&FNONBLOCK)
589 break;
590 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
591 "ptsd_opn", 0);
592 if (error)
593 goto out;
594 }
595 error = (*linesw[tp->t_line].l_open)(dev, tp);
596 /* Successful open; mark as open by the slave */
597 pti->pt_flags |= PF_OPEN_S;
598 CLR(tp->t_state, TS_IOCTL_NOT_OK);
599 if (error == 0)
600 ptmx_wakeup(tp, FREAD|FWRITE);
601 out:
602 tty_unlock(tp);
603 return (error);
604 }
605
606 static void ptsd_revoke_knotes(dev_t, struct tty *);
607
608 FREE_BSDSTATIC int
609 ptsd_close(dev_t dev, int flag, __unused int mode, __unused proc_t p)
610 {
611 struct tty *tp;
612 struct ptmx_ioctl *pti;
613 int err;
614
615 /*
616 * This is temporary until the VSX conformance tests
617 * are fixed. They are hanging with a deadlock
618 * where close(ptsd) will not complete without t_timeout set
619 */
620 #define FIX_VSX_HANG 1
621 #ifdef FIX_VSX_HANG
622 int save_timeout;
623 #endif
624 pti = ptmx_get_ioctl(minor(dev), 0);
625
626 tp = pti->pt_tty;
627 tty_lock(tp);
628
629 #ifdef FIX_VSX_HANG
630 save_timeout = tp->t_timeout;
631 tp->t_timeout = 60;
632 #endif
633 err = (*linesw[tp->t_line].l_close)(tp, flag);
634 ptsd_stop(tp, FREAD|FWRITE);
635 (void) ttyclose(tp);
636 #ifdef FIX_VSX_HANG
637 tp->t_timeout = save_timeout;
638 #endif
639 tty_unlock(tp);
640
641 if ((flag & IO_REVOKE) == IO_REVOKE)
642 ptsd_revoke_knotes(dev, tp);
643
644 /* unconditional, just like ttyclose() */
645 ptmx_free_ioctl(minor(dev), PF_OPEN_S);
646
647 return (err);
648 }
649
650 FREE_BSDSTATIC int
651 ptsd_read(dev_t dev, struct uio *uio, int flag)
652 {
653 proc_t p = current_proc();
654
655 struct tty *tp;
656 struct ptmx_ioctl *pti;
657 int error = 0;
658 struct uthread *ut;
659 struct pgrp * pg;
660
661 pti = ptmx_get_ioctl(minor(dev), 0);
662
663 tp = pti->pt_tty;
664 tty_lock(tp);
665
666 ut = (struct uthread *)get_bsdthread_info(current_thread());
667 again:
668 if (pti->pt_flags & PF_REMOTE) {
669 while (isbackground(p, tp)) {
670 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
671 (ut->uu_sigmask & sigmask(SIGTTIN)) ||
672 p->p_lflag & P_LPPWAIT) {
673 error = EIO;
674 goto out;
675 }
676 pg = proc_pgrp(p);
677 if (pg == PGRP_NULL) {
678 error = EIO;
679 goto out;
680 }
681 /*
682 * SAFE: We about to drop the lock ourselves by
683 * SAFE: erroring out or sleeping anyway.
684 */
685 tty_unlock(tp);
686 if (pg->pg_jobc == 0) {
687 pg_rele(pg);
688 tty_lock(tp);
689 error = EIO;
690 goto out;
691 }
692 pgsignal(pg, SIGTTIN, 1);
693 pg_rele(pg);
694 tty_lock(tp);
695
696 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH | PTTYBLOCK, "ptsd_bg",
697 0);
698 if (error)
699 goto out;
700 }
701 if (tp->t_canq.c_cc == 0) {
702 if (flag & IO_NDELAY) {
703 error = EWOULDBLOCK;
704 goto out;
705 }
706 error = ttysleep(tp, TSA_PTS_READ(tp), TTIPRI | PCATCH,
707 "ptsd_in", 0);
708 if (error)
709 goto out;
710 goto again;
711 }
712 while (tp->t_canq.c_cc > 1 && uio_resid(uio) > 0) {
713 int cc;
714 char buf[BUFSIZ];
715
716 cc = min(uio_resid(uio), BUFSIZ);
717 // Don't copy the very last byte
718 cc = min(cc, tp->t_canq.c_cc - 1);
719 cc = q_to_b(&tp->t_canq, (u_char *)buf, cc);
720 error = uiomove(buf, cc, uio);
721 if (error)
722 break;
723 }
724 if (tp->t_canq.c_cc == 1)
725 (void) getc(&tp->t_canq);
726 if (tp->t_canq.c_cc)
727 goto out;
728 } else
729 if (tp->t_oproc)
730 error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
731 ptmx_wakeup(tp, FWRITE);
732 out:
733 tty_unlock(tp);
734 return (error);
735 }
736
737 /*
738 * Write to pseudo-tty.
739 * Wakeups of controlling tty will happen
740 * indirectly, when tty driver calls ptsd_start.
741 */
742 FREE_BSDSTATIC int
743 ptsd_write(dev_t dev, struct uio *uio, int flag)
744 {
745 struct tty *tp;
746 struct ptmx_ioctl *pti;
747 int error;
748
749 pti = ptmx_get_ioctl(minor(dev), 0);
750
751 tp = pti->pt_tty;
752 tty_lock(tp);
753
754 if (tp->t_oproc == 0)
755 error = EIO;
756 else
757 error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
758
759 tty_unlock(tp);
760 return (error);
761 }
762
763 /*
764 * Start output on pseudo-tty.
765 * Wake up process selecting or sleeping for input from controlling tty.
766 *
767 * t_oproc for this driver; called from within the line discipline
768 *
769 * Locks: Assumes tp is locked on entry, remains locked on exit
770 */
771 static void
772 ptsd_start(struct tty *tp)
773 {
774 struct ptmx_ioctl *pti;
775
776 pti = ptmx_get_ioctl(minor(tp->t_dev), 0);
777
778 if (tp->t_state & TS_TTSTOP)
779 goto out;
780 if (pti->pt_flags & PF_STOPPED) {
781 pti->pt_flags &= ~PF_STOPPED;
782 pti->pt_send = TIOCPKT_START;
783 }
784 ptmx_wakeup(tp, FREAD);
785 out:
786 return;
787 }
788
789 /*
790 * Locks: Assumes tty_lock() is held over this call.
791 */
792 static void
793 ptmx_wakeup(struct tty *tp, int flag)
794 {
795 struct ptmx_ioctl *pti;
796
797 pti = ptmx_get_ioctl(minor(tp->t_dev), 0);
798
799 if (flag & FREAD) {
800 selwakeup(&pti->pt_selr);
801 wakeup(TSA_PTC_READ(tp));
802 }
803 if (flag & FWRITE) {
804 selwakeup(&pti->pt_selw);
805 wakeup(TSA_PTC_WRITE(tp));
806 }
807 }
808
809 FREE_BSDSTATIC int
810 ptmx_open(dev_t dev, __unused int flag, __unused int devtype, __unused proc_t p)
811 {
812 struct tty *tp;
813 struct ptmx_ioctl *pti;
814 int error = 0;
815
816 pti = ptmx_get_ioctl(minor(dev), PF_OPEN_M);
817 if (pti == NULL) {
818 return (ENXIO);
819 } else if (pti == (struct ptmx_ioctl*)-1) {
820 return (EREDRIVEOPEN);
821 }
822
823 tp = pti->pt_tty;
824 tty_lock(tp);
825
826 /* If master is open OR slave is still draining, pty is still busy */
827 if (tp->t_oproc || (tp->t_state & TS_ISOPEN)) {
828 tty_unlock(tp);
829 /*
830 * If master is closed, we are the only reference, so we
831 * need to clear the master open bit
832 */
833 if (!tp->t_oproc)
834 ptmx_free_ioctl(minor(dev), PF_OPEN_M);
835 error = EBUSY;
836 goto err;
837 }
838 tp->t_oproc = ptsd_start;
839 CLR(tp->t_state, TS_ZOMBIE);
840 SET(tp->t_state, TS_IOCTL_NOT_OK);
841 #ifdef sun4c
842 tp->t_stop = ptsd_stop;
843 #endif
844 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
845 tp->t_lflag &= ~EXTPROC;
846
847 tty_unlock(tp);
848 err:
849 return (error);
850 }
851
852 FREE_BSDSTATIC int
853 ptmx_close(dev_t dev, __unused int flags, __unused int fmt, __unused proc_t p)
854 {
855 struct tty *tp;
856 struct ptmx_ioctl *pti;
857
858 pti = ptmx_get_ioctl(minor(dev), 0);
859
860 tp = pti->pt_tty;
861 tty_lock(tp);
862
863 (void)(*linesw[tp->t_line].l_modem)(tp, 0);
864
865 /*
866 * XXX MDMBUF makes no sense for ptys but would inhibit the above
867 * l_modem(). CLOCAL makes sense but isn't supported. Special
868 * l_modem()s that ignore carrier drop make no sense for ptys but
869 * may be in use because other parts of the line discipline make
870 * sense for ptys. Recover by doing everything that a normal
871 * ttymodem() would have done except for sending a SIGHUP.
872 */
873 if (tp->t_state & TS_ISOPEN) {
874 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
875 tp->t_state |= TS_ZOMBIE;
876 ttyflush(tp, FREAD | FWRITE);
877 }
878
879 tp->t_oproc = 0; /* mark closed */
880
881 tty_unlock(tp);
882
883 ptmx_free_ioctl(minor(dev), PF_OPEN_M);
884
885 return (0);
886 }
887
888 FREE_BSDSTATIC int
889 ptmx_read(dev_t dev, struct uio *uio, int flag)
890 {
891 struct tty *tp;
892 struct ptmx_ioctl *pti;
893 char buf[BUFSIZ];
894 int error = 0, cc;
895
896 pti = ptmx_get_ioctl(minor(dev), 0);
897
898 tp = pti->pt_tty;
899 tty_lock(tp);
900
901 /*
902 * We want to block until the slave
903 * is open, and there's something to read;
904 * but if we lost the slave or we're NBIO,
905 * then return the appropriate error instead.
906 */
907 for (;;) {
908 if (tp->t_state&TS_ISOPEN) {
909 if (pti->pt_flags & PF_PKT && pti->pt_send) {
910 error = ureadc((int)pti->pt_send, uio);
911 if (error)
912 goto out;
913 if (pti->pt_send & TIOCPKT_IOCTL) {
914 cc = min(uio_resid(uio),
915 sizeof(tp->t_termios));
916 uiomove((caddr_t)&tp->t_termios, cc,
917 uio);
918 }
919 pti->pt_send = 0;
920 goto out;
921 }
922 if (pti->pt_flags & PF_UCNTL && pti->pt_ucntl) {
923 error = ureadc((int)pti->pt_ucntl, uio);
924 if (error)
925 goto out;
926 pti->pt_ucntl = 0;
927 goto out;
928 }
929 if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
930 break;
931 }
932 if ((tp->t_state & TS_CONNECTED) == 0)
933 goto out; /* EOF */
934 if (flag & IO_NDELAY) {
935 error = EWOULDBLOCK;
936 goto out;
937 }
938 error = ttysleep(tp, TSA_PTC_READ(tp), TTIPRI | PCATCH, "ptmx_in", 0);
939 if (error)
940 goto out;
941 }
942 if (pti->pt_flags & (PF_PKT|PF_UCNTL))
943 error = ureadc(0, uio);
944 while (uio_resid(uio) > 0 && error == 0) {
945 cc = q_to_b(&tp->t_outq, (u_char *)buf, min(uio_resid(uio), BUFSIZ));
946 if (cc <= 0)
947 break;
948 error = uiomove(buf, cc, uio);
949 }
950 (*linesw[tp->t_line].l_start)(tp);
951
952 out:
953 tty_unlock(tp);
954 return (error);
955 }
956
957 /*
958 * Line discipline callback
959 *
960 * Locks: tty_lock() is assumed held on entry and exit.
961 */
962 FREE_BSDSTATIC int
963 ptsd_stop(struct tty *tp, int flush)
964 {
965 struct ptmx_ioctl *pti;
966 int flag;
967
968 pti = ptmx_get_ioctl(minor(tp->t_dev), 0);
969
970 /* note: FLUSHREAD and FLUSHWRITE already ok */
971 if (flush == 0) {
972 flush = TIOCPKT_STOP;
973 pti->pt_flags |= PF_STOPPED;
974 } else
975 pti->pt_flags &= ~PF_STOPPED;
976 pti->pt_send |= flush;
977 /* change of perspective */
978 flag = 0;
979 if (flush & FREAD)
980 flag |= FWRITE;
981 if (flush & FWRITE)
982 flag |= FREAD;
983 ptmx_wakeup(tp, flag);
984
985 return (0);
986 }
987
988 FREE_BSDSTATIC int
989 ptsd_reset(__unused int uban)
990 {
991 return (0);
992 }
993
994 /*
995 * Reinput pending characters after state switch
996 * call at spltty().
997 *
998 * XXX Code duplication: static function, should be inlined
999 */
1000 static void
1001 ttypend(struct tty *tp)
1002 {
1003 struct clist tq;
1004 int c;
1005
1006 CLR(tp->t_lflag, PENDIN);
1007 SET(tp->t_state, TS_TYPEN);
1008 tq = tp->t_rawq;
1009 tp->t_rawq.c_cc = 0;
1010 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
1011 while ((c = getc(&tq)) >= 0)
1012 ttyinput(c, tp);
1013 CLR(tp->t_state, TS_TYPEN);
1014 }
1015
1016 /*
1017 * Must be called at spltty().
1018 *
1019 * XXX Code duplication: static function, should be inlined
1020 */
1021 static int
1022 ttnread(struct tty *tp)
1023 {
1024 int nread;
1025
1026 if (ISSET(tp->t_lflag, PENDIN))
1027 ttypend(tp);
1028 nread = tp->t_canq.c_cc;
1029 if (!ISSET(tp->t_lflag, ICANON)) {
1030 nread += tp->t_rawq.c_cc;
1031 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1032 nread = 0;
1033 }
1034 return (nread);
1035 }
1036
1037 int
1038 ptsd_select(dev_t dev, int rw, void *wql, proc_t p)
1039 {
1040 struct ptmx_ioctl *pti;
1041 struct tty *tp;
1042 int retval = 0;
1043
1044 pti = ptmx_get_ioctl(minor(dev), 0);
1045
1046 tp = pti->pt_tty;
1047
1048 if (tp == NULL)
1049 return (ENXIO);
1050
1051 tty_lock(tp);
1052
1053 switch (rw) {
1054 case FREAD:
1055 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1056 retval = 1;
1057 break;
1058 }
1059
1060 retval = ttnread(tp);
1061 if (retval > 0) {
1062 break;
1063 }
1064
1065 selrecord(p, &tp->t_rsel, wql);
1066 break;
1067 case FWRITE:
1068 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1069 retval = 1;
1070 break;
1071 }
1072
1073 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
1074 ISSET(tp->t_state, TS_CONNECTED)) {
1075 retval = tp->t_hiwat - tp->t_outq.c_cc;
1076 break;
1077 }
1078
1079 selrecord(p, &tp->t_wsel, wql);
1080 break;
1081 }
1082
1083 tty_unlock(tp);
1084 return (retval);
1085 }
1086
1087 FREE_BSDSTATIC int
1088 ptmx_select(dev_t dev, int rw, void *wql, proc_t p)
1089 {
1090 struct tty *tp;
1091 struct ptmx_ioctl *pti;
1092 int retval = 0;
1093
1094 pti = ptmx_get_ioctl(minor(dev), 0);
1095
1096 tp = pti->pt_tty;
1097 tty_lock(tp);
1098
1099 if ((tp->t_state & TS_CONNECTED) == 0) {
1100 retval = 1;
1101 goto out;
1102 }
1103 switch (rw) {
1104 case FREAD:
1105 /*
1106 * Need to block timeouts (ttrstart).
1107 */
1108 if ((tp->t_state&TS_ISOPEN) &&
1109 tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
1110 retval = tp->t_outq.c_cc;
1111 break;
1112 }
1113 /* FALLTHROUGH */
1114
1115 case 0: /* exceptional */
1116 if ((tp->t_state&TS_ISOPEN) &&
1117 ((pti->pt_flags & PF_PKT && pti->pt_send) ||
1118 (pti->pt_flags & PF_UCNTL && pti->pt_ucntl))) {
1119 retval = 1;
1120 break;
1121 }
1122 selrecord(p, &pti->pt_selr, wql);
1123 break;
1124
1125 case FWRITE:
1126 if (tp->t_state&TS_ISOPEN) {
1127 if (pti->pt_flags & PF_REMOTE) {
1128 if (tp->t_canq.c_cc == 0) {
1129 retval = (TTYHOG -1) ;
1130 break;
1131 }
1132 } else {
1133 retval = (TTYHOG - 2) - (tp->t_rawq.c_cc + tp->t_canq.c_cc);
1134 if (retval > 0) {
1135 break;
1136 }
1137 if (tp->t_canq.c_cc == 0 && (tp->t_lflag&ICANON)) {
1138 retval = 1;
1139 break;
1140 }
1141 retval = 0;
1142 }
1143 }
1144 selrecord(p, &pti->pt_selw, wql);
1145 break;
1146
1147 }
1148 out:
1149 tty_unlock(tp);
1150 return (retval);
1151 }
1152
1153 FREE_BSDSTATIC int
1154 ptmx_stop(__unused struct tty *tp, __unused int flush)
1155 {
1156 return (0);
1157 }
1158
1159 FREE_BSDSTATIC int
1160 ptmx_reset(__unused int uban)
1161 {
1162 return (0);
1163 }
1164
1165 FREE_BSDSTATIC int
1166 ptmx_write(dev_t dev, struct uio *uio, int flag)
1167 {
1168 struct tty *tp;
1169 struct ptmx_ioctl *pti;
1170 u_char *cp = NULL;
1171 int cc = 0;
1172 u_char locbuf[BUFSIZ];
1173 int wcnt = 0;
1174 int error = 0;
1175
1176 pti = ptmx_get_ioctl(minor(dev), 0);
1177
1178 tp = pti->pt_tty;
1179 tty_lock(tp);
1180
1181 again:
1182 if ((tp->t_state&TS_ISOPEN) == 0)
1183 goto block;
1184 if (pti->pt_flags & PF_REMOTE) {
1185 if (tp->t_canq.c_cc)
1186 goto block;
1187 while ((uio_resid(uio) > 0 || cc > 0) &&
1188 tp->t_canq.c_cc < TTYHOG - 1) {
1189 if (cc == 0) {
1190 cc = min(uio_resid(uio), BUFSIZ);
1191 cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
1192 cp = locbuf;
1193 error = uiomove((caddr_t)cp, cc, uio);
1194 if (error)
1195 goto out;
1196 /* check again for safety */
1197 if ((tp->t_state & TS_ISOPEN) == 0) {
1198 /* adjust as usual */
1199 uio_setresid(uio, (uio_resid(uio) + cc));
1200 error = EIO;
1201 goto out;
1202 }
1203 }
1204 if (cc > 0) {
1205 cc = b_to_q((u_char *)cp, cc, &tp->t_canq);
1206 /*
1207 * XXX we don't guarantee that the canq size
1208 * is >= TTYHOG, so the above b_to_q() may
1209 * leave some bytes uncopied. However, space
1210 * is guaranteed for the null terminator if
1211 * we don't fail here since (TTYHOG - 1) is
1212 * not a multiple of CBSIZE.
1213 */
1214 if (cc > 0)
1215 break;
1216 }
1217 }
1218 /* adjust for data copied in but not written */
1219 uio_setresid(uio, (uio_resid(uio) + cc));
1220 (void) putc(0, &tp->t_canq);
1221 ttwakeup(tp);
1222 wakeup(TSA_PTS_READ(tp));
1223 goto out;
1224 }
1225 while (uio_resid(uio) > 0 || cc > 0) {
1226 if (cc == 0) {
1227 cc = min(uio_resid(uio), BUFSIZ);
1228 cp = locbuf;
1229 error = uiomove((caddr_t)cp, cc, uio);
1230 if (error)
1231 goto out;
1232 /* check again for safety */
1233 if ((tp->t_state & TS_ISOPEN) == 0) {
1234 /* adjust for data copied in but not written */
1235 uio_setresid(uio, (uio_resid(uio) + cc));
1236 error = EIO;
1237 goto out;
1238 }
1239 }
1240 while (cc > 0) {
1241 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
1242 (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
1243 wakeup(TSA_HUP_OR_INPUT(tp));
1244 goto block;
1245 }
1246 (*linesw[tp->t_line].l_rint)(*cp++, tp);
1247 wcnt++;
1248 cc--;
1249 }
1250 cc = 0;
1251 }
1252
1253 out:
1254 tty_unlock(tp);
1255 return (error);
1256
1257 block:
1258 /*
1259 * Come here to wait for slave to open, for space
1260 * in outq, or space in rawq, or an empty canq.
1261 */
1262 if ((tp->t_state & TS_CONNECTED) == 0) {
1263 /* adjust for data copied in but not written */
1264 uio_setresid(uio, (uio_resid(uio) + cc));
1265 error = EIO;
1266 goto out;
1267 }
1268 if (flag & IO_NDELAY) {
1269 /* adjust for data copied in but not written */
1270 uio_setresid(uio, (uio_resid(uio) + cc));
1271 if (wcnt == 0)
1272 error = EWOULDBLOCK;
1273 goto out;
1274 }
1275 error = ttysleep(tp, TSA_PTC_WRITE(tp), TTOPRI | PCATCH, "ptmx_out", 0);
1276 if (error) {
1277 /* adjust for data copied in but not written */
1278 uio_setresid(uio, (uio_resid(uio) + cc));
1279 goto out;
1280 }
1281 goto again;
1282 }
1283
1284
1285 FREE_BSDSTATIC int
1286 cptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, proc_t p)
1287 {
1288 struct tty *tp;
1289 struct ptmx_ioctl *pti;
1290 u_char *cc;
1291 int stop, error = 0;
1292 int allow_ext_ioctl = 1;
1293
1294 pti = ptmx_get_ioctl(minor(dev), 0);
1295
1296 tp = pti->pt_tty;
1297 tty_lock(tp);
1298
1299 cc = tp->t_cc;
1300
1301 /*
1302 * Do not permit extended ioctls on the master side of the pty unless
1303 * the slave side has been successfully opened and initialized.
1304 */
1305 if (cdevsw[major(dev)].d_open == ptmx_open && ISSET(tp->t_state, TS_IOCTL_NOT_OK))
1306 allow_ext_ioctl = 0;
1307
1308 /*
1309 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
1310 * ttywflush(tp) will hang if there are characters in the outq.
1311 */
1312 if (cmd == TIOCEXT && allow_ext_ioctl) {
1313 /*
1314 * When the EXTPROC bit is being toggled, we need
1315 * to send an TIOCPKT_IOCTL if the packet driver
1316 * is turned on.
1317 */
1318 if (*(int *)data) {
1319 if (pti->pt_flags & PF_PKT) {
1320 pti->pt_send |= TIOCPKT_IOCTL;
1321 ptmx_wakeup(tp, FREAD);
1322 }
1323 tp->t_lflag |= EXTPROC;
1324 } else {
1325 if ((tp->t_lflag & EXTPROC) &&
1326 (pti->pt_flags & PF_PKT)) {
1327 pti->pt_send |= TIOCPKT_IOCTL;
1328 ptmx_wakeup(tp, FREAD);
1329 }
1330 tp->t_lflag &= ~EXTPROC;
1331 }
1332 goto out;
1333 } else
1334 if (cdevsw[major(dev)].d_open == ptmx_open) {
1335 switch (cmd) {
1336
1337 case TIOCGPGRP:
1338 /*
1339 * We aviod calling ttioctl on the controller since,
1340 * in that case, tp must be the controlling terminal.
1341 */
1342 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
1343 goto out;
1344
1345 case TIOCPKT:
1346 if (*(int *)data) {
1347 if (pti->pt_flags & PF_UCNTL) {
1348 error = EINVAL;
1349 goto out;
1350 }
1351 pti->pt_flags |= PF_PKT;
1352 } else
1353 pti->pt_flags &= ~PF_PKT;
1354 goto out;
1355
1356 case TIOCUCNTL:
1357 if (*(int *)data) {
1358 if (pti->pt_flags & PF_PKT) {
1359 error = EINVAL;
1360 goto out;
1361 }
1362 pti->pt_flags |= PF_UCNTL;
1363 } else
1364 pti->pt_flags &= ~PF_UCNTL;
1365 goto out;
1366
1367 case TIOCREMOTE:
1368 if (*(int *)data)
1369 pti->pt_flags |= PF_REMOTE;
1370 else
1371 pti->pt_flags &= ~PF_REMOTE;
1372 ttyflush(tp, FREAD|FWRITE);
1373 goto out;
1374
1375 case TIOCSETP:
1376 case TIOCSETN:
1377 case TIOCSETD:
1378 case TIOCSETA_32:
1379 case TIOCSETAW_32:
1380 case TIOCSETAF_32:
1381 case TIOCSETA_64:
1382 case TIOCSETAW_64:
1383 case TIOCSETAF_64:
1384 ndflush(&tp->t_outq, tp->t_outq.c_cc);
1385 break;
1386
1387 case TIOCSIG:
1388 if (*(unsigned int *)data >= NSIG ||
1389 *(unsigned int *)data == 0) {
1390 error = EINVAL;
1391 goto out;
1392 }
1393 if ((tp->t_lflag&NOFLSH) == 0)
1394 ttyflush(tp, FREAD|FWRITE);
1395 if ((*(unsigned int *)data == SIGINFO) &&
1396 ((tp->t_lflag&NOKERNINFO) == 0))
1397 ttyinfo_locked(tp);
1398 /*
1399 * SAFE: All callers drop the lock on return and
1400 * SAFE: the linesw[] will short circut this call
1401 * SAFE: if the ioctl() is eaten before the lower
1402 * SAFE: level code gets to see it.
1403 */
1404 tty_unlock(tp);
1405 tty_pgsignal(tp, *(unsigned int *)data, 1);
1406 tty_lock(tp);
1407 goto out;
1408
1409 case TIOCPTYGRANT: /* grantpt(3) */
1410 /*
1411 * Change the uid of the slave to that of the calling
1412 * thread, change the gid of the slave to GID_TTY,
1413 * change the mode to 0620 (rw--w----).
1414 */
1415 {
1416 error = _devfs_setattr(pti->pt_devhandle, 0620, kauth_getuid(), GID_TTY);
1417 goto out;
1418 }
1419
1420 case TIOCPTYGNAME: /* ptsname(3) */
1421 /*
1422 * Report the name of the slave device in *data
1423 * (128 bytes max.). Use the same template string
1424 * used for calling devfs_make_node() to create it.
1425 */
1426 snprintf(data, 128, "/dev/" PTSD_TEMPLATE, minor(dev));
1427 error = 0;
1428 goto out;
1429
1430 case TIOCPTYUNLK: /* unlockpt(3) */
1431 /*
1432 * Unlock the slave device so that it can be opened.
1433 */
1434 pti->pt_flags |= PF_UNLOCKED;
1435 error = 0;
1436 goto out;
1437 }
1438
1439 /*
1440 * Fail all other calls; pty masters are not serial devices;
1441 * we only pretend they are when the slave side of the pty is
1442 * already open.
1443 */
1444 if (!allow_ext_ioctl) {
1445 error = ENOTTY;
1446 goto out;
1447 }
1448 }
1449 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1450 if (error == ENOTTY) {
1451 error = ttioctl_locked(tp, cmd, data, flag, p);
1452 if (error == ENOTTY) {
1453 if (pti->pt_flags & PF_UCNTL && (cmd & ~0xff) == UIOCCMD(0)) {
1454 /* Process the UIOCMD ioctl group */
1455 if (cmd & 0xff) {
1456 pti->pt_ucntl = (u_char)cmd;
1457 ptmx_wakeup(tp, FREAD);
1458 }
1459 error = 0;
1460 goto out;
1461 } else if (cmd == TIOCSBRK || cmd == TIOCCBRK) {
1462 /*
1463 * POSIX conformance; rdar://3936338
1464 *
1465 * Clear ENOTTY in the case of setting or
1466 * clearing a break failing because pty's
1467 * don't support break like real serial
1468 * ports.
1469 */
1470 error = 0;
1471 goto out;
1472 }
1473 }
1474 }
1475
1476 /*
1477 * If external processing and packet mode send ioctl packet.
1478 */
1479 if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
1480 switch(cmd) {
1481 case TIOCSETA_32:
1482 case TIOCSETAW_32:
1483 case TIOCSETAF_32:
1484 case TIOCSETA_64:
1485 case TIOCSETAW_64:
1486 case TIOCSETAF_64:
1487 case TIOCSETP:
1488 case TIOCSETN:
1489 case TIOCSETC:
1490 case TIOCSLTC:
1491 case TIOCLBIS:
1492 case TIOCLBIC:
1493 case TIOCLSET:
1494 pti->pt_send |= TIOCPKT_IOCTL;
1495 ptmx_wakeup(tp, FREAD);
1496 default:
1497 break;
1498 }
1499 }
1500 stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1501 && CCEQ(cc[VSTART], CTRL('q'));
1502 if (pti->pt_flags & PF_NOSTOP) {
1503 if (stop) {
1504 pti->pt_send &= ~TIOCPKT_NOSTOP;
1505 pti->pt_send |= TIOCPKT_DOSTOP;
1506 pti->pt_flags &= ~PF_NOSTOP;
1507 ptmx_wakeup(tp, FREAD);
1508 }
1509 } else {
1510 if (!stop) {
1511 pti->pt_send &= ~TIOCPKT_DOSTOP;
1512 pti->pt_send |= TIOCPKT_NOSTOP;
1513 pti->pt_flags |= PF_NOSTOP;
1514 ptmx_wakeup(tp, FREAD);
1515 }
1516 }
1517 out:
1518 tty_unlock(tp);
1519 return (error);
1520 }
1521
1522 /*
1523 * kqueue support.
1524 */
1525 int ptsd_kqfilter(dev_t, struct knote *);
1526 static void ptsd_kqops_detach(struct knote *);
1527 static int ptsd_kqops_event(struct knote *, long);
1528
1529 static struct filterops ptsd_kqops = {
1530 .f_isfd = 1,
1531 .f_detach = ptsd_kqops_detach,
1532 .f_event = ptsd_kqops_event,
1533 };
1534
1535 #define PTSD_KNOTE_VALID NULL
1536 #define PTSD_KNOTE_REVOKED ((void *)-911l)
1537
1538 /*
1539 * In the normal case, by the time the driver_close() routine is called
1540 * on the slave, all knotes have been detached. However in the revoke(2)
1541 * case, the driver's close routine is called while there are knotes active
1542 * that reference the handlers below. And we have no obvious means to
1543 * reach from the driver out to the kqueue's that reference them to get
1544 * them to stop.
1545 */
1546
1547 static void
1548 ptsd_kqops_detach(struct knote *kn)
1549 {
1550 struct ptmx_ioctl *pti;
1551 struct tty *tp;
1552 dev_t dev, lockdev = (dev_t)kn->kn_hookid;
1553
1554 ptsd_kevent_mtx_lock(minor(lockdev));
1555
1556 if ((dev = (dev_t)kn->kn_hookid) != 0) {
1557 pti = ptmx_get_ioctl(minor(dev), 0);
1558 if (pti != NULL && (tp = pti->pt_tty) != NULL) {
1559 tty_lock(tp);
1560 if (kn->kn_filter == EVFILT_READ)
1561 KNOTE_DETACH(&tp->t_rsel.si_note, kn);
1562 else
1563 KNOTE_DETACH(&tp->t_wsel.si_note, kn);
1564 tty_unlock(tp);
1565 kn->kn_hookid = 0;
1566 }
1567 }
1568
1569 ptsd_kevent_mtx_unlock(minor(lockdev));
1570 }
1571
1572 static int
1573 ptsd_kqops_event(struct knote *kn, long hint)
1574 {
1575 struct ptmx_ioctl *pti;
1576 struct tty *tp;
1577 dev_t dev = (dev_t)kn->kn_hookid;
1578 int retval = 0;
1579
1580 ptsd_kevent_mtx_lock(minor(dev));
1581
1582 do {
1583 if (kn->kn_hook != PTSD_KNOTE_VALID ) {
1584 /* We were revoked */
1585 kn->kn_data = 0;
1586 kn->kn_flags |= EV_EOF;
1587 retval = 1;
1588 break;
1589 }
1590
1591 pti = ptmx_get_ioctl(minor(dev), 0);
1592 if (pti == NULL || (tp = pti->pt_tty) == NULL) {
1593 kn->kn_data = ENXIO;
1594 kn->kn_flags |= EV_ERROR;
1595 retval = 1;
1596 break;
1597 }
1598
1599 if (hint == 0)
1600 tty_lock(tp);
1601
1602 if (kn->kn_filter == EVFILT_READ) {
1603 kn->kn_data = ttnread(tp);
1604 if (kn->kn_data > 0)
1605 retval = 1;
1606 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1607 kn->kn_flags |= EV_EOF;
1608 retval = 1;
1609 }
1610 } else { /* EVFILT_WRITE */
1611 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
1612 ISSET(tp->t_state, TS_CONNECTED)) {
1613 kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc;
1614 retval = 1;
1615 }
1616 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1617 kn->kn_flags |= EV_EOF;
1618 retval = 1;
1619 }
1620 }
1621
1622 if (hint == 0)
1623 tty_unlock(tp);
1624 } while (0);
1625
1626 ptsd_kevent_mtx_unlock(minor(dev));
1627
1628 return (retval);
1629 }
1630 int
1631 ptsd_kqfilter(dev_t dev, struct knote *kn)
1632 {
1633 struct tty *tp = NULL;
1634 struct ptmx_ioctl *pti = NULL;
1635 int retval = 0;
1636
1637 /* make sure we're talking about the right device type */
1638 if (cdevsw[major(dev)].d_open != ptsd_open) {
1639 return (EINVAL);
1640 }
1641
1642 if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
1643 return (ENXIO);
1644 }
1645
1646 tp = pti->pt_tty;
1647 tty_lock(tp);
1648
1649 kn->kn_hookid = dev;
1650 kn->kn_hook = PTSD_KNOTE_VALID;
1651 kn->kn_fop = &ptsd_kqops;
1652
1653 switch (kn->kn_filter) {
1654 case EVFILT_READ:
1655 KNOTE_ATTACH(&tp->t_rsel.si_note, kn);
1656 break;
1657 case EVFILT_WRITE:
1658 KNOTE_ATTACH(&tp->t_wsel.si_note, kn);
1659 break;
1660 default:
1661 retval = EINVAL;
1662 break;
1663 }
1664
1665 tty_unlock(tp);
1666 return (retval);
1667 }
1668
1669 /*
1670 * Support for revoke(2).
1671 *
1672 * Mark all the kn_hook fields so that future invocations of the
1673 * f_event op will just say "EOF" *without* looking at the
1674 * ptmx_ioctl structure (which may disappear or be recycled at
1675 * the end of ptsd_close). Issue wakeups to post that EOF to
1676 * anyone listening. And finally remove the knotes from the
1677 * tty's klists to keep ttyclose() happy, and set the hookid to
1678 * zero to make the final detach passively successful.
1679 */
1680 static void
1681 ptsd_revoke_knotes(dev_t dev, struct tty *tp)
1682 {
1683 struct klist *list;
1684 struct knote *kn, *tkn;
1685
1686 /* (Hold and drop the right locks in the right order.) */
1687
1688 ptsd_kevent_mtx_lock(minor(dev));
1689 tty_lock(tp);
1690
1691 list = &tp->t_rsel.si_note;
1692 SLIST_FOREACH(kn, list, kn_selnext)
1693 kn->kn_hook = PTSD_KNOTE_REVOKED;
1694
1695 list = &tp->t_wsel.si_note;
1696 SLIST_FOREACH(kn, list, kn_selnext)
1697 kn->kn_hook = PTSD_KNOTE_REVOKED;
1698
1699 tty_unlock(tp);
1700 ptsd_kevent_mtx_unlock(minor(dev));
1701
1702 tty_lock(tp);
1703 ttwakeup(tp);
1704 ttwwakeup(tp);
1705 tty_unlock(tp);
1706
1707 ptsd_kevent_mtx_lock(minor(dev));
1708 tty_lock(tp);
1709
1710 list = &tp->t_rsel.si_note;
1711 SLIST_FOREACH_SAFE(kn, list, kn_selnext, tkn) {
1712 (void) KNOTE_DETACH(list, kn);
1713 kn->kn_hookid = 0;
1714 }
1715
1716 list = &tp->t_wsel.si_note;
1717 SLIST_FOREACH_SAFE(kn, list, kn_selnext, tkn) {
1718 (void) KNOTE_DETACH(list, kn);
1719 kn->kn_hookid = 0;
1720 }
1721
1722 tty_unlock(tp);
1723 ptsd_kevent_mtx_unlock(minor(dev));
1724 }