1 /* 2 * Copyright (c) 2006 Robert N. M. Watson 3 * Copyright (c) 2006 Olivier Houchard 4 * Copyright (c) 2003 Networks Associates Technology, Inc. 5 * All rights reserved. 6 * 7 * This software was developed for the FreeBSD Project in part by Network 8 * Associates Laboratories, the Security Research Division of Network 9 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 10 * as part of the DARPA CHATS research program. 11 * 12 * Copyright (c) 1982, 1986, 1989, 1993 13 * The Regents of the University of California. All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 40 */ 41 42 #include <sys/cdefs.h> 43 __FBSDID("$FreeBSD$"); 44 45 /* 46 * Pseudo-teletype Driver 47 * (Actually two drivers, requiring two entries in 'cdevsw') 48 */ 49 #include "opt_compat.h" 50 #include "opt_tty.h" 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/lock.h> 54 #include <sys/mutex.h> 55 #include <sys/sx.h> 56 #if defined(COMPAT_43TTY) 57 #include <sys/ioctl_compat.h> 58 #endif 59 #include <sys/proc.h> 60 #include <sys/queue.h> 61 #include <sys/tty.h> 62 #include <sys/fcntl.h> 63 #include <sys/poll.h> 64 #include <sys/kernel.h> 65 #include <sys/vnode.h> 66 #include <sys/signalvar.h> 67 #include <sys/malloc.h> 68 #include <sys/conf.h> 69 #include <sys/sysctl.h> 70 #include <sys/filio.h> 71 72 static MALLOC_DEFINE(M_PTY, "ptys", "pty data structures"); 73 74 static void ptsstart(struct tty *tp); 75 static void ptsstop(struct tty *tp, int rw); 76 static void ptcwakeup(struct tty *tp, int flag); 77 78 static d_open_t ptsopen; 79 static d_close_t ptsclose; 80 static d_read_t ptsread; 81 static d_write_t ptswrite; 82 static d_ioctl_t ptsioctl; 83 static d_ioctl_t ptcioctl; 84 static d_open_t ptcopen; 85 static d_close_t ptcclose; 86 static d_read_t ptcread; 87 static d_write_t ptcwrite; 88 static d_poll_t ptcpoll; 89 90 static struct cdevsw pts_cdevsw = { 91 .d_version = D_VERSION, 92 .d_open = ptsopen, 93 .d_close = ptsclose, 94 .d_read = ptsread, 95 .d_write = ptswrite, 96 .d_ioctl = ptsioctl, 97 .d_poll = ttypoll, 98 .d_name = "pts", 99 .d_flags = D_TTY | D_NEEDGIANT, 100 .d_kqfilter = ttykqfilter, 101 }; 102 103 static struct cdevsw ptc_cdevsw = { 104 .d_version = D_VERSION, 105 .d_open = ptcopen, 106 .d_close = ptcclose, 107 .d_read = ptcread, 108 .d_write = ptcwrite, 109 .d_ioctl = ptcioctl, 110 .d_poll = ptcpoll, 111 .d_name = "ptc", 112 .d_flags = D_TTY | D_NEEDGIANT, 113 .d_kqfilter = ttykqfilter, 114 }; 115 116 #define BUFSIZ 100 /* Chunk size iomoved to/from user */ 117 118 #define TSA_PTC_READ(tp) ((void *)&(tp)->t_outq.c_cf) 119 #define TSA_PTC_WRITE(tp) ((void *)&(tp)->t_rawq.c_cl) 120 #define TSA_PTS_READ(tp) ((void *)&(tp)->t_canq) 121 122 #define NUM_TO_MINOR(c) ((c & 0xff) | ((c & ~0xff) << 16)) 123 /*- 124 * Once a tty is allocated, it cannot (currently) be freed. As such, 125 * we keep a global list of ptys that have been used so we can recycle 126 * them. An another list is provided for released pts, whiiich are 127 * not currently allocated, permitting reuse. pt_flags holds state 128 * associated with a particular session, so isn't overloaded for this. 129 * When a pty descriptor is unused, its number is set to -1 giving 130 * more consistent and traditional allocation orders to pty numbers. 131 * 132 * Locking: (p) indicates that the field is locked by the global pt_mtx. 133 * (c) indicates the value is constant after allocation. Other fields 134 * await tty locking generally, and are protected by Giant. 135 */ 136 struct pt_desc { 137 int pt_num; /* (c) pty number */ 138 LIST_ENTRY(pt_desc) pt_list; /* (p) global pty list */ 139 140 int pt_flags; 141 struct selinfo pt_selr, pt_selw; 142 u_char pt_send; 143 u_char pt_ucntl; 144 struct tty *pt_tty; 145 struct cdev *pt_devs, *pt_devc; 146 int pt_pts_open, pt_ptc_open; 147 struct prison *pt_prison; 148 }; 149 150 static struct mtx pt_mtx; 151 static LIST_HEAD(,pt_desc) pt_list; 152 static LIST_HEAD(,pt_desc) pt_free_list; 153 154 #define PF_PKT 0x008 /* packet mode */ 155 #define PF_STOPPED 0x010 /* user told stopped */ 156 #define PF_NOSTOP 0x040 157 #define PF_UCNTL 0x080 /* user control mode */ 158 159 static unsigned int next_avail_nb; 160 161 static int use_pts = 0; 162 163 static unsigned int max_pts = 1000; 164 165 static unsigned int nb_allocated; 166 167 TUNABLE_INT("kern.pts.enable", &use_pts); 168 169 SYSCTL_NODE(_kern, OID_AUTO, pts, CTLFLAG_RD, 0, "pts"); 170 171 SYSCTL_INT(_kern_pts, OID_AUTO, enable, CTLFLAG_RW, &use_pts, 0, 172 "enable pts"); 173 174 SYSCTL_INT(_kern_pts, OID_AUTO, max, CTLFLAG_RW, &max_pts, 0, "max pts"); 175 176 /* 177 * If there's a free pty descriptor in the pty descriptor list, retrieve it. 178 * Otherwise, allocate a new one, initialize it, and hook it up. If there's 179 * not a tty number, reject. 180 */ 181 static struct pt_desc * 182 pty_new(void) 183 { 184 struct pt_desc *pt; 185 int nb; 186 187 mtx_lock(&pt_mtx); 188 if (nb_allocated >= max_pts || nb_allocated == 0xffffff) { 189 mtx_unlock(&pt_mtx); 190 return (NULL); 191 } 192 pt = LIST_FIRST(&pt_free_list); 193 if (pt) { 194 LIST_REMOVE(pt, pt_list); 195 LIST_INSERT_HEAD(&pt_list, pt, pt_list); 196 mtx_unlock(&pt_mtx); 197 } else { 198 nb = next_avail_nb++; 199 mtx_unlock(&pt_mtx); 200 pt = malloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO); 201 mtx_lock(&pt_mtx); 202 pt->pt_num = nb; 203 LIST_INSERT_HEAD(&pt_list, pt, pt_list); 204 mtx_unlock(&pt_mtx); 205 pt->pt_tty = ttyalloc(); 206 } 207 nb_allocated++; 208 return (pt); 209 } 210 211 /* 212 * Release a pty descriptor back to the pool for reuse. The pty number 213 * remains allocated. 214 */ 215 static void 216 pty_release(struct pt_desc *pt) 217 { 218 219 KASSERT(pt->pt_ptc_open == 0 && pt->pt_pts_open == 0, 220 ("pty_release: pts/%d freed while open\n", pt->pt_num)); 221 KASSERT(pt->pt_devs == NULL && pt->pt_devc == NULL, 222 ("pty_release: pts/%d freed whith non-null struct cdev\n", pt->pt_num)); 223 mtx_assert(&pt_mtx, MA_OWNED); 224 nb_allocated--; 225 LIST_REMOVE(pt, pt_list); 226 LIST_INSERT_HEAD(&pt_free_list, pt, pt_list); 227 } 228 229 /* 230 * Given a pty descriptor, if both endpoints are closed, release all 231 * resources and destroy the device nodes to flush file system level 232 * state for the tty (owner, avoid races, etc). 233 */ 234 static void 235 pty_maybecleanup(struct pt_desc *pt) 236 { 237 238 if (pt->pt_ptc_open || pt->pt_pts_open) 239 return; 240 241 if (pt->pt_tty->t_refcnt > 1) 242 return; 243 244 if (bootverbose) 245 printf("destroying pty %d\n", pt->pt_num); 246 247 destroy_dev(pt->pt_devs); 248 destroy_dev(pt->pt_devc); 249 pt->pt_devs = pt->pt_devc = NULL; 250 pt->pt_tty->t_dev = NULL; 251 ttyrel(pt->pt_tty); 252 pt->pt_tty = NULL; 253 254 mtx_lock(&pt_mtx); 255 pty_release(pt); 256 mtx_unlock(&pt_mtx); 257 } 258 259 /*ARGSUSED*/ 260 static int 261 ptsopen(struct cdev *dev, int flag, int devtype, struct thread *td) 262 { 263 struct tty *tp; 264 int error; 265 struct pt_desc *pt; 266 267 pt = dev->si_drv1; 268 tp = dev->si_tty; 269 if ((tp->t_state & TS_ISOPEN) == 0) 270 ttyinitmode(tp, 1, 0); 271 else if (tp->t_state & TS_XCLUDE && suser(td)) { 272 return (EBUSY); 273 } else if (pt->pt_prison != td->td_ucred->cr_prison && suser(td)) { 274 return (EBUSY); 275 } 276 if (tp->t_oproc) /* Ctrlr still around. */ 277 ttyld_modem(tp, 1); 278 while ((tp->t_state & TS_CARR_ON) == 0) { 279 if (flag&FNONBLOCK) 280 break; 281 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH, 282 "ptsopn", 0); 283 if (error) 284 return (error); 285 } 286 error = ttyld_open(tp, dev); 287 if (error == 0) { 288 ptcwakeup(tp, FREAD|FWRITE); 289 pt->pt_pts_open = 1; 290 } 291 return (error); 292 } 293 294 static int 295 ptsclose(struct cdev *dev, int flag, int mode, struct thread *td) 296 { 297 struct pt_desc *pt = dev->si_drv1; 298 struct tty *tp; 299 int err; 300 301 tp = dev->si_tty; 302 err = ttyld_close(tp, flag); 303 ptsstop(tp, FREAD|FWRITE); 304 (void) tty_close(tp); 305 pt->pt_pts_open = 0; 306 pty_maybecleanup(pt); 307 return (err); 308 } 309 310 static int 311 ptsread(struct cdev *dev, struct uio *uio, int flag) 312 { 313 struct tty *tp = dev->si_tty; 314 int error = 0; 315 316 if (tp->t_oproc) 317 error = ttyld_read(tp, uio, flag); 318 ptcwakeup(tp, FWRITE); 319 return (error); 320 } 321 322 /* 323 * Write to pseudo-tty. 324 * Wakeups of controlling tty will happen 325 * indirectly, when tty driver calls ptsstart. 326 */ 327 static int 328 ptswrite(struct cdev *dev, struct uio *uio, int flag) 329 { 330 struct tty *tp; 331 332 tp = dev->si_tty; 333 if (tp->t_oproc == 0) 334 return (EIO); 335 return (ttyld_write(tp, uio, flag)); 336 } 337 338 /* 339 * Start output on pseudo-tty. 340 * Wake up process selecting or sleeping for input from controlling tty. 341 */ 342 static void 343 ptsstart(struct tty *tp) 344 { 345 struct pt_desc *pt = tp->t_dev->si_drv1; 346 347 if (tp->t_state & TS_TTSTOP) 348 return; 349 if (pt->pt_flags & PF_STOPPED) { 350 pt->pt_flags &= ~PF_STOPPED; 351 pt->pt_send = TIOCPKT_START; 352 } 353 ptcwakeup(tp, FREAD); 354 } 355 356 static void 357 ptcwakeup(struct tty *tp, int flag) 358 { 359 struct pt_desc *pt = tp->t_dev->si_drv1; 360 361 if (flag & FREAD) { 362 selwakeup(&pt->pt_selr); 363 wakeup(TSA_PTC_READ(tp)); 364 } 365 if (flag & FWRITE) { 366 selwakeup(&pt->pt_selw); 367 wakeup(TSA_PTC_WRITE(tp)); 368 } 369 } 370 371 /* 372 * ptcopen implementes exclusive access to the master/control device 373 * as well as creating the slave device based on the credential of the 374 * process opening the master. By creating the slave here, we avoid 375 * a race to access the master in terms of having a process with access 376 * to an incorrectly owned slave, but it does create the possibility 377 * that a racing process can cause a ptmx user to get EIO if it gets 378 * there first. Consumers of ptmx must look for EIO and retry if it 379 * happens. VFS locking may actually prevent this from occurring due 380 * to the lookup into devfs holding the vnode lock through open, but 381 * it's better to be careful. 382 */ 383 static int 384 ptcopen(struct cdev *dev, int flag, int devtype, struct thread *td) 385 { 386 struct pt_desc *pt; 387 struct tty *tp; 388 struct cdev *devs; 389 390 pt = dev->si_drv1; 391 /* 392 * In case we have destroyed the struct tty at the last connect time, 393 * we need to recreate it. 394 */ 395 if (pt->pt_tty == NULL) { 396 pt->pt_tty = ttyalloc(); 397 dev->si_tty = pt->pt_tty; 398 } 399 tp = dev->si_tty; 400 if (tp->t_oproc) 401 return (EIO); 402 403 /* 404 * XXX: Might want to make the ownership/permissions here more 405 * configurable. 406 */ 407 if (pt->pt_devs) 408 devs = pt->pt_devs; 409 else 410 pt->pt_devs = devs = make_dev_cred(&pts_cdevsw, 411 NUM_TO_MINOR(pt->pt_num), 412 td->td_ucred, UID_ROOT, GID_WHEEL, 0666, "pts/%d", 413 pt->pt_num); 414 devs->si_drv1 = pt; 415 devs->si_tty = pt->pt_tty; 416 pt->pt_tty->t_dev = devs; 417 418 tp->t_timeout = -1; 419 tp->t_oproc = ptsstart; 420 tp->t_stop = ptsstop; 421 ttyld_modem(tp, 1); 422 tp->t_lflag &= ~EXTPROC; 423 pt = dev->si_drv1; 424 pt->pt_prison = td->td_ucred->cr_prison; 425 pt->pt_flags = 0; 426 pt->pt_send = 0; 427 pt->pt_ucntl = 0; 428 pt->pt_ptc_open = 1; 429 return (0); 430 } 431 432 static int 433 ptcclose(struct cdev *dev, int flags, int fmt, struct thread *td) 434 { 435 struct pt_desc *pt = dev->si_drv1; 436 struct tty *tp; 437 438 tp = dev->si_tty; 439 ttyld_modem(tp, 0); 440 441 /* 442 * XXX MDMBUF makes no sense for ptys but would inhibit the above 443 * l_modem(). CLOCAL makes sense but isn't supported. Special 444 * l_modem()s that ignore carrier drop make no sense for ptys but 445 * may be in use because other parts of the line discipline make 446 * sense for ptys. Recover by doing everything that a normal 447 * ttymodem() would have done except for sending a SIGHUP. 448 */ 449 if (tp->t_state & TS_ISOPEN) { 450 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED); 451 tp->t_state |= TS_ZOMBIE; 452 ttyflush(tp, FREAD | FWRITE); 453 } 454 455 tp->t_oproc = 0; /* mark closed */ 456 pt->pt_ptc_open = 0; 457 pty_maybecleanup(pt); 458 return (0); 459 } 460 461 static int 462 ptcread(struct cdev *dev, struct uio *uio, int flag) 463 { 464 struct tty *tp = dev->si_tty; 465 struct pt_desc *pt = dev->si_drv1; 466 char buf[BUFSIZ]; 467 int error = 0, cc; 468 469 /* 470 * We want to block until the slave 471 * is open, and there's something to read; 472 * but if we lost the slave or we're NBIO, 473 * then return the appropriate error instead. 474 */ 475 for (;;) { 476 if (tp->t_state&TS_ISOPEN) { 477 if (pt->pt_flags&PF_PKT && pt->pt_send) { 478 error = ureadc((int)pt->pt_send, uio); 479 if (error) 480 return (error); 481 if (pt->pt_send & TIOCPKT_IOCTL) { 482 cc = min(uio->uio_resid, 483 sizeof(tp->t_termios)); 484 uiomove(&tp->t_termios, cc, uio); 485 } 486 pt->pt_send = 0; 487 return (0); 488 } 489 if (pt->pt_flags&PF_UCNTL && pt->pt_ucntl) { 490 error = ureadc((int)pt->pt_ucntl, uio); 491 if (error) 492 return (error); 493 pt->pt_ucntl = 0; 494 return (0); 495 } 496 if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) 497 break; 498 } 499 if ((tp->t_state & TS_CONNECTED) == 0) 500 return (0); /* EOF */ 501 if (flag & O_NONBLOCK) 502 return (EWOULDBLOCK); 503 error = tsleep(TSA_PTC_READ(tp), TTIPRI | PCATCH, "ptcin", 0); 504 if (error) 505 return (error); 506 } 507 if (pt->pt_flags & (PF_PKT|PF_UCNTL)) 508 error = ureadc(0, uio); 509 while (uio->uio_resid > 0 && error == 0) { 510 cc = q_to_b(&tp->t_outq, buf, min(uio->uio_resid, BUFSIZ)); 511 if (cc <= 0) 512 break; 513 error = uiomove(buf, cc, uio); 514 } 515 ttwwakeup(tp); 516 return (error); 517 } 518 519 static void 520 ptsstop(struct tty *tp, int flush) 521 { 522 struct pt_desc *pt = tp->t_dev->si_drv1; 523 int flag; 524 525 /* note: FLUSHREAD and FLUSHWRITE already ok */ 526 if (flush == 0) { 527 flush = TIOCPKT_STOP; 528 pt->pt_flags |= PF_STOPPED; 529 } else 530 pt->pt_flags &= ~PF_STOPPED; 531 pt->pt_send |= flush; 532 /* change of perspective */ 533 flag = 0; 534 if (flush & FREAD) 535 flag |= FWRITE; 536 if (flush & FWRITE) 537 flag |= FREAD; 538 ptcwakeup(tp, flag); 539 } 540 541 static int 542 ptcpoll(struct cdev *dev, int events, struct thread *td) 543 { 544 struct tty *tp = dev->si_tty; 545 struct pt_desc *pt = dev->si_drv1; 546 int revents = 0; 547 int s; 548 549 if ((tp->t_state & TS_CONNECTED) == 0) 550 return (events & 551 (POLLHUP | POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)); 552 553 /* 554 * Need to block timeouts (ttrstart). 555 */ 556 s = spltty(); 557 558 if (events & (POLLIN | POLLRDNORM)) 559 if ((tp->t_state & TS_ISOPEN) && 560 ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) || 561 ((pt->pt_flags & PF_PKT) && pt->pt_send) || 562 ((pt->pt_flags & PF_UCNTL) && pt->pt_ucntl))) 563 revents |= events & (POLLIN | POLLRDNORM); 564 565 if (events & (POLLOUT | POLLWRNORM)) 566 if (tp->t_state & TS_ISOPEN && 567 (((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) || 568 (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) 569 revents |= events & (POLLOUT | POLLWRNORM); 570 571 if (events & POLLHUP) 572 if ((tp->t_state & TS_CARR_ON) == 0) 573 revents |= POLLHUP; 574 575 if (revents == 0) { 576 if (events & (POLLIN | POLLRDNORM)) 577 selrecord(td, &pt->pt_selr); 578 579 if (events & (POLLOUT | POLLWRNORM)) 580 selrecord(td, &pt->pt_selw); 581 } 582 splx(s); 583 584 return (revents); 585 } 586 587 static int 588 ptcwrite(struct cdev *dev, struct uio *uio, int flag) 589 { 590 struct tty *tp = dev->si_tty; 591 u_char *cp = 0; 592 int cc = 0; 593 u_char locbuf[BUFSIZ]; 594 int cnt = 0; 595 int error = 0; 596 597 again: 598 if ((tp->t_state&TS_ISOPEN) == 0) 599 goto block; 600 while (uio->uio_resid > 0 || cc > 0) { 601 if (cc == 0) { 602 cc = min(uio->uio_resid, BUFSIZ); 603 cp = locbuf; 604 error = uiomove(cp, cc, uio); 605 if (error) 606 return (error); 607 /* check again for safety */ 608 if ((tp->t_state & TS_ISOPEN) == 0) { 609 /* adjust for data copied in but not written */ 610 uio->uio_resid += cc; 611 return (EIO); 612 } 613 } 614 while (cc > 0) { 615 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 && 616 (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) { 617 wakeup(TSA_HUP_OR_INPUT(tp)); 618 goto block; 619 } 620 ttyld_rint(tp, *cp++); 621 cnt++; 622 cc--; 623 } 624 cc = 0; 625 } 626 return (0); 627 block: 628 /* 629 * Come here to wait for slave to open, for space 630 * in outq, or space in rawq, or an empty canq. 631 */ 632 if ((tp->t_state & TS_CONNECTED) == 0) { 633 /* adjust for data copied in but not written */ 634 uio->uio_resid += cc; 635 return (EIO); 636 } 637 if (flag & IO_NDELAY) { 638 /* adjust for data copied in but not written */ 639 uio->uio_resid += cc; 640 if (cnt == 0) 641 return (EWOULDBLOCK); 642 return (0); 643 } 644 error = tsleep(TSA_PTC_WRITE(tp), TTOPRI | PCATCH, "ptcout", 0); 645 if (error) { 646 /* adjust for data copied in but not written */ 647 uio->uio_resid += cc; 648 return (error); 649 } 650 goto again; 651 } 652 653 static int 654 ptcioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 655 { 656 struct tty *tp = dev->si_tty; 657 struct pt_desc *pt = dev->si_drv1; 658 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 659 defined(COMPAT_FREEBSD4) || defined(COMPAT_43) 660 int ival; 661 #endif 662 663 switch (cmd) { 664 665 case TIOCGPGRP: 666 /* 667 * We avoid calling ttioctl on the controller since, 668 * in that case, tp must be the controlling terminal. 669 */ 670 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0; 671 return (0); 672 673 case TIOCPKT: 674 if (*(int *)data) { 675 if (pt->pt_flags & PF_UCNTL) 676 return (EINVAL); 677 pt->pt_flags |= PF_PKT; 678 } else 679 pt->pt_flags &= ~PF_PKT; 680 return (0); 681 682 case TIOCUCNTL: 683 if (*(int *)data) { 684 if (pt->pt_flags & PF_PKT) 685 return (EINVAL); 686 pt->pt_flags |= PF_UCNTL; 687 } else 688 pt->pt_flags &= ~PF_UCNTL; 689 return (0); 690 case TIOCGPTN: 691 *(unsigned int *)data = pt->pt_num; 692 return (0); 693 } 694 695 /* 696 * The rest of the ioctls shouldn't be called until 697 * the slave is open. 698 */ 699 if ((tp->t_state & TS_ISOPEN) == 0) { 700 if (cmd == TIOCGETA) { 701 /* 702 * TIOCGETA is used by isatty() to make sure it's 703 * a tty. Linux openpty() calls isatty() very early, 704 * before the slave is opened, so don't actually 705 * fill the struct termios, but just let isatty() 706 * know it's a tty. 707 */ 708 return (0); 709 } 710 if (cmd != FIONBIO && cmd != FIOASYNC) 711 return (EAGAIN); 712 } 713 714 switch (cmd) { 715 #ifdef COMPAT_43TTY 716 case TIOCSETP: 717 case TIOCSETN: 718 #endif 719 case TIOCSETD: 720 case TIOCSETA: 721 case TIOCSETAW: 722 case TIOCSETAF: 723 /* 724 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG. 725 * ttywflush(tp) will hang if there are characters in 726 * the outq. 727 */ 728 ndflush(&tp->t_outq, tp->t_outq.c_cc); 729 break; 730 731 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 732 defined(COMPAT_FREEBSD4) || defined(COMPAT_43) 733 case _IO('t', 95): 734 ival = IOCPARM_IVAL(data); 735 data = (caddr_t)&ival; 736 /* FALLTHROUGH */ 737 #endif 738 case TIOCSIG: 739 if (*(unsigned int *)data >= NSIG || 740 *(unsigned int *)data == 0) 741 return(EINVAL); 742 if ((tp->t_lflag&NOFLSH) == 0) 743 ttyflush(tp, FREAD|FWRITE); 744 if (tp->t_pgrp != NULL) { 745 PGRP_LOCK(tp->t_pgrp); 746 pgsignal(tp->t_pgrp, *(unsigned int *)data, 1); 747 PGRP_UNLOCK(tp->t_pgrp); 748 } 749 if ((*(unsigned int *)data == SIGINFO) && 750 ((tp->t_lflag&NOKERNINFO) == 0)) 751 ttyinfo(tp); 752 return(0); 753 } 754 return (ptsioctl(dev, cmd, data, flag, td)); 755 } 756 /*ARGSUSED*/ 757 static int 758 ptsioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 759 { 760 struct tty *tp = dev->si_tty; 761 struct pt_desc *pt = dev->si_drv1; 762 u_char *cc = tp->t_cc; 763 int stop, error; 764 765 if (cmd == TIOCEXT) { 766 /* 767 * When the EXTPROC bit is being toggled, we need 768 * to send an TIOCPKT_IOCTL if the packet driver 769 * is turned on. 770 */ 771 if (*(int *)data) { 772 if (pt->pt_flags & PF_PKT) { 773 pt->pt_send |= TIOCPKT_IOCTL; 774 ptcwakeup(tp, FREAD); 775 } 776 tp->t_lflag |= EXTPROC; 777 } else { 778 if ((tp->t_lflag & EXTPROC) && 779 (pt->pt_flags & PF_PKT)) { 780 pt->pt_send |= TIOCPKT_IOCTL; 781 ptcwakeup(tp, FREAD); 782 } 783 tp->t_lflag &= ~EXTPROC; 784 } 785 return(0); 786 } 787 error = ttioctl(tp, cmd, data, flag); 788 if (error == ENOTTY) { 789 if (pt->pt_flags & PF_UCNTL && 790 (cmd & ~0xff) == UIOCCMD(0)) { 791 if (cmd & 0xff) { 792 pt->pt_ucntl = (u_char)cmd; 793 ptcwakeup(tp, FREAD); 794 } 795 return (0); 796 } 797 error = ENOTTY; 798 } 799 /* 800 * If external processing and packet mode send ioctl packet. 801 */ 802 if ((tp->t_lflag&EXTPROC) && (pt->pt_flags & PF_PKT)) { 803 switch(cmd) { 804 case TIOCSETA: 805 case TIOCSETAW: 806 case TIOCSETAF: 807 #ifdef COMPAT_43TTY 808 case TIOCSETP: 809 case TIOCSETN: 810 case TIOCSETC: 811 case TIOCSLTC: 812 case TIOCLBIS: 813 case TIOCLBIC: 814 case TIOCLSET: 815 #endif 816 pt->pt_send |= TIOCPKT_IOCTL; 817 ptcwakeup(tp, FREAD); 818 break; 819 default: 820 break; 821 } 822 } 823 stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s')) 824 && CCEQ(cc[VSTART], CTRL('q')); 825 if (pt->pt_flags & PF_NOSTOP) { 826 if (stop) { 827 pt->pt_send &= ~TIOCPKT_NOSTOP; 828 pt->pt_send |= TIOCPKT_DOSTOP; 829 pt->pt_flags &= ~PF_NOSTOP; 830 ptcwakeup(tp, FREAD); 831 } 832 } else { 833 if (!stop) { 834 pt->pt_send &= ~TIOCPKT_DOSTOP; 835 pt->pt_send |= TIOCPKT_NOSTOP; 836 pt->pt_flags |= PF_NOSTOP; 837 ptcwakeup(tp, FREAD); 838 } 839 } 840 return (error); 841 } 842 843 /* 844 * Match lookups on /dev/ptmx, find the next free pty (if any), set up 845 * the pty descriptor, register it, and return a reference to the master. 846 * 847 * pts == /dev/pts/xxx (oldstyle: ttyp...) 848 * ptc == /dev/pty/xxx (oldstyle: ptyp...) 849 */ 850 static void 851 pty_clone(void *arg, struct ucred *cred, char *name, int namelen, 852 struct cdev **dev) 853 { 854 struct pt_desc *pt; 855 struct cdev *devc; 856 857 if (!use_pts) 858 return; 859 860 if (*dev != NULL) 861 return; 862 863 if (strcmp(name, "ptmx") != 0) 864 return; 865 866 pt = pty_new(); 867 if (pt == NULL) 868 return; 869 870 /* 871 * XXX: Lack of locking here considered worrying. We expose the 872 * pts/pty device nodes before they are fully initialized, although 873 * Giant likely protects us (unless make_dev blocks...?). 874 * 875 * XXX: If a process performs a lookup on /dev/ptmx but never an 876 * open, we won't GC the device node. We should have a callout 877 * sometime later that GC's device instances that were never 878 * opened, or some way to tell devfs that "this had better be for 879 * an open() or we won't create a device". 880 */ 881 pt->pt_devc = devc = make_dev_cred(&ptc_cdevsw, 882 NUM_TO_MINOR(pt->pt_num), cred, UID_ROOT, GID_WHEEL, 0666, 883 "pty/%d", pt->pt_num); 884 885 dev_ref(devc); 886 devc->si_drv1 = pt; 887 devc->si_tty = pt->pt_tty; 888 *dev = devc; 889 890 if (bootverbose) 891 printf("pty_clone: allocated pty %d to uid %d\n", pt->pt_num, 892 cred->cr_ruid); 893 894 return; 895 } 896 897 static void 898 pty_drvinit(void *unused) 899 { 900 901 mtx_init(&pt_mtx, "pt_mtx", NULL, MTX_DEF); 902 LIST_INIT(&pt_list); 903 LIST_INIT(&pt_free_list); 904 EVENTHANDLER_REGISTER(dev_clone, pty_clone, 0, 1000); 905 } 906 907 SYSINIT(ptydev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE,pty_drvinit,NULL) 908