]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty_ptmx.c
xnu-1456.1.26.tar.gz
[apple/xnu.git] / bsd / kern / tty_ptmx.c
1 /*
2 * Copyright (c) 1997-2006 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, 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,
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 int
263 ptmx_init( __unused int config_count)
264 {
265 /*
266 * We start looking at slot 10, since there are inits that will
267 * stomp explicit slots (e.g. vndevice stomps 1) below that.
268 */
269
270 /* Get a major number for /dev/ptmx */
271 if((ptmx_major = cdevsw_add(-15, &ptmx_cdev)) == -1) {
272 printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
273 return (ENOENT);
274 }
275
276 /* Get a major number for /dev/pts/nnn */
277 if ((ptsd_major = cdevsw_add(-15, &ptsd_cdev)) == -1) {
278 (void)cdevsw_remove(ptmx_major, &ptmx_cdev);
279 printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
280 return (ENOENT);
281 }
282
283 /* Create the /dev/ptmx device {<major>,0} */
284 (void)devfs_make_node_clone(makedev(ptmx_major, 0),
285 DEVFS_CHAR, UID_ROOT, GID_TTY, 0666,
286 ptmx_clone, PTMX_TEMPLATE);
287 return (0);
288 }
289
290
291 static struct _ptmx_ioctl_state {
292 struct ptmx_ioctl **pis_ioctl_list; /* pointer vector */
293 int pis_total; /* total slots */
294 int pis_free; /* free slots */
295 } _state;
296 #define PTMX_GROW_VECTOR 16 /* Grow by this many slots at a time */
297
298 /*
299 * Given a minor number, return the corresponding structure for that minor
300 * number. If there isn't one, and the create flag is specified, we create
301 * one if possible.
302 *
303 * Parameters: minor Minor number of ptmx device
304 * open_flag PF_OPEN_M First open of master
305 * PF_OPEN_S First open of slave
306 * 0 Just want ioctl struct
307 *
308 * Returns: NULL Did not exist/could not create
309 * !NULL structure corresponding minor number
310 *
311 * Locks: tty_lock() on ptmx_ioctl->pt_tty NOT held on entry or exit.
312 */
313 static struct ptmx_ioctl *
314 ptmx_get_ioctl(int minor, int open_flag)
315 {
316 struct ptmx_ioctl *new_ptmx_ioctl;
317
318 if (open_flag & PF_OPEN_M) {
319
320 /*
321 * If we are about to allocate more memory, but we have
322 * already hit the administrative limit, then fail the
323 * operation.
324 *
325 * Note: Subtract free from total when making this
326 * check to allow unit increments, rather than
327 * snapping to the nearest PTMX_GROW_VECTOR...
328 */
329 if ((_state.pis_total - _state.pis_free) >= ptmx_max) {
330 return (NULL);
331 }
332
333 MALLOC(new_ptmx_ioctl, struct ptmx_ioctl *, sizeof(struct ptmx_ioctl), M_TTYS, M_WAITOK|M_ZERO);
334 if (new_ptmx_ioctl == NULL) {
335 return (NULL);
336 }
337
338 if ((new_ptmx_ioctl->pt_tty = ttymalloc()) == NULL) {
339 FREE(new_ptmx_ioctl, M_TTYS);
340 return (NULL);
341 }
342
343 /*
344 * Hold the DEVFS_LOCK() over this whole operation; devfs
345 * itself does this over malloc/free as well, so this should
346 * be safe to do. We hold it longer than we want to, but
347 * doing so avoids a reallocation race on the minor number.
348 */
349 DEVFS_LOCK();
350 /* Need to allocate a larger vector? */
351 if (_state.pis_free == 0) {
352 struct ptmx_ioctl **new_pis_ioctl_list;
353 struct ptmx_ioctl **old_pis_ioctl_list = NULL;
354
355 /* Yes. */
356 MALLOC(new_pis_ioctl_list, struct ptmx_ioctl **, sizeof(struct ptmx_ioctl *) * (_state.pis_total + PTMX_GROW_VECTOR), M_TTYS, M_WAITOK|M_ZERO);
357 if (new_pis_ioctl_list == NULL) {
358 ttyfree(new_ptmx_ioctl->pt_tty);
359 DEVFS_UNLOCK();
360 FREE(new_ptmx_ioctl, M_TTYS);
361 return (NULL);
362 }
363
364 /* If this is not the first time, copy the old over */
365 bcopy(_state.pis_ioctl_list, new_pis_ioctl_list, sizeof(struct ptmx_ioctl *) * _state.pis_total);
366 old_pis_ioctl_list = _state.pis_ioctl_list;
367 _state.pis_ioctl_list = new_pis_ioctl_list;
368 _state.pis_free += PTMX_GROW_VECTOR;
369 _state.pis_total += PTMX_GROW_VECTOR;
370 if (old_pis_ioctl_list)
371 FREE(old_pis_ioctl_list, M_TTYS);
372 }
373
374 if (_state.pis_ioctl_list[minor] != NULL) {
375 ttyfree(new_ptmx_ioctl->pt_tty);
376 DEVFS_UNLOCK();
377 FREE(new_ptmx_ioctl, M_TTYS);
378
379 /* Special error value so we know to redrive the open, we've been raced */
380 return (struct ptmx_ioctl*)-1;
381
382 }
383
384 /* Vector is large enough; grab a new ptmx_ioctl */
385
386 /* Now grab a free slot... */
387 _state.pis_ioctl_list[minor] = new_ptmx_ioctl;
388
389 /* reduce free count */
390 _state.pis_free--;
391
392 _state.pis_ioctl_list[minor]->pt_flags |= PF_OPEN_M;
393 DEVFS_UNLOCK();
394
395 /* Create the /dev/ttysXXX device {<major>,XXX} */
396 _state.pis_ioctl_list[minor]->pt_devhandle = devfs_make_node(
397 makedev(ptsd_major, minor),
398 DEVFS_CHAR, UID_ROOT, GID_TTY, 0620,
399 PTSD_TEMPLATE, minor);
400 if (_state.pis_ioctl_list[minor]->pt_devhandle == NULL) {
401 printf("devfs_make_node() call failed for ptmx_get_ioctl()!!!!\n");
402 }
403 } else if (open_flag & PF_OPEN_S) {
404 DEVFS_LOCK();
405 _state.pis_ioctl_list[minor]->pt_flags |= PF_OPEN_S;
406 DEVFS_UNLOCK();
407 }
408 return (_state.pis_ioctl_list[minor]);
409 }
410
411 /*
412 * Locks: tty_lock() of old_ptmx_ioctl->pt_tty NOT held for this call.
413 */
414 static int
415 ptmx_free_ioctl(int minor, int open_flag)
416 {
417 struct ptmx_ioctl *old_ptmx_ioctl = NULL;
418
419 DEVFS_LOCK();
420 _state.pis_ioctl_list[minor]->pt_flags &= ~(open_flag);
421
422 /*
423 * Was this the last close? We will recognize it because we only get
424 * a notification on the last close of a device, and we will have
425 * cleared both the master and the slave open bits in the flags.
426 */
427 if (!(_state.pis_ioctl_list[minor]->pt_flags & (PF_OPEN_M|PF_OPEN_S))) {
428 /* Mark as free so it can be reallocated later */
429 old_ptmx_ioctl = _state.pis_ioctl_list[ minor];
430 }
431 DEVFS_UNLOCK();
432
433 /* Free old after dropping lock */
434 if (old_ptmx_ioctl != NULL) {
435 /*
436 * XXX See <rdar://5348651> and <rdar://4854638>
437 *
438 * XXX Conditional to be removed when/if tty/pty reference
439 * XXX counting and mutex implemented.
440 */
441 if (old_ptmx_ioctl->pt_devhandle != NULL)
442 devfs_remove(old_ptmx_ioctl->pt_devhandle);
443 ttyfree(old_ptmx_ioctl->pt_tty);
444 FREE(old_ptmx_ioctl, M_TTYS);
445
446 /* Don't remove the entry until the devfs slot is free */
447 DEVFS_LOCK();
448 _state.pis_ioctl_list[ minor] = NULL;
449 _state.pis_free++;
450 DEVFS_UNLOCK();
451 }
452
453 return (0); /* Success */
454 }
455
456
457
458
459 /*
460 * Given the dev entry that's being opened, we clone the device. This driver
461 * doesn't actually use the dev entry, since we alreaqdy know who we are by
462 * being called from this code. This routine is a callback registered from
463 * devfs_make_node_clone() in ptmx_init(); it's purpose is to provide a new
464 * minor number, or to return -1, if one can't be provided.
465 *
466 * Parameters: dev The device we are cloning from
467 *
468 * Returns: >= 0 A new minor device number
469 * -1 Error: ENOMEM ("Can't alloc device")
470 *
471 * NOTE: Called with DEVFS_LOCK() held
472 */
473 static int
474 ptmx_clone(__unused dev_t dev, int action)
475 {
476 int i;
477
478 if (action == DEVFS_CLONE_ALLOC) {
479 /* First one */
480 if (_state.pis_total == 0)
481 return (0);
482
483 /*
484 * Note: We can add hinting on free slots, if this linear search
485 * ends up being a performance bottleneck...
486 */
487 for(i = 0; i < _state.pis_total; i++) {
488 if (_state.pis_ioctl_list[ i] == NULL)
489 break;
490 }
491
492 /*
493 * XXX We fall off the end here; if we did this twice at the
494 * XXX same time, we could return the same minor to two
495 * XXX callers; we should probably exand the pointer vector
496 * XXX here, but I need more information on the MALLOC/FREE
497 * XXX locking to ensure against a deadlock. Maybe we can
498 * XXX just high watermark it at 1/2 of PTMX_GROW_VECTOR?
499 * XXX That would require returning &minor as implict return
500 * XXX and an error code ("EAGAIN/ERESTART") or 0 as our
501 * XXX explicit return.
502 */
503
504 return (i); /* empty slot or next slot */
505 }
506 return(-1);
507 }
508
509 FREE_BSDSTATIC int
510 ptsd_open(dev_t dev, int flag, __unused int devtype, __unused proc_t p)
511 {
512 struct tty *tp;
513 struct ptmx_ioctl *pti;
514 int error;
515
516 if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
517 return (ENXIO);
518 }
519
520 if (!(pti->pt_flags & PF_UNLOCKED)) {
521 return (EAGAIN);
522 }
523
524 tp = pti->pt_tty;
525 tty_lock(tp);
526
527 if ((tp->t_state & TS_ISOPEN) == 0) {
528 termioschars(&tp->t_termios); /* Set up default chars */
529 tp->t_iflag = TTYDEF_IFLAG;
530 tp->t_oflag = TTYDEF_OFLAG;
531 tp->t_lflag = TTYDEF_LFLAG;
532 tp->t_cflag = TTYDEF_CFLAG;
533 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
534 ttsetwater(tp); /* would be done in xxparam() */
535 } else if (tp->t_state&TS_XCLUDE && suser(kauth_cred_get(), NULL)) {
536 error = EBUSY;
537 goto out;
538 }
539 if (tp->t_oproc) /* Ctrlr still around. */
540 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
541 while ((tp->t_state & TS_CARR_ON) == 0) {
542 if (flag&FNONBLOCK)
543 break;
544 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
545 "ptsd_opn", 0);
546 if (error)
547 goto out;
548 }
549 error = (*linesw[tp->t_line].l_open)(dev, tp);
550 /* Successful open; mark as open by the slave */
551 pti->pt_flags |= PF_OPEN_S;
552 if (error == 0)
553 ptmx_wakeup(tp, FREAD|FWRITE);
554 out:
555 tty_unlock(tp);
556 return (error);
557 }
558
559 FREE_BSDSTATIC int
560 ptsd_close(dev_t dev, int flag, __unused int mode, __unused proc_t p)
561 {
562 struct tty *tp;
563 struct ptmx_ioctl *pti;
564 int err;
565
566 /*
567 * This is temporary until the VSX conformance tests
568 * are fixed. They are hanging with a deadlock
569 * where close(ptsd) will not complete without t_timeout set
570 */
571 #define FIX_VSX_HANG 1
572 #ifdef FIX_VSX_HANG
573 int save_timeout;
574 #endif
575 pti = ptmx_get_ioctl(minor(dev), 0);
576
577 tp = pti->pt_tty;
578 tty_lock(tp);
579
580 #ifdef FIX_VSX_HANG
581 save_timeout = tp->t_timeout;
582 tp->t_timeout = 60;
583 #endif
584 err = (*linesw[tp->t_line].l_close)(tp, flag);
585 ptsd_stop(tp, FREAD|FWRITE);
586 (void) ttyclose(tp);
587 #ifdef FIX_VSX_HANG
588 tp->t_timeout = save_timeout;
589 #endif
590
591 tty_unlock(tp);
592
593 /* unconditional, just like ttyclose() */
594 ptmx_free_ioctl(minor(dev), PF_OPEN_S);
595
596 return (err);
597 }
598
599 FREE_BSDSTATIC int
600 ptsd_read(dev_t dev, struct uio *uio, int flag)
601 {
602 proc_t p = current_proc();
603
604 struct tty *tp;
605 struct ptmx_ioctl *pti;
606 int error = 0;
607 struct uthread *ut;
608 struct pgrp * pg;
609
610 pti = ptmx_get_ioctl(minor(dev), 0);
611
612 tp = pti->pt_tty;
613 tty_lock(tp);
614
615 ut = (struct uthread *)get_bsdthread_info(current_thread());
616 again:
617 if (pti->pt_flags & PF_REMOTE) {
618 while (isbackground(p, tp)) {
619 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
620 (ut->uu_sigmask & sigmask(SIGTTIN)) ||
621 p->p_lflag & P_LPPWAIT) {
622 error = EIO;
623 goto out;
624 }
625 pg = proc_pgrp(p);
626 if (pg == PGRP_NULL) {
627 error = EIO;
628 goto out;
629 }
630 /*
631 * SAFE: We about to drop the lock ourselves by
632 * SAFE: erroring out or sleeping anyway.
633 */
634 tty_unlock(tp);
635 if (pg->pg_jobc == 0) {
636 pg_rele(pg);
637 tty_lock(tp);
638 error = EIO;
639 goto out;
640 }
641 pgsignal(pg, SIGTTIN, 1);
642 pg_rele(pg);
643 tty_lock(tp);
644
645 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH | PTTYBLOCK, "ptsd_bg",
646 0);
647 if (error)
648 goto out;
649 }
650 if (tp->t_canq.c_cc == 0) {
651 if (flag & IO_NDELAY) {
652 error = EWOULDBLOCK;
653 goto out;
654 }
655 error = ttysleep(tp, TSA_PTS_READ(tp), TTIPRI | PCATCH,
656 "ptsd_in", 0);
657 if (error)
658 goto out;
659 goto again;
660 }
661 while (tp->t_canq.c_cc > 1 && uio_resid(uio) > 0) {
662 int cc;
663 char buf[BUFSIZ];
664
665 cc = min(uio_resid(uio), BUFSIZ);
666 // Don't copy the very last byte
667 cc = min(cc, tp->t_canq.c_cc - 1);
668 cc = q_to_b(&tp->t_canq, (u_char *)buf, cc);
669 error = uiomove(buf, cc, uio);
670 if (error)
671 break;
672 }
673 if (tp->t_canq.c_cc == 1)
674 (void) getc(&tp->t_canq);
675 if (tp->t_canq.c_cc)
676 goto out;
677 } else
678 if (tp->t_oproc)
679 error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
680 ptmx_wakeup(tp, FWRITE);
681 out:
682 tty_unlock(tp);
683 return (error);
684 }
685
686 /*
687 * Write to pseudo-tty.
688 * Wakeups of controlling tty will happen
689 * indirectly, when tty driver calls ptsd_start.
690 */
691 FREE_BSDSTATIC int
692 ptsd_write(dev_t dev, struct uio *uio, int flag)
693 {
694 struct tty *tp;
695 struct ptmx_ioctl *pti;
696 int error;
697
698 pti = ptmx_get_ioctl(minor(dev), 0);
699
700 tp = pti->pt_tty;
701 tty_lock(tp);
702
703 if (tp->t_oproc == 0)
704 error = EIO;
705 else
706 error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
707
708 tty_unlock(tp);
709 return (error);
710 }
711
712 /*
713 * Start output on pseudo-tty.
714 * Wake up process selecting or sleeping for input from controlling tty.
715 *
716 * t_oproc for this driver; called from within the line discipline
717 *
718 * Locks: Assumes tp is locked on entry, remains locked on exit
719 */
720 static void
721 ptsd_start(struct tty *tp)
722 {
723 struct ptmx_ioctl *pti;
724
725 pti = ptmx_get_ioctl(minor(tp->t_dev), 0);
726
727 if (tp->t_state & TS_TTSTOP)
728 goto out;
729 if (pti->pt_flags & PF_STOPPED) {
730 pti->pt_flags &= ~PF_STOPPED;
731 pti->pt_send = TIOCPKT_START;
732 }
733 ptmx_wakeup(tp, FREAD);
734 out:
735 return;
736 }
737
738 /*
739 * Locks: Assumes tty_lock() is held over this call.
740 */
741 static void
742 ptmx_wakeup(struct tty *tp, int flag)
743 {
744 struct ptmx_ioctl *pti;
745
746 pti = ptmx_get_ioctl(minor(tp->t_dev), 0);
747
748 if (flag & FREAD) {
749 selwakeup(&pti->pt_selr);
750 wakeup(TSA_PTC_READ(tp));
751 }
752 if (flag & FWRITE) {
753 selwakeup(&pti->pt_selw);
754 wakeup(TSA_PTC_WRITE(tp));
755 }
756 }
757
758 FREE_BSDSTATIC int
759 ptmx_open(dev_t dev, __unused int flag, __unused int devtype, __unused proc_t p)
760 {
761 struct tty *tp;
762 struct ptmx_ioctl *pti;
763 int error = 0;
764
765 pti = ptmx_get_ioctl(minor(dev), PF_OPEN_M);
766 if (pti == NULL) {
767 return (ENXIO);
768 } else if (pti == (struct ptmx_ioctl*)-1) {
769 return (EREDRIVEOPEN);
770 }
771
772 tp = pti->pt_tty;
773 tty_lock(tp);
774
775 /* If master is open OR slave is still draining, pty is still busy */
776 if (tp->t_oproc || (tp->t_state & TS_ISOPEN)) {
777 tty_unlock(tp);
778 /*
779 * If master is closed, we are the only reference, so we
780 * need to clear the master open bit
781 */
782 if (!tp->t_oproc)
783 ptmx_free_ioctl(minor(dev), PF_OPEN_M);
784 error = EBUSY;
785 goto err;
786 }
787 tp->t_oproc = ptsd_start;
788 CLR(tp->t_state, TS_ZOMBIE);
789 #ifdef sun4c
790 tp->t_stop = ptsd_stop;
791 #endif
792 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
793 tp->t_lflag &= ~EXTPROC;
794
795 tty_unlock(tp);
796 err:
797 return (error);
798 }
799
800 FREE_BSDSTATIC int
801 ptmx_close(dev_t dev, __unused int flags, __unused int fmt, __unused proc_t p)
802 {
803 struct tty *tp;
804 struct ptmx_ioctl *pti;
805
806 pti = ptmx_get_ioctl(minor(dev), 0);
807
808 tp = pti->pt_tty;
809 tty_lock(tp);
810
811 (void)(*linesw[tp->t_line].l_modem)(tp, 0);
812
813 /*
814 * XXX MDMBUF makes no sense for ptys but would inhibit the above
815 * l_modem(). CLOCAL makes sense but isn't supported. Special
816 * l_modem()s that ignore carrier drop make no sense for ptys but
817 * may be in use because other parts of the line discipline make
818 * sense for ptys. Recover by doing everything that a normal
819 * ttymodem() would have done except for sending a SIGHUP.
820 */
821 if (tp->t_state & TS_ISOPEN) {
822 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
823 tp->t_state |= TS_ZOMBIE;
824 ttyflush(tp, FREAD | FWRITE);
825 }
826
827 tp->t_oproc = 0; /* mark closed */
828
829 tty_unlock(tp);
830
831 ptmx_free_ioctl(minor(dev), PF_OPEN_M);
832
833 return (0);
834 }
835
836 FREE_BSDSTATIC int
837 ptmx_read(dev_t dev, struct uio *uio, int flag)
838 {
839 struct tty *tp;
840 struct ptmx_ioctl *pti;
841 char buf[BUFSIZ];
842 int error = 0, cc;
843
844 pti = ptmx_get_ioctl(minor(dev), 0);
845
846 tp = pti->pt_tty;
847 tty_lock(tp);
848
849 /*
850 * We want to block until the slave
851 * is open, and there's something to read;
852 * but if we lost the slave or we're NBIO,
853 * then return the appropriate error instead.
854 */
855 for (;;) {
856 if (tp->t_state&TS_ISOPEN) {
857 if (pti->pt_flags & PF_PKT && pti->pt_send) {
858 error = ureadc((int)pti->pt_send, uio);
859 if (error)
860 goto out;
861 if (pti->pt_send & TIOCPKT_IOCTL) {
862 cc = min(uio_resid(uio),
863 sizeof(tp->t_termios));
864 uiomove((caddr_t)&tp->t_termios, cc,
865 uio);
866 }
867 pti->pt_send = 0;
868 goto out;
869 }
870 if (pti->pt_flags & PF_UCNTL && pti->pt_ucntl) {
871 error = ureadc((int)pti->pt_ucntl, uio);
872 if (error)
873 goto out;
874 pti->pt_ucntl = 0;
875 goto out;
876 }
877 if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
878 break;
879 }
880 if ((tp->t_state & TS_CONNECTED) == 0)
881 goto out; /* EOF */
882 if (flag & IO_NDELAY) {
883 error = EWOULDBLOCK;
884 goto out;
885 }
886 error = ttysleep(tp, TSA_PTC_READ(tp), TTIPRI | PCATCH, "ptmx_in", 0);
887 if (error)
888 goto out;
889 }
890 if (pti->pt_flags & (PF_PKT|PF_UCNTL))
891 error = ureadc(0, uio);
892 while (uio_resid(uio) > 0 && error == 0) {
893 cc = q_to_b(&tp->t_outq, (u_char *)buf, min(uio_resid(uio), BUFSIZ));
894 if (cc <= 0)
895 break;
896 error = uiomove(buf, cc, uio);
897 }
898 (*linesw[tp->t_line].l_start)(tp);
899
900 out:
901 tty_unlock(tp);
902 return (error);
903 }
904
905 /*
906 * Line discipline callback
907 *
908 * Locks: tty_lock() is assumed held on entry and exit.
909 */
910 FREE_BSDSTATIC int
911 ptsd_stop(struct tty *tp, int flush)
912 {
913 struct ptmx_ioctl *pti;
914 int flag;
915
916 pti = ptmx_get_ioctl(minor(tp->t_dev), 0);
917
918 /* note: FLUSHREAD and FLUSHWRITE already ok */
919 if (flush == 0) {
920 flush = TIOCPKT_STOP;
921 pti->pt_flags |= PF_STOPPED;
922 } else
923 pti->pt_flags &= ~PF_STOPPED;
924 pti->pt_send |= flush;
925 /* change of perspective */
926 flag = 0;
927 if (flush & FREAD)
928 flag |= FWRITE;
929 if (flush & FWRITE)
930 flag |= FREAD;
931 ptmx_wakeup(tp, flag);
932
933 return (0);
934 }
935
936 FREE_BSDSTATIC int
937 ptsd_reset(__unused int uban)
938 {
939 return (0);
940 }
941
942 /*
943 * Reinput pending characters after state switch
944 * call at spltty().
945 *
946 * XXX Code duplication: static function, should be inlined
947 */
948 static void
949 ttypend(struct tty *tp)
950 {
951 struct clist tq;
952 int c;
953
954 CLR(tp->t_lflag, PENDIN);
955 SET(tp->t_state, TS_TYPEN);
956 tq = tp->t_rawq;
957 tp->t_rawq.c_cc = 0;
958 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
959 while ((c = getc(&tq)) >= 0)
960 ttyinput(c, tp);
961 CLR(tp->t_state, TS_TYPEN);
962 }
963
964 /*
965 * Must be called at spltty().
966 *
967 * XXX Code duplication: static function, should be inlined
968 */
969 static int
970 ttnread(struct tty *tp)
971 {
972 int nread;
973
974 if (ISSET(tp->t_lflag, PENDIN))
975 ttypend(tp);
976 nread = tp->t_canq.c_cc;
977 if (!ISSET(tp->t_lflag, ICANON)) {
978 nread += tp->t_rawq.c_cc;
979 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
980 nread = 0;
981 }
982 return (nread);
983 }
984
985 int
986 ptsd_select(dev_t dev, int rw, void *wql, proc_t p)
987 {
988 struct ptmx_ioctl *pti;
989 struct tty *tp;
990 int retval = 0;
991
992 pti = ptmx_get_ioctl(minor(dev), 0);
993
994 tp = pti->pt_tty;
995
996 if (tp == NULL)
997 return (ENXIO);
998
999 tty_lock(tp);
1000
1001 switch (rw) {
1002 case FREAD:
1003 if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE)) {
1004 retval = 1;
1005 break;
1006 }
1007 selrecord(p, &tp->t_rsel, wql);
1008 break;
1009 case FWRITE:
1010 if ((tp->t_outq.c_cc <= tp->t_lowat &&
1011 ISSET(tp->t_state, TS_CONNECTED))
1012 || ISSET(tp->t_state, TS_ZOMBIE)) {
1013 retval = 1;
1014 break;
1015 }
1016 selrecord(p, &tp->t_wsel, wql);
1017 break;
1018 }
1019
1020 tty_unlock(tp);
1021 return (retval);
1022 }
1023
1024 FREE_BSDSTATIC int
1025 ptmx_select(dev_t dev, int rw, void *wql, proc_t p)
1026 {
1027 struct tty *tp;
1028 struct ptmx_ioctl *pti;
1029 int retval = 0;
1030
1031 pti = ptmx_get_ioctl(minor(dev), 0);
1032
1033 tp = pti->pt_tty;
1034 tty_lock(tp);
1035
1036 if ((tp->t_state & TS_CONNECTED) == 0) {
1037 retval = 1;
1038 goto out;
1039 }
1040 switch (rw) {
1041 case FREAD:
1042 /*
1043 * Need to block timeouts (ttrstart).
1044 */
1045 if ((tp->t_state&TS_ISOPEN) &&
1046 tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
1047 retval = 1;
1048 break;
1049 }
1050 /* FALLTHROUGH */
1051
1052 case 0: /* exceptional */
1053 if ((tp->t_state&TS_ISOPEN) &&
1054 ((pti->pt_flags & PF_PKT && pti->pt_send) ||
1055 (pti->pt_flags & PF_UCNTL && pti->pt_ucntl))) {
1056 retval = 1;
1057 break;
1058 }
1059 selrecord(p, &pti->pt_selr, wql);
1060 break;
1061
1062 case FWRITE:
1063 if (tp->t_state&TS_ISOPEN) {
1064 if (pti->pt_flags & PF_REMOTE) {
1065 if (tp->t_canq.c_cc == 0) {
1066 retval = 1;
1067 break;
1068 }
1069 } else {
1070 if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2) {
1071 retval = 1;
1072 break;
1073 }
1074 if (tp->t_canq.c_cc == 0 && (tp->t_lflag&ICANON)) {
1075 retval = 1;
1076 break;
1077 }
1078 }
1079 }
1080 selrecord(p, &pti->pt_selw, wql);
1081 break;
1082
1083 }
1084 out:
1085 tty_unlock(tp);
1086 return (retval);
1087 }
1088
1089 FREE_BSDSTATIC int
1090 ptmx_stop(__unused struct tty *tp, __unused int flush)
1091 {
1092 return (0);
1093 }
1094
1095 FREE_BSDSTATIC int
1096 ptmx_reset(__unused int uban)
1097 {
1098 return (0);
1099 }
1100
1101 FREE_BSDSTATIC int
1102 ptmx_write(dev_t dev, struct uio *uio, int flag)
1103 {
1104 struct tty *tp;
1105 struct ptmx_ioctl *pti;
1106 u_char *cp = NULL;
1107 int cc = 0;
1108 u_char locbuf[BUFSIZ];
1109 int wcnt = 0;
1110 int error = 0;
1111
1112 pti = ptmx_get_ioctl(minor(dev), 0);
1113
1114 tp = pti->pt_tty;
1115 tty_lock(tp);
1116
1117 again:
1118 if ((tp->t_state&TS_ISOPEN) == 0)
1119 goto block;
1120 if (pti->pt_flags & PF_REMOTE) {
1121 if (tp->t_canq.c_cc)
1122 goto block;
1123 while ((uio_resid(uio) > 0 || cc > 0) &&
1124 tp->t_canq.c_cc < TTYHOG - 1) {
1125 if (cc == 0) {
1126 cc = min(uio_resid(uio), BUFSIZ);
1127 cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
1128 cp = locbuf;
1129 error = uiomove((caddr_t)cp, cc, uio);
1130 if (error)
1131 goto out;
1132 /* check again for safety */
1133 if ((tp->t_state & TS_ISOPEN) == 0) {
1134 /* adjust as usual */
1135 uio_setresid(uio, (uio_resid(uio) + cc));
1136 error = EIO;
1137 goto out;
1138 }
1139 }
1140 if (cc > 0) {
1141 cc = b_to_q((u_char *)cp, cc, &tp->t_canq);
1142 /*
1143 * XXX we don't guarantee that the canq size
1144 * is >= TTYHOG, so the above b_to_q() may
1145 * leave some bytes uncopied. However, space
1146 * is guaranteed for the null terminator if
1147 * we don't fail here since (TTYHOG - 1) is
1148 * not a multiple of CBSIZE.
1149 */
1150 if (cc > 0)
1151 break;
1152 }
1153 }
1154 /* adjust for data copied in but not written */
1155 uio_setresid(uio, (uio_resid(uio) + cc));
1156 (void) putc(0, &tp->t_canq);
1157 ttwakeup(tp);
1158 wakeup(TSA_PTS_READ(tp));
1159 goto out;
1160 }
1161 while (uio_resid(uio) > 0 || cc > 0) {
1162 if (cc == 0) {
1163 cc = min(uio_resid(uio), BUFSIZ);
1164 cp = locbuf;
1165 error = uiomove((caddr_t)cp, cc, uio);
1166 if (error)
1167 goto out;
1168 /* check again for safety */
1169 if ((tp->t_state & TS_ISOPEN) == 0) {
1170 /* adjust for data copied in but not written */
1171 uio_setresid(uio, (uio_resid(uio) + cc));
1172 error = EIO;
1173 goto out;
1174 }
1175 }
1176 while (cc > 0) {
1177 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
1178 (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
1179 wakeup(TSA_HUP_OR_INPUT(tp));
1180 goto block;
1181 }
1182 (*linesw[tp->t_line].l_rint)(*cp++, tp);
1183 wcnt++;
1184 cc--;
1185 }
1186 cc = 0;
1187 }
1188
1189 out:
1190 tty_unlock(tp);
1191 return (error);
1192
1193 block:
1194 /*
1195 * Come here to wait for slave to open, for space
1196 * in outq, or space in rawq, or an empty canq.
1197 */
1198 if ((tp->t_state & TS_CONNECTED) == 0) {
1199 /* adjust for data copied in but not written */
1200 uio_setresid(uio, (uio_resid(uio) + cc));
1201 error = EIO;
1202 goto out;
1203 }
1204 if (flag & IO_NDELAY) {
1205 /* adjust for data copied in but not written */
1206 uio_setresid(uio, (uio_resid(uio) + cc));
1207 if (wcnt == 0)
1208 error = EWOULDBLOCK;
1209 goto out;
1210 }
1211 error = ttysleep(tp, TSA_PTC_WRITE(tp), TTOPRI | PCATCH, "ptmx_out", 0);
1212 if (error) {
1213 /* adjust for data copied in but not written */
1214 uio_setresid(uio, (uio_resid(uio) + cc));
1215 goto out;
1216 }
1217 goto again;
1218 }
1219
1220
1221 FREE_BSDSTATIC int
1222 cptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, proc_t p)
1223 {
1224 struct tty *tp;
1225 struct ptmx_ioctl *pti;
1226 u_char *cc;
1227 int stop, error = 0;
1228
1229 pti = ptmx_get_ioctl(minor(dev), 0);
1230
1231 tp = pti->pt_tty;
1232 tty_lock(tp);
1233
1234 cc = tp->t_cc;
1235
1236 /*
1237 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
1238 * ttywflush(tp) will hang if there are characters in the outq.
1239 */
1240 if (cmd == TIOCEXT) {
1241 /*
1242 * When the EXTPROC bit is being toggled, we need
1243 * to send an TIOCPKT_IOCTL if the packet driver
1244 * is turned on.
1245 */
1246 if (*(int *)data) {
1247 if (pti->pt_flags & PF_PKT) {
1248 pti->pt_send |= TIOCPKT_IOCTL;
1249 ptmx_wakeup(tp, FREAD);
1250 }
1251 tp->t_lflag |= EXTPROC;
1252 } else {
1253 if ((tp->t_lflag & EXTPROC) &&
1254 (pti->pt_flags & PF_PKT)) {
1255 pti->pt_send |= TIOCPKT_IOCTL;
1256 ptmx_wakeup(tp, FREAD);
1257 }
1258 tp->t_lflag &= ~EXTPROC;
1259 }
1260 goto out;
1261 } else
1262 if (cdevsw[major(dev)].d_open == ptmx_open)
1263 switch (cmd) {
1264
1265 case TIOCGPGRP:
1266 /*
1267 * We aviod calling ttioctl on the controller since,
1268 * in that case, tp must be the controlling terminal.
1269 */
1270 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
1271 goto out;
1272
1273 case TIOCPKT:
1274 if (*(int *)data) {
1275 if (pti->pt_flags & PF_UCNTL) {
1276 error = EINVAL;
1277 goto out;
1278 }
1279 pti->pt_flags |= PF_PKT;
1280 } else
1281 pti->pt_flags &= ~PF_PKT;
1282 goto out;
1283
1284 case TIOCUCNTL:
1285 if (*(int *)data) {
1286 if (pti->pt_flags & PF_PKT) {
1287 error = EINVAL;
1288 goto out;
1289 }
1290 pti->pt_flags |= PF_UCNTL;
1291 } else
1292 pti->pt_flags &= ~PF_UCNTL;
1293 goto out;
1294
1295 case TIOCREMOTE:
1296 if (*(int *)data)
1297 pti->pt_flags |= PF_REMOTE;
1298 else
1299 pti->pt_flags &= ~PF_REMOTE;
1300 ttyflush(tp, FREAD|FWRITE);
1301 goto out;
1302
1303 case TIOCSETP:
1304 case TIOCSETN:
1305 case TIOCSETD:
1306 case TIOCSETA_32:
1307 case TIOCSETAW_32:
1308 case TIOCSETAF_32:
1309 case TIOCSETA_64:
1310 case TIOCSETAW_64:
1311 case TIOCSETAF_64:
1312 ndflush(&tp->t_outq, tp->t_outq.c_cc);
1313 break;
1314
1315 case TIOCSIG:
1316 if (*(unsigned int *)data >= NSIG ||
1317 *(unsigned int *)data == 0) {
1318 error = EINVAL;
1319 goto out;
1320 }
1321 if ((tp->t_lflag&NOFLSH) == 0)
1322 ttyflush(tp, FREAD|FWRITE);
1323 if ((*(unsigned int *)data == SIGINFO) &&
1324 ((tp->t_lflag&NOKERNINFO) == 0))
1325 ttyinfo_locked(tp);
1326 /*
1327 * SAFE: All callers drop the lock on return and
1328 * SAFE: the linesw[] will short circut this call
1329 * SAFE: if the ioctl() is eaten before the lower
1330 * SAFE: level code gets to see it.
1331 */
1332 tty_unlock(tp);
1333 tty_pgsignal(tp, *(unsigned int *)data, 1);
1334 tty_lock(tp);
1335 goto out;
1336
1337 case TIOCPTYGRANT: /* grantpt(3) */
1338 /*
1339 * Change the uid of the slave to that of the calling
1340 * thread, change the gid of the slave to GID_TTY,
1341 * change the mode to 0620 (rw--w----).
1342 */
1343 {
1344 error = _devfs_setattr(pti->pt_devhandle, 0620, kauth_getuid(), GID_TTY);
1345 goto out;
1346 }
1347
1348 case TIOCPTYGNAME: /* ptsname(3) */
1349 /*
1350 * Report the name of the slave device in *data
1351 * (128 bytes max.). Use the same template string
1352 * used for calling devfs_make_node() to create it.
1353 */
1354 snprintf(data, 128, "/dev/" PTSD_TEMPLATE, minor(dev));
1355 error = 0;
1356 goto out;
1357
1358 case TIOCPTYUNLK: /* unlockpt(3) */
1359 /*
1360 * Unlock the slave device so that it can be opened.
1361 */
1362 pti->pt_flags |= PF_UNLOCKED;
1363 error = 0;
1364 goto out;
1365 }
1366 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1367 if (error == ENOTTY) {
1368 error = ttioctl_locked(tp, cmd, data, flag, p);
1369 if (error == ENOTTY) {
1370 if (pti->pt_flags & PF_UCNTL && (cmd & ~0xff) == UIOCCMD(0)) {
1371 /* Process the UIOCMD ioctl group */
1372 if (cmd & 0xff) {
1373 pti->pt_ucntl = (u_char)cmd;
1374 ptmx_wakeup(tp, FREAD);
1375 }
1376 error = 0;
1377 goto out;
1378 } else if (cmd == TIOCSBRK || cmd == TIOCCBRK) {
1379 /*
1380 * POSIX conformance; rdar://3936338
1381 *
1382 * Clear ENOTTY in the case of setting or
1383 * clearing a break failing because pty's
1384 * don't support break like real serial
1385 * ports.
1386 */
1387 error = 0;
1388 goto out;
1389 }
1390 }
1391 }
1392
1393 /*
1394 * If external processing and packet mode send ioctl packet.
1395 */
1396 if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
1397 switch(cmd) {
1398 case TIOCSETA_32:
1399 case TIOCSETAW_32:
1400 case TIOCSETAF_32:
1401 case TIOCSETA_64:
1402 case TIOCSETAW_64:
1403 case TIOCSETAF_64:
1404 case TIOCSETP:
1405 case TIOCSETN:
1406 case TIOCSETC:
1407 case TIOCSLTC:
1408 case TIOCLBIS:
1409 case TIOCLBIC:
1410 case TIOCLSET:
1411 pti->pt_send |= TIOCPKT_IOCTL;
1412 ptmx_wakeup(tp, FREAD);
1413 default:
1414 break;
1415 }
1416 }
1417 stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1418 && CCEQ(cc[VSTART], CTRL('q'));
1419 if (pti->pt_flags & PF_NOSTOP) {
1420 if (stop) {
1421 pti->pt_send &= ~TIOCPKT_NOSTOP;
1422 pti->pt_send |= TIOCPKT_DOSTOP;
1423 pti->pt_flags &= ~PF_NOSTOP;
1424 ptmx_wakeup(tp, FREAD);
1425 }
1426 } else {
1427 if (!stop) {
1428 pti->pt_send &= ~TIOCPKT_DOSTOP;
1429 pti->pt_send |= TIOCPKT_NOSTOP;
1430 pti->pt_flags |= PF_NOSTOP;
1431 ptmx_wakeup(tp, FREAD);
1432 }
1433 }
1434 out:
1435 tty_unlock(tp);
1436 return (error);
1437 }
1438
1439 /*
1440 * kqueue support.
1441 */
1442 int ptsd_kqfilter(dev_t, struct knote *);
1443 static void ptsd_kqops_read_detach(struct knote *);
1444 static int ptsd_kqops_read_event(struct knote *, long);
1445 static void ptsd_kqops_write_detach(struct knote *);
1446 static int ptsd_kqops_write_event(struct knote *, long);
1447
1448 static struct filterops ptsd_kqops_read = {
1449 .f_isfd = 1,
1450 .f_detach = ptsd_kqops_read_detach,
1451 .f_event = ptsd_kqops_read_event,
1452 };
1453 static struct filterops ptsd_kqops_write = {
1454 .f_isfd = 1,
1455 .f_detach = ptsd_kqops_write_detach,
1456 .f_event = ptsd_kqops_write_event,
1457 };
1458
1459 static void
1460 ptsd_kqops_read_detach(struct knote *kn)
1461 {
1462 struct ptmx_ioctl *pti;
1463 struct tty *tp;
1464 dev_t dev = (dev_t) kn->kn_hookid;
1465
1466 pti = ptmx_get_ioctl(minor(dev), 0);
1467 tp = pti->pt_tty;
1468
1469 if (tp == NULL)
1470 return;
1471
1472 tty_lock(tp);
1473 KNOTE_DETACH(&tp->t_rsel.si_note, kn);
1474 tty_unlock(tp);
1475
1476 kn->kn_hookid = 0;
1477 }
1478
1479 static int
1480 ptsd_kqops_read_event(struct knote *kn, long hint)
1481 {
1482 struct ptmx_ioctl *pti;
1483 struct tty *tp;
1484 dev_t dev = (dev_t) kn->kn_hookid;
1485 int retval = 0;
1486
1487 pti = ptmx_get_ioctl(minor(dev), 0);
1488 tp = pti->pt_tty;
1489
1490 if (tp == NULL)
1491 return (ENXIO);
1492
1493 if (hint == 0)
1494 tty_lock(tp);
1495
1496 kn->kn_data = ttnread(tp);
1497 if (kn->kn_data > 0) {
1498 retval = 1;
1499 }
1500
1501 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1502 kn->kn_flags |= EV_EOF;
1503 retval = 1;
1504 }
1505
1506 if (hint == 0)
1507 tty_unlock(tp);
1508 return (retval);
1509 }
1510 static void
1511 ptsd_kqops_write_detach(struct knote *kn)
1512 {
1513 struct ptmx_ioctl *pti;
1514 struct tty *tp;
1515 dev_t dev = (dev_t) kn->kn_hookid;
1516
1517 pti = ptmx_get_ioctl(minor(dev), 0);
1518 tp = pti->pt_tty;
1519
1520 if (tp == NULL)
1521 return;
1522
1523 tty_lock(tp);
1524 KNOTE_DETACH(&tp->t_wsel.si_note, kn);
1525 tty_unlock(tp);
1526
1527 kn->kn_hookid = 0;
1528 }
1529
1530 static int
1531 ptsd_kqops_write_event(struct knote *kn, long hint)
1532 {
1533 struct ptmx_ioctl *pti;
1534 struct tty *tp;
1535 dev_t dev = (dev_t) kn->kn_hookid;
1536 int retval = 0;
1537
1538 pti = ptmx_get_ioctl(minor(dev), 0);
1539 tp = pti->pt_tty;
1540
1541 if (tp == NULL)
1542 return (ENXIO);
1543
1544 if (hint == 0)
1545 tty_lock(tp);
1546
1547 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
1548 ISSET(tp->t_state, TS_CONNECTED)) {
1549 kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc;
1550 retval = 1;
1551 }
1552
1553 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1554 kn->kn_flags |= EV_EOF;
1555 retval = 1;
1556 }
1557
1558 if (hint == 0)
1559 tty_unlock(tp);
1560 return (retval);
1561
1562 }
1563
1564 int
1565 ptsd_kqfilter(dev_t dev, struct knote *kn)
1566 {
1567 struct tty *tp = NULL;
1568 struct ptmx_ioctl *pti = NULL;
1569 int retval = 0;
1570
1571 /* make sure we're talking about the right device type */
1572 if (cdevsw[major(dev)].d_open != ptsd_open) {
1573 return (EINVAL);
1574 }
1575
1576 if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
1577 return (ENXIO);
1578 }
1579
1580 tp = pti->pt_tty;
1581 tty_lock(tp);
1582
1583 kn->kn_hookid = dev;
1584
1585 switch (kn->kn_filter) {
1586 case EVFILT_READ:
1587 kn->kn_fop = &ptsd_kqops_read;
1588 SLIST_INIT(&tp->t_rsel.si_note);
1589 KNOTE_ATTACH(&tp->t_rsel.si_note, kn);
1590 break;
1591 case EVFILT_WRITE:
1592 kn->kn_fop = &ptsd_kqops_write;
1593 SLIST_INIT(&tp->t_wsel.si_note);
1594 KNOTE_ATTACH(&tp->t_wsel.si_note, kn);
1595 break;
1596 default:
1597 retval = EINVAL;
1598 break;
1599 }
1600
1601 tty_unlock(tp);
1602 return (retval);
1603 }
1604