1 /*- 2 * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Portions of this software were developed under sponsorship from Snow 6 * B.V., the Netherlands. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include "opt_capsicum.h" 34 #include "opt_compat.h" 35 36 #include <sys/param.h> 37 #include <sys/capsicum.h> 38 #include <sys/conf.h> 39 #include <sys/cons.h> 40 #include <sys/fcntl.h> 41 #include <sys/file.h> 42 #include <sys/filedesc.h> 43 #include <sys/filio.h> 44 #ifdef COMPAT_43TTY 45 #include <sys/ioctl_compat.h> 46 #endif /* COMPAT_43TTY */ 47 #include <sys/kernel.h> 48 #include <sys/limits.h> 49 #include <sys/malloc.h> 50 #include <sys/mount.h> 51 #include <sys/poll.h> 52 #include <sys/priv.h> 53 #include <sys/proc.h> 54 #include <sys/serial.h> 55 #include <sys/signal.h> 56 #include <sys/stat.h> 57 #include <sys/sx.h> 58 #include <sys/sysctl.h> 59 #include <sys/systm.h> 60 #include <sys/tty.h> 61 #include <sys/ttycom.h> 62 #define TTYDEFCHARS 63 #include <sys/ttydefaults.h> 64 #undef TTYDEFCHARS 65 #include <sys/ucred.h> 66 #include <sys/vnode.h> 67 68 #include <machine/stdarg.h> 69 70 static MALLOC_DEFINE(M_TTY, "tty", "tty device"); 71 72 static void tty_rel_free(struct tty *tp); 73 74 static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list); 75 static struct sx tty_list_sx; 76 SX_SYSINIT(tty_list, &tty_list_sx, "tty list"); 77 static unsigned int tty_list_count = 0; 78 79 /* Character device of /dev/console. */ 80 static struct cdev *dev_console; 81 static const char *dev_console_filename; 82 83 /* 84 * Flags that are supported and stored by this implementation. 85 */ 86 #define TTYSUP_IFLAG (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|\ 87 INLCR|IGNCR|ICRNL|IXON|IXOFF|IXANY|IMAXBEL) 88 #define TTYSUP_OFLAG (OPOST|ONLCR|TAB3|ONOEOT|OCRNL|ONOCR|ONLRET) 89 #define TTYSUP_LFLAG (ECHOKE|ECHOE|ECHOK|ECHO|ECHONL|ECHOPRT|\ 90 ECHOCTL|ISIG|ICANON|ALTWERASE|IEXTEN|TOSTOP|\ 91 FLUSHO|NOKERNINFO|NOFLSH) 92 #define TTYSUP_CFLAG (CIGNORE|CSIZE|CSTOPB|CREAD|PARENB|PARODD|\ 93 HUPCL|CLOCAL|CCTS_OFLOW|CRTS_IFLOW|CDTR_IFLOW|\ 94 CDSR_OFLOW|CCAR_OFLOW) 95 96 #define TTY_CALLOUT(tp,d) (dev2unit(d) & TTYUNIT_CALLOUT) 97 98 /* 99 * Set TTY buffer sizes. 100 */ 101 102 #define TTYBUF_MAX 65536 103 104 static void 105 tty_watermarks(struct tty *tp) 106 { 107 size_t bs = 0; 108 109 /* Provide an input buffer for 0.2 seconds of data. */ 110 if (tp->t_termios.c_cflag & CREAD) 111 bs = MIN(tp->t_termios.c_ispeed / 5, TTYBUF_MAX); 112 ttyinq_setsize(&tp->t_inq, tp, bs); 113 114 /* Set low watermark at 10% (when 90% is available). */ 115 tp->t_inlow = (ttyinq_getallocatedsize(&tp->t_inq) * 9) / 10; 116 117 /* Provide an output buffer for 0.2 seconds of data. */ 118 bs = MIN(tp->t_termios.c_ospeed / 5, TTYBUF_MAX); 119 ttyoutq_setsize(&tp->t_outq, tp, bs); 120 121 /* Set low watermark at 10% (when 90% is available). */ 122 tp->t_outlow = (ttyoutq_getallocatedsize(&tp->t_outq) * 9) / 10; 123 } 124 125 static int 126 tty_drain(struct tty *tp, int leaving) 127 { 128 size_t bytesused; 129 int error, revokecnt; 130 131 if (ttyhook_hashook(tp, getc_inject)) 132 /* buffer is inaccessible */ 133 return (0); 134 135 while (ttyoutq_bytesused(&tp->t_outq) > 0 || ttydevsw_busy(tp)) { 136 ttydevsw_outwakeup(tp); 137 /* Could be handled synchronously. */ 138 bytesused = ttyoutq_bytesused(&tp->t_outq); 139 if (bytesused == 0 && !ttydevsw_busy(tp)) 140 return (0); 141 142 /* Wait for data to be drained. */ 143 if (leaving) { 144 revokecnt = tp->t_revokecnt; 145 error = tty_timedwait(tp, &tp->t_outwait, hz); 146 switch (error) { 147 case ERESTART: 148 if (revokecnt != tp->t_revokecnt) 149 error = 0; 150 break; 151 case EWOULDBLOCK: 152 if (ttyoutq_bytesused(&tp->t_outq) < bytesused) 153 error = 0; 154 break; 155 } 156 } else 157 error = tty_wait(tp, &tp->t_outwait); 158 159 if (error) 160 return (error); 161 } 162 163 return (0); 164 } 165 166 /* 167 * Though ttydev_enter() and ttydev_leave() seem to be related, they 168 * don't have to be used together. ttydev_enter() is used by the cdev 169 * operations to prevent an actual operation from being processed when 170 * the TTY has been abandoned. ttydev_leave() is used by ttydev_open() 171 * and ttydev_close() to determine whether per-TTY data should be 172 * deallocated. 173 */ 174 175 static __inline int 176 ttydev_enter(struct tty *tp) 177 { 178 tty_lock(tp); 179 180 if (tty_gone(tp) || !tty_opened(tp)) { 181 /* Device is already gone. */ 182 tty_unlock(tp); 183 return (ENXIO); 184 } 185 186 return (0); 187 } 188 189 static void 190 ttydev_leave(struct tty *tp) 191 { 192 tty_lock_assert(tp, MA_OWNED); 193 194 if (tty_opened(tp) || tp->t_flags & TF_OPENCLOSE) { 195 /* Device is still opened somewhere. */ 196 tty_unlock(tp); 197 return; 198 } 199 200 tp->t_flags |= TF_OPENCLOSE; 201 202 /* Stop asynchronous I/O. */ 203 funsetown(&tp->t_sigio); 204 205 /* Remove console TTY. */ 206 if (constty == tp) 207 constty_clear(); 208 209 /* Drain any output. */ 210 MPASS((tp->t_flags & TF_STOPPED) == 0); 211 if (!tty_gone(tp)) 212 tty_drain(tp, 1); 213 214 ttydisc_close(tp); 215 216 /* Free i/o queues now since they might be large. */ 217 ttyinq_free(&tp->t_inq); 218 tp->t_inlow = 0; 219 ttyoutq_free(&tp->t_outq); 220 tp->t_outlow = 0; 221 222 knlist_clear(&tp->t_inpoll.si_note, 1); 223 knlist_clear(&tp->t_outpoll.si_note, 1); 224 225 if (!tty_gone(tp)) 226 ttydevsw_close(tp); 227 228 tp->t_flags &= ~TF_OPENCLOSE; 229 cv_broadcast(&tp->t_dcdwait); 230 tty_rel_free(tp); 231 } 232 233 /* 234 * Operations that are exposed through the character device in /dev. 235 */ 236 static int 237 ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 238 { 239 struct tty *tp; 240 int error; 241 242 tp = dev->si_drv1; 243 error = 0; 244 tty_lock(tp); 245 if (tty_gone(tp)) { 246 /* Device is already gone. */ 247 tty_unlock(tp); 248 return (ENXIO); 249 } 250 251 /* 252 * Block when other processes are currently opening or closing 253 * the TTY. 254 */ 255 while (tp->t_flags & TF_OPENCLOSE) { 256 error = tty_wait(tp, &tp->t_dcdwait); 257 if (error != 0) { 258 tty_unlock(tp); 259 return (error); 260 } 261 } 262 tp->t_flags |= TF_OPENCLOSE; 263 264 /* 265 * Make sure the "tty" and "cua" device cannot be opened at the 266 * same time. 267 */ 268 if (TTY_CALLOUT(tp, dev)) { 269 if (tp->t_flags & TF_OPENED_IN) { 270 error = EBUSY; 271 goto done; 272 } 273 } else { 274 if (tp->t_flags & TF_OPENED_OUT) { 275 error = EBUSY; 276 goto done; 277 } 278 } 279 280 if (tp->t_flags & TF_EXCLUDE && priv_check(td, PRIV_TTY_EXCLUSIVE)) { 281 error = EBUSY; 282 goto done; 283 } 284 285 if (!tty_opened(tp)) { 286 /* Set proper termios flags. */ 287 if (TTY_CALLOUT(tp, dev)) 288 tp->t_termios = tp->t_termios_init_out; 289 else 290 tp->t_termios = tp->t_termios_init_in; 291 ttydevsw_param(tp, &tp->t_termios); 292 /* Prevent modem control on callout devices and /dev/console. */ 293 if (TTY_CALLOUT(tp, dev) || dev == dev_console) 294 tp->t_termios.c_cflag |= CLOCAL; 295 296 ttydevsw_modem(tp, SER_DTR|SER_RTS, 0); 297 298 error = ttydevsw_open(tp); 299 if (error != 0) 300 goto done; 301 302 ttydisc_open(tp); 303 tty_watermarks(tp); /* XXXGL: drops lock */ 304 } 305 306 /* Wait for Carrier Detect. */ 307 if ((oflags & O_NONBLOCK) == 0 && 308 (tp->t_termios.c_cflag & CLOCAL) == 0) { 309 while ((ttydevsw_modem(tp, 0, 0) & SER_DCD) == 0) { 310 error = tty_wait(tp, &tp->t_dcdwait); 311 if (error != 0) 312 goto done; 313 } 314 } 315 316 if (dev == dev_console) 317 tp->t_flags |= TF_OPENED_CONS; 318 else if (TTY_CALLOUT(tp, dev)) 319 tp->t_flags |= TF_OPENED_OUT; 320 else 321 tp->t_flags |= TF_OPENED_IN; 322 323 done: tp->t_flags &= ~TF_OPENCLOSE; 324 cv_broadcast(&tp->t_dcdwait); 325 ttydev_leave(tp); 326 327 return (error); 328 } 329 330 static int 331 ttydev_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 332 { 333 struct tty *tp = dev->si_drv1; 334 335 tty_lock(tp); 336 337 /* 338 * Don't actually close the device if it is being used as the 339 * console. 340 */ 341 MPASS((tp->t_flags & TF_OPENED) != TF_OPENED); 342 if (dev == dev_console) 343 tp->t_flags &= ~TF_OPENED_CONS; 344 else 345 tp->t_flags &= ~(TF_OPENED_IN|TF_OPENED_OUT); 346 347 if (tp->t_flags & TF_OPENED) { 348 tty_unlock(tp); 349 return (0); 350 } 351 352 /* 353 * This can only be called once. The callin and the callout 354 * devices cannot be opened at the same time. 355 */ 356 tp->t_flags &= ~(TF_EXCLUDE|TF_STOPPED); 357 358 /* Properly wake up threads that are stuck - revoke(). */ 359 tp->t_revokecnt++; 360 tty_wakeup(tp, FREAD|FWRITE); 361 cv_broadcast(&tp->t_bgwait); 362 cv_broadcast(&tp->t_dcdwait); 363 364 ttydev_leave(tp); 365 366 return (0); 367 } 368 369 static __inline int 370 tty_is_ctty(struct tty *tp, struct proc *p) 371 { 372 tty_lock_assert(tp, MA_OWNED); 373 374 return (p->p_session == tp->t_session && p->p_flag & P_CONTROLT); 375 } 376 377 int 378 tty_wait_background(struct tty *tp, struct thread *td, int sig) 379 { 380 struct proc *p = td->td_proc; 381 struct pgrp *pg; 382 ksiginfo_t ksi; 383 int error; 384 385 MPASS(sig == SIGTTIN || sig == SIGTTOU); 386 tty_lock_assert(tp, MA_OWNED); 387 388 for (;;) { 389 PROC_LOCK(p); 390 /* 391 * The process should only sleep, when: 392 * - This terminal is the controling terminal 393 * - Its process group is not the foreground process 394 * group 395 * - The parent process isn't waiting for the child to 396 * exit 397 * - the signal to send to the process isn't masked 398 */ 399 if (!tty_is_ctty(tp, p) || p->p_pgrp == tp->t_pgrp) { 400 /* Allow the action to happen. */ 401 PROC_UNLOCK(p); 402 return (0); 403 } 404 405 if (SIGISMEMBER(p->p_sigacts->ps_sigignore, sig) || 406 SIGISMEMBER(td->td_sigmask, sig)) { 407 /* Only allow them in write()/ioctl(). */ 408 PROC_UNLOCK(p); 409 return (sig == SIGTTOU ? 0 : EIO); 410 } 411 412 pg = p->p_pgrp; 413 if (p->p_flag & P_PPWAIT || pg->pg_jobc == 0) { 414 /* Don't allow the action to happen. */ 415 PROC_UNLOCK(p); 416 return (EIO); 417 } 418 PROC_UNLOCK(p); 419 420 /* 421 * Send the signal and sleep until we're the new 422 * foreground process group. 423 */ 424 if (sig != 0) { 425 ksiginfo_init(&ksi); 426 ksi.ksi_code = SI_KERNEL; 427 ksi.ksi_signo = sig; 428 sig = 0; 429 } 430 PGRP_LOCK(pg); 431 pgsignal(pg, ksi.ksi_signo, 1, &ksi); 432 PGRP_UNLOCK(pg); 433 434 error = tty_wait(tp, &tp->t_bgwait); 435 if (error) 436 return (error); 437 } 438 } 439 440 static int 441 ttydev_read(struct cdev *dev, struct uio *uio, int ioflag) 442 { 443 struct tty *tp = dev->si_drv1; 444 int error; 445 446 error = ttydev_enter(tp); 447 if (error) 448 goto done; 449 error = ttydisc_read(tp, uio, ioflag); 450 tty_unlock(tp); 451 452 /* 453 * The read() call should not throw an error when the device is 454 * being destroyed. Silently convert it to an EOF. 455 */ 456 done: if (error == ENXIO) 457 error = 0; 458 return (error); 459 } 460 461 static int 462 ttydev_write(struct cdev *dev, struct uio *uio, int ioflag) 463 { 464 struct tty *tp = dev->si_drv1; 465 int error; 466 467 error = ttydev_enter(tp); 468 if (error) 469 return (error); 470 471 if (tp->t_termios.c_lflag & TOSTOP) { 472 error = tty_wait_background(tp, curthread, SIGTTOU); 473 if (error) 474 goto done; 475 } 476 477 if (ioflag & IO_NDELAY && tp->t_flags & TF_BUSY_OUT) { 478 /* Allow non-blocking writes to bypass serialization. */ 479 error = ttydisc_write(tp, uio, ioflag); 480 } else { 481 /* Serialize write() calls. */ 482 while (tp->t_flags & TF_BUSY_OUT) { 483 error = tty_wait(tp, &tp->t_outserwait); 484 if (error) 485 goto done; 486 } 487 488 tp->t_flags |= TF_BUSY_OUT; 489 error = ttydisc_write(tp, uio, ioflag); 490 tp->t_flags &= ~TF_BUSY_OUT; 491 cv_signal(&tp->t_outserwait); 492 } 493 494 done: tty_unlock(tp); 495 return (error); 496 } 497 498 static int 499 ttydev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 500 struct thread *td) 501 { 502 struct tty *tp = dev->si_drv1; 503 int error; 504 505 error = ttydev_enter(tp); 506 if (error) 507 return (error); 508 509 switch (cmd) { 510 case TIOCCBRK: 511 case TIOCCONS: 512 case TIOCDRAIN: 513 case TIOCEXCL: 514 case TIOCFLUSH: 515 case TIOCNXCL: 516 case TIOCSBRK: 517 case TIOCSCTTY: 518 case TIOCSETA: 519 case TIOCSETAF: 520 case TIOCSETAW: 521 case TIOCSPGRP: 522 case TIOCSTART: 523 case TIOCSTAT: 524 case TIOCSTI: 525 case TIOCSTOP: 526 case TIOCSWINSZ: 527 #if 0 528 case TIOCSDRAINWAIT: 529 case TIOCSETD: 530 #endif 531 #ifdef COMPAT_43TTY 532 case TIOCLBIC: 533 case TIOCLBIS: 534 case TIOCLSET: 535 case TIOCSETC: 536 case OTIOCSETD: 537 case TIOCSETN: 538 case TIOCSETP: 539 case TIOCSLTC: 540 #endif /* COMPAT_43TTY */ 541 /* 542 * If the ioctl() causes the TTY to be modified, let it 543 * wait in the background. 544 */ 545 error = tty_wait_background(tp, curthread, SIGTTOU); 546 if (error) 547 goto done; 548 } 549 550 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) { 551 struct termios *old = &tp->t_termios; 552 struct termios *new = (struct termios *)data; 553 struct termios *lock = TTY_CALLOUT(tp, dev) ? 554 &tp->t_termios_lock_out : &tp->t_termios_lock_in; 555 int cc; 556 557 /* 558 * Lock state devices. Just overwrite the values of the 559 * commands that are currently in use. 560 */ 561 new->c_iflag = (old->c_iflag & lock->c_iflag) | 562 (new->c_iflag & ~lock->c_iflag); 563 new->c_oflag = (old->c_oflag & lock->c_oflag) | 564 (new->c_oflag & ~lock->c_oflag); 565 new->c_cflag = (old->c_cflag & lock->c_cflag) | 566 (new->c_cflag & ~lock->c_cflag); 567 new->c_lflag = (old->c_lflag & lock->c_lflag) | 568 (new->c_lflag & ~lock->c_lflag); 569 for (cc = 0; cc < NCCS; ++cc) 570 if (lock->c_cc[cc]) 571 new->c_cc[cc] = old->c_cc[cc]; 572 if (lock->c_ispeed) 573 new->c_ispeed = old->c_ispeed; 574 if (lock->c_ospeed) 575 new->c_ospeed = old->c_ospeed; 576 } 577 578 error = tty_ioctl(tp, cmd, data, fflag, td); 579 done: tty_unlock(tp); 580 581 return (error); 582 } 583 584 static int 585 ttydev_poll(struct cdev *dev, int events, struct thread *td) 586 { 587 struct tty *tp = dev->si_drv1; 588 int error, revents = 0; 589 590 error = ttydev_enter(tp); 591 if (error) 592 return ((events & (POLLIN|POLLRDNORM)) | POLLHUP); 593 594 if (events & (POLLIN|POLLRDNORM)) { 595 /* See if we can read something. */ 596 if (ttydisc_read_poll(tp) > 0) 597 revents |= events & (POLLIN|POLLRDNORM); 598 } 599 600 if (tp->t_flags & TF_ZOMBIE) { 601 /* Hangup flag on zombie state. */ 602 revents |= POLLHUP; 603 } else if (events & (POLLOUT|POLLWRNORM)) { 604 /* See if we can write something. */ 605 if (ttydisc_write_poll(tp) > 0) 606 revents |= events & (POLLOUT|POLLWRNORM); 607 } 608 609 if (revents == 0) { 610 if (events & (POLLIN|POLLRDNORM)) 611 selrecord(td, &tp->t_inpoll); 612 if (events & (POLLOUT|POLLWRNORM)) 613 selrecord(td, &tp->t_outpoll); 614 } 615 616 tty_unlock(tp); 617 618 return (revents); 619 } 620 621 static int 622 ttydev_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, 623 int nprot, vm_memattr_t *memattr) 624 { 625 struct tty *tp = dev->si_drv1; 626 int error; 627 628 /* Handle mmap() through the driver. */ 629 630 error = ttydev_enter(tp); 631 if (error) 632 return (-1); 633 error = ttydevsw_mmap(tp, offset, paddr, nprot, memattr); 634 tty_unlock(tp); 635 636 return (error); 637 } 638 639 /* 640 * kqueue support. 641 */ 642 643 static void 644 tty_kqops_read_detach(struct knote *kn) 645 { 646 struct tty *tp = kn->kn_hook; 647 648 knlist_remove(&tp->t_inpoll.si_note, kn, 0); 649 } 650 651 static int 652 tty_kqops_read_event(struct knote *kn, long hint) 653 { 654 struct tty *tp = kn->kn_hook; 655 656 tty_lock_assert(tp, MA_OWNED); 657 658 if (tty_gone(tp) || tp->t_flags & TF_ZOMBIE) { 659 kn->kn_flags |= EV_EOF; 660 return (1); 661 } else { 662 kn->kn_data = ttydisc_read_poll(tp); 663 return (kn->kn_data > 0); 664 } 665 } 666 667 static void 668 tty_kqops_write_detach(struct knote *kn) 669 { 670 struct tty *tp = kn->kn_hook; 671 672 knlist_remove(&tp->t_outpoll.si_note, kn, 0); 673 } 674 675 static int 676 tty_kqops_write_event(struct knote *kn, long hint) 677 { 678 struct tty *tp = kn->kn_hook; 679 680 tty_lock_assert(tp, MA_OWNED); 681 682 if (tty_gone(tp)) { 683 kn->kn_flags |= EV_EOF; 684 return (1); 685 } else { 686 kn->kn_data = ttydisc_write_poll(tp); 687 return (kn->kn_data > 0); 688 } 689 } 690 691 static struct filterops tty_kqops_read = { 692 .f_isfd = 1, 693 .f_detach = tty_kqops_read_detach, 694 .f_event = tty_kqops_read_event, 695 }; 696 static struct filterops tty_kqops_write = { 697 .f_isfd = 1, 698 .f_detach = tty_kqops_write_detach, 699 .f_event = tty_kqops_write_event, 700 }; 701 702 static int 703 ttydev_kqfilter(struct cdev *dev, struct knote *kn) 704 { 705 struct tty *tp = dev->si_drv1; 706 int error; 707 708 error = ttydev_enter(tp); 709 if (error) 710 return (error); 711 712 switch (kn->kn_filter) { 713 case EVFILT_READ: 714 kn->kn_hook = tp; 715 kn->kn_fop = &tty_kqops_read; 716 knlist_add(&tp->t_inpoll.si_note, kn, 1); 717 break; 718 case EVFILT_WRITE: 719 kn->kn_hook = tp; 720 kn->kn_fop = &tty_kqops_write; 721 knlist_add(&tp->t_outpoll.si_note, kn, 1); 722 break; 723 default: 724 error = EINVAL; 725 break; 726 } 727 728 tty_unlock(tp); 729 return (error); 730 } 731 732 static struct cdevsw ttydev_cdevsw = { 733 .d_version = D_VERSION, 734 .d_open = ttydev_open, 735 .d_close = ttydev_close, 736 .d_read = ttydev_read, 737 .d_write = ttydev_write, 738 .d_ioctl = ttydev_ioctl, 739 .d_kqfilter = ttydev_kqfilter, 740 .d_poll = ttydev_poll, 741 .d_mmap = ttydev_mmap, 742 .d_name = "ttydev", 743 .d_flags = D_TTY, 744 }; 745 746 /* 747 * Init/lock-state devices 748 */ 749 750 static int 751 ttyil_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 752 { 753 struct tty *tp; 754 int error; 755 756 tp = dev->si_drv1; 757 error = 0; 758 tty_lock(tp); 759 if (tty_gone(tp)) 760 error = ENODEV; 761 tty_unlock(tp); 762 763 return (error); 764 } 765 766 static int 767 ttyil_close(struct cdev *dev, int flag, int mode, struct thread *td) 768 { 769 return (0); 770 } 771 772 static int 773 ttyil_rdwr(struct cdev *dev, struct uio *uio, int ioflag) 774 { 775 return (ENODEV); 776 } 777 778 static int 779 ttyil_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 780 struct thread *td) 781 { 782 struct tty *tp = dev->si_drv1; 783 int error; 784 785 tty_lock(tp); 786 if (tty_gone(tp)) { 787 error = ENODEV; 788 goto done; 789 } 790 791 error = ttydevsw_cioctl(tp, dev2unit(dev), cmd, data, td); 792 if (error != ENOIOCTL) 793 goto done; 794 error = 0; 795 796 switch (cmd) { 797 case TIOCGETA: 798 /* Obtain terminal flags through tcgetattr(). */ 799 *(struct termios*)data = *(struct termios*)dev->si_drv2; 800 break; 801 case TIOCSETA: 802 /* Set terminal flags through tcsetattr(). */ 803 error = priv_check(td, PRIV_TTY_SETA); 804 if (error) 805 break; 806 *(struct termios*)dev->si_drv2 = *(struct termios*)data; 807 break; 808 case TIOCGETD: 809 *(int *)data = TTYDISC; 810 break; 811 case TIOCGWINSZ: 812 bzero(data, sizeof(struct winsize)); 813 break; 814 default: 815 error = ENOTTY; 816 } 817 818 done: tty_unlock(tp); 819 return (error); 820 } 821 822 static struct cdevsw ttyil_cdevsw = { 823 .d_version = D_VERSION, 824 .d_open = ttyil_open, 825 .d_close = ttyil_close, 826 .d_read = ttyil_rdwr, 827 .d_write = ttyil_rdwr, 828 .d_ioctl = ttyil_ioctl, 829 .d_name = "ttyil", 830 .d_flags = D_TTY, 831 }; 832 833 static void 834 tty_init_termios(struct tty *tp) 835 { 836 struct termios *t = &tp->t_termios_init_in; 837 838 t->c_cflag = TTYDEF_CFLAG; 839 t->c_iflag = TTYDEF_IFLAG; 840 t->c_lflag = TTYDEF_LFLAG; 841 t->c_oflag = TTYDEF_OFLAG; 842 t->c_ispeed = TTYDEF_SPEED; 843 t->c_ospeed = TTYDEF_SPEED; 844 memcpy(&t->c_cc, ttydefchars, sizeof ttydefchars); 845 846 tp->t_termios_init_out = *t; 847 } 848 849 void 850 tty_init_console(struct tty *tp, speed_t s) 851 { 852 struct termios *ti = &tp->t_termios_init_in; 853 struct termios *to = &tp->t_termios_init_out; 854 855 if (s != 0) { 856 ti->c_ispeed = ti->c_ospeed = s; 857 to->c_ispeed = to->c_ospeed = s; 858 } 859 860 ti->c_cflag |= CLOCAL; 861 to->c_cflag |= CLOCAL; 862 } 863 864 /* 865 * Standard device routine implementations, mostly meant for 866 * pseudo-terminal device drivers. When a driver creates a new terminal 867 * device class, missing routines are patched. 868 */ 869 870 static int 871 ttydevsw_defopen(struct tty *tp) 872 { 873 874 return (0); 875 } 876 877 static void 878 ttydevsw_defclose(struct tty *tp) 879 { 880 } 881 882 static void 883 ttydevsw_defoutwakeup(struct tty *tp) 884 { 885 886 panic("Terminal device has output, while not implemented"); 887 } 888 889 static void 890 ttydevsw_definwakeup(struct tty *tp) 891 { 892 } 893 894 static int 895 ttydevsw_defioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) 896 { 897 898 return (ENOIOCTL); 899 } 900 901 static int 902 ttydevsw_defcioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td) 903 { 904 905 return (ENOIOCTL); 906 } 907 908 static int 909 ttydevsw_defparam(struct tty *tp, struct termios *t) 910 { 911 912 /* 913 * Allow the baud rate to be adjusted for pseudo-devices, but at 914 * least restrict it to 115200 to prevent excessive buffer 915 * usage. Also disallow 0, to prevent foot shooting. 916 */ 917 if (t->c_ispeed < B50) 918 t->c_ispeed = B50; 919 else if (t->c_ispeed > B115200) 920 t->c_ispeed = B115200; 921 if (t->c_ospeed < B50) 922 t->c_ospeed = B50; 923 else if (t->c_ospeed > B115200) 924 t->c_ospeed = B115200; 925 t->c_cflag |= CREAD; 926 927 return (0); 928 } 929 930 static int 931 ttydevsw_defmodem(struct tty *tp, int sigon, int sigoff) 932 { 933 934 /* Simulate a carrier to make the TTY layer happy. */ 935 return (SER_DCD); 936 } 937 938 static int 939 ttydevsw_defmmap(struct tty *tp, vm_ooffset_t offset, vm_paddr_t *paddr, 940 int nprot, vm_memattr_t *memattr) 941 { 942 943 return (-1); 944 } 945 946 static void 947 ttydevsw_defpktnotify(struct tty *tp, char event) 948 { 949 } 950 951 static void 952 ttydevsw_deffree(void *softc) 953 { 954 955 panic("Terminal device freed without a free-handler"); 956 } 957 958 static bool 959 ttydevsw_defbusy(struct tty *tp __unused) 960 { 961 962 return (FALSE); 963 } 964 965 /* 966 * TTY allocation and deallocation. TTY devices can be deallocated when 967 * the driver doesn't use it anymore, when the TTY isn't a session's 968 * controlling TTY and when the device node isn't opened through devfs. 969 */ 970 971 struct tty * 972 tty_alloc(struct ttydevsw *tsw, void *sc) 973 { 974 975 return (tty_alloc_mutex(tsw, sc, NULL)); 976 } 977 978 struct tty * 979 tty_alloc_mutex(struct ttydevsw *tsw, void *sc, struct mtx *mutex) 980 { 981 struct tty *tp; 982 983 /* Make sure the driver defines all routines. */ 984 #define PATCH_FUNC(x) do { \ 985 if (tsw->tsw_ ## x == NULL) \ 986 tsw->tsw_ ## x = ttydevsw_def ## x; \ 987 } while (0) 988 PATCH_FUNC(open); 989 PATCH_FUNC(close); 990 PATCH_FUNC(outwakeup); 991 PATCH_FUNC(inwakeup); 992 PATCH_FUNC(ioctl); 993 PATCH_FUNC(cioctl); 994 PATCH_FUNC(param); 995 PATCH_FUNC(modem); 996 PATCH_FUNC(mmap); 997 PATCH_FUNC(pktnotify); 998 PATCH_FUNC(free); 999 PATCH_FUNC(busy); 1000 #undef PATCH_FUNC 1001 1002 tp = malloc(sizeof(struct tty), M_TTY, M_WAITOK|M_ZERO); 1003 tp->t_devsw = tsw; 1004 tp->t_devswsoftc = sc; 1005 tp->t_flags = tsw->tsw_flags; 1006 1007 tty_init_termios(tp); 1008 1009 cv_init(&tp->t_inwait, "ttyin"); 1010 cv_init(&tp->t_outwait, "ttyout"); 1011 cv_init(&tp->t_outserwait, "ttyosr"); 1012 cv_init(&tp->t_bgwait, "ttybg"); 1013 cv_init(&tp->t_dcdwait, "ttydcd"); 1014 1015 /* Allow drivers to use a custom mutex to lock the TTY. */ 1016 if (mutex != NULL) { 1017 tp->t_mtx = mutex; 1018 } else { 1019 tp->t_mtx = &tp->t_mtxobj; 1020 mtx_init(&tp->t_mtxobj, "ttymtx", NULL, MTX_DEF); 1021 } 1022 1023 knlist_init_mtx(&tp->t_inpoll.si_note, tp->t_mtx); 1024 knlist_init_mtx(&tp->t_outpoll.si_note, tp->t_mtx); 1025 1026 return (tp); 1027 } 1028 1029 static void 1030 tty_dealloc(void *arg) 1031 { 1032 struct tty *tp = arg; 1033 1034 /* 1035 * ttyydev_leave() usually frees the i/o queues earlier, but it is 1036 * not always called between queue allocation and here. The queues 1037 * may be allocated by ioctls on a pty control device without the 1038 * corresponding pty slave device ever being open, or after it is 1039 * closed. 1040 */ 1041 ttyinq_free(&tp->t_inq); 1042 ttyoutq_free(&tp->t_outq); 1043 seldrain(&tp->t_inpoll); 1044 seldrain(&tp->t_outpoll); 1045 knlist_destroy(&tp->t_inpoll.si_note); 1046 knlist_destroy(&tp->t_outpoll.si_note); 1047 1048 cv_destroy(&tp->t_inwait); 1049 cv_destroy(&tp->t_outwait); 1050 cv_destroy(&tp->t_bgwait); 1051 cv_destroy(&tp->t_dcdwait); 1052 cv_destroy(&tp->t_outserwait); 1053 1054 if (tp->t_mtx == &tp->t_mtxobj) 1055 mtx_destroy(&tp->t_mtxobj); 1056 ttydevsw_free(tp); 1057 free(tp, M_TTY); 1058 } 1059 1060 static void 1061 tty_rel_free(struct tty *tp) 1062 { 1063 struct cdev *dev; 1064 1065 tty_lock_assert(tp, MA_OWNED); 1066 1067 #define TF_ACTIVITY (TF_GONE|TF_OPENED|TF_HOOK|TF_OPENCLOSE) 1068 if (tp->t_sessioncnt != 0 || (tp->t_flags & TF_ACTIVITY) != TF_GONE) { 1069 /* TTY is still in use. */ 1070 tty_unlock(tp); 1071 return; 1072 } 1073 1074 /* TTY can be deallocated. */ 1075 dev = tp->t_dev; 1076 tp->t_dev = NULL; 1077 tty_unlock(tp); 1078 1079 if (dev != NULL) { 1080 sx_xlock(&tty_list_sx); 1081 TAILQ_REMOVE(&tty_list, tp, t_list); 1082 tty_list_count--; 1083 sx_xunlock(&tty_list_sx); 1084 destroy_dev_sched_cb(dev, tty_dealloc, tp); 1085 } 1086 } 1087 1088 void 1089 tty_rel_pgrp(struct tty *tp, struct pgrp *pg) 1090 { 1091 MPASS(tp->t_sessioncnt > 0); 1092 tty_lock_assert(tp, MA_OWNED); 1093 1094 if (tp->t_pgrp == pg) 1095 tp->t_pgrp = NULL; 1096 1097 tty_unlock(tp); 1098 } 1099 1100 void 1101 tty_rel_sess(struct tty *tp, struct session *sess) 1102 { 1103 MPASS(tp->t_sessioncnt > 0); 1104 1105 /* Current session has left. */ 1106 if (tp->t_session == sess) { 1107 tp->t_session = NULL; 1108 MPASS(tp->t_pgrp == NULL); 1109 } 1110 tp->t_sessioncnt--; 1111 tty_rel_free(tp); 1112 } 1113 1114 void 1115 tty_rel_gone(struct tty *tp) 1116 { 1117 MPASS(!tty_gone(tp)); 1118 1119 /* Simulate carrier removal. */ 1120 ttydisc_modem(tp, 0); 1121 1122 /* Wake up all blocked threads. */ 1123 tty_wakeup(tp, FREAD|FWRITE); 1124 cv_broadcast(&tp->t_bgwait); 1125 cv_broadcast(&tp->t_dcdwait); 1126 1127 tp->t_flags |= TF_GONE; 1128 tty_rel_free(tp); 1129 } 1130 1131 /* 1132 * Exposing information about current TTY's through sysctl 1133 */ 1134 1135 static void 1136 tty_to_xtty(struct tty *tp, struct xtty *xt) 1137 { 1138 tty_lock_assert(tp, MA_OWNED); 1139 1140 xt->xt_size = sizeof(struct xtty); 1141 xt->xt_insize = ttyinq_getsize(&tp->t_inq); 1142 xt->xt_incc = ttyinq_bytescanonicalized(&tp->t_inq); 1143 xt->xt_inlc = ttyinq_bytesline(&tp->t_inq); 1144 xt->xt_inlow = tp->t_inlow; 1145 xt->xt_outsize = ttyoutq_getsize(&tp->t_outq); 1146 xt->xt_outcc = ttyoutq_bytesused(&tp->t_outq); 1147 xt->xt_outlow = tp->t_outlow; 1148 xt->xt_column = tp->t_column; 1149 xt->xt_pgid = tp->t_pgrp ? tp->t_pgrp->pg_id : 0; 1150 xt->xt_sid = tp->t_session ? tp->t_session->s_sid : 0; 1151 xt->xt_flags = tp->t_flags; 1152 xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : NODEV; 1153 } 1154 1155 static int 1156 sysctl_kern_ttys(SYSCTL_HANDLER_ARGS) 1157 { 1158 unsigned long lsize; 1159 struct xtty *xtlist, *xt; 1160 struct tty *tp; 1161 int error; 1162 1163 sx_slock(&tty_list_sx); 1164 lsize = tty_list_count * sizeof(struct xtty); 1165 if (lsize == 0) { 1166 sx_sunlock(&tty_list_sx); 1167 return (0); 1168 } 1169 1170 xtlist = xt = malloc(lsize, M_TTY, M_WAITOK); 1171 1172 TAILQ_FOREACH(tp, &tty_list, t_list) { 1173 tty_lock(tp); 1174 tty_to_xtty(tp, xt); 1175 tty_unlock(tp); 1176 xt++; 1177 } 1178 sx_sunlock(&tty_list_sx); 1179 1180 error = SYSCTL_OUT(req, xtlist, lsize); 1181 free(xtlist, M_TTY); 1182 return (error); 1183 } 1184 1185 SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, 1186 0, 0, sysctl_kern_ttys, "S,xtty", "List of TTYs"); 1187 1188 /* 1189 * Device node creation. Device has been set up, now we can expose it to 1190 * the user. 1191 */ 1192 1193 int 1194 tty_makedevf(struct tty *tp, struct ucred *cred, int flags, 1195 const char *fmt, ...) 1196 { 1197 va_list ap; 1198 struct make_dev_args args; 1199 struct cdev *dev, *init, *lock, *cua, *cinit, *clock; 1200 const char *prefix = "tty"; 1201 char name[SPECNAMELEN - 3]; /* for "tty" and "cua". */ 1202 uid_t uid; 1203 gid_t gid; 1204 mode_t mode; 1205 int error; 1206 1207 /* Remove "tty" prefix from devices like PTY's. */ 1208 if (tp->t_flags & TF_NOPREFIX) 1209 prefix = ""; 1210 1211 va_start(ap, fmt); 1212 vsnrprintf(name, sizeof name, 32, fmt, ap); 1213 va_end(ap); 1214 1215 if (cred == NULL) { 1216 /* System device. */ 1217 uid = UID_ROOT; 1218 gid = GID_WHEEL; 1219 mode = S_IRUSR|S_IWUSR; 1220 } else { 1221 /* User device. */ 1222 uid = cred->cr_ruid; 1223 gid = GID_TTY; 1224 mode = S_IRUSR|S_IWUSR|S_IWGRP; 1225 } 1226 1227 flags = flags & TTYMK_CLONING ? MAKEDEV_REF : 0; 1228 flags |= MAKEDEV_CHECKNAME; 1229 1230 /* Master call-in device. */ 1231 make_dev_args_init(&args); 1232 args.mda_flags = flags; 1233 args.mda_devsw = &ttydev_cdevsw; 1234 args.mda_cr = cred; 1235 args.mda_uid = uid; 1236 args.mda_gid = gid; 1237 args.mda_mode = mode; 1238 args.mda_si_drv1 = tp; 1239 error = make_dev_s(&args, &dev, "%s%s", prefix, name); 1240 if (error != 0) 1241 return (error); 1242 tp->t_dev = dev; 1243 1244 init = lock = cua = cinit = clock = NULL; 1245 1246 /* Slave call-in devices. */ 1247 if (tp->t_flags & TF_INITLOCK) { 1248 args.mda_devsw = &ttyil_cdevsw; 1249 args.mda_unit = TTYUNIT_INIT; 1250 args.mda_si_drv1 = tp; 1251 args.mda_si_drv2 = &tp->t_termios_init_in; 1252 error = make_dev_s(&args, &init, "%s%s.init", prefix, name); 1253 if (error != 0) 1254 goto fail; 1255 dev_depends(dev, init); 1256 1257 args.mda_unit = TTYUNIT_LOCK; 1258 args.mda_si_drv2 = &tp->t_termios_lock_in; 1259 error = make_dev_s(&args, &lock, "%s%s.lock", prefix, name); 1260 if (error != 0) 1261 goto fail; 1262 dev_depends(dev, lock); 1263 } 1264 1265 /* Call-out devices. */ 1266 if (tp->t_flags & TF_CALLOUT) { 1267 make_dev_args_init(&args); 1268 args.mda_flags = flags; 1269 args.mda_devsw = &ttydev_cdevsw; 1270 args.mda_cr = cred; 1271 args.mda_uid = UID_UUCP; 1272 args.mda_gid = GID_DIALER; 1273 args.mda_mode = 0660; 1274 args.mda_unit = TTYUNIT_CALLOUT; 1275 args.mda_si_drv1 = tp; 1276 error = make_dev_s(&args, &cua, "cua%s", name); 1277 if (error != 0) 1278 goto fail; 1279 dev_depends(dev, cua); 1280 1281 /* Slave call-out devices. */ 1282 if (tp->t_flags & TF_INITLOCK) { 1283 args.mda_devsw = &ttyil_cdevsw; 1284 args.mda_unit = TTYUNIT_CALLOUT | TTYUNIT_INIT; 1285 args.mda_si_drv2 = &tp->t_termios_init_out; 1286 error = make_dev_s(&args, &cinit, "cua%s.init", name); 1287 if (error != 0) 1288 goto fail; 1289 dev_depends(dev, cinit); 1290 1291 args.mda_unit = TTYUNIT_CALLOUT | TTYUNIT_LOCK; 1292 args.mda_si_drv2 = &tp->t_termios_lock_out; 1293 error = make_dev_s(&args, &clock, "cua%s.lock", name); 1294 if (error != 0) 1295 goto fail; 1296 dev_depends(dev, clock); 1297 } 1298 } 1299 1300 sx_xlock(&tty_list_sx); 1301 TAILQ_INSERT_TAIL(&tty_list, tp, t_list); 1302 tty_list_count++; 1303 sx_xunlock(&tty_list_sx); 1304 1305 return (0); 1306 1307 fail: 1308 destroy_dev(dev); 1309 if (init) 1310 destroy_dev(init); 1311 if (lock) 1312 destroy_dev(lock); 1313 if (cinit) 1314 destroy_dev(cinit); 1315 if (clock) 1316 destroy_dev(clock); 1317 1318 return (error); 1319 } 1320 1321 /* 1322 * Signalling processes. 1323 */ 1324 1325 void 1326 tty_signal_sessleader(struct tty *tp, int sig) 1327 { 1328 struct proc *p; 1329 1330 tty_lock_assert(tp, MA_OWNED); 1331 MPASS(sig >= 1 && sig < NSIG); 1332 1333 /* Make signals start output again. */ 1334 tp->t_flags &= ~TF_STOPPED; 1335 1336 if (tp->t_session != NULL && tp->t_session->s_leader != NULL) { 1337 p = tp->t_session->s_leader; 1338 PROC_LOCK(p); 1339 kern_psignal(p, sig); 1340 PROC_UNLOCK(p); 1341 } 1342 } 1343 1344 void 1345 tty_signal_pgrp(struct tty *tp, int sig) 1346 { 1347 ksiginfo_t ksi; 1348 1349 tty_lock_assert(tp, MA_OWNED); 1350 MPASS(sig >= 1 && sig < NSIG); 1351 1352 /* Make signals start output again. */ 1353 tp->t_flags &= ~TF_STOPPED; 1354 1355 if (sig == SIGINFO && !(tp->t_termios.c_lflag & NOKERNINFO)) 1356 tty_info(tp); 1357 if (tp->t_pgrp != NULL) { 1358 ksiginfo_init(&ksi); 1359 ksi.ksi_signo = sig; 1360 ksi.ksi_code = SI_KERNEL; 1361 PGRP_LOCK(tp->t_pgrp); 1362 pgsignal(tp->t_pgrp, sig, 1, &ksi); 1363 PGRP_UNLOCK(tp->t_pgrp); 1364 } 1365 } 1366 1367 void 1368 tty_wakeup(struct tty *tp, int flags) 1369 { 1370 if (tp->t_flags & TF_ASYNC && tp->t_sigio != NULL) 1371 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL)); 1372 1373 if (flags & FWRITE) { 1374 cv_broadcast(&tp->t_outwait); 1375 selwakeup(&tp->t_outpoll); 1376 KNOTE_LOCKED(&tp->t_outpoll.si_note, 0); 1377 } 1378 if (flags & FREAD) { 1379 cv_broadcast(&tp->t_inwait); 1380 selwakeup(&tp->t_inpoll); 1381 KNOTE_LOCKED(&tp->t_inpoll.si_note, 0); 1382 } 1383 } 1384 1385 int 1386 tty_wait(struct tty *tp, struct cv *cv) 1387 { 1388 int error; 1389 int revokecnt = tp->t_revokecnt; 1390 1391 tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED); 1392 MPASS(!tty_gone(tp)); 1393 1394 error = cv_wait_sig(cv, tp->t_mtx); 1395 1396 /* Bail out when the device slipped away. */ 1397 if (tty_gone(tp)) 1398 return (ENXIO); 1399 1400 /* Restart the system call when we may have been revoked. */ 1401 if (tp->t_revokecnt != revokecnt) 1402 return (ERESTART); 1403 1404 return (error); 1405 } 1406 1407 int 1408 tty_timedwait(struct tty *tp, struct cv *cv, int hz) 1409 { 1410 int error; 1411 int revokecnt = tp->t_revokecnt; 1412 1413 tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED); 1414 MPASS(!tty_gone(tp)); 1415 1416 error = cv_timedwait_sig(cv, tp->t_mtx, hz); 1417 1418 /* Bail out when the device slipped away. */ 1419 if (tty_gone(tp)) 1420 return (ENXIO); 1421 1422 /* Restart the system call when we may have been revoked. */ 1423 if (tp->t_revokecnt != revokecnt) 1424 return (ERESTART); 1425 1426 return (error); 1427 } 1428 1429 void 1430 tty_flush(struct tty *tp, int flags) 1431 { 1432 if (flags & FWRITE) { 1433 tp->t_flags &= ~TF_HIWAT_OUT; 1434 ttyoutq_flush(&tp->t_outq); 1435 tty_wakeup(tp, FWRITE); 1436 ttydevsw_pktnotify(tp, TIOCPKT_FLUSHWRITE); 1437 } 1438 if (flags & FREAD) { 1439 tty_hiwat_in_unblock(tp); 1440 ttyinq_flush(&tp->t_inq); 1441 ttydevsw_inwakeup(tp); 1442 ttydevsw_pktnotify(tp, TIOCPKT_FLUSHREAD); 1443 } 1444 } 1445 1446 void 1447 tty_set_winsize(struct tty *tp, const struct winsize *wsz) 1448 { 1449 1450 if (memcmp(&tp->t_winsize, wsz, sizeof(*wsz)) == 0) 1451 return; 1452 tp->t_winsize = *wsz; 1453 tty_signal_pgrp(tp, SIGWINCH); 1454 } 1455 1456 static int 1457 tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag, 1458 struct thread *td) 1459 { 1460 int error; 1461 1462 switch (cmd) { 1463 /* 1464 * Modem commands. 1465 * The SER_* and TIOCM_* flags are the same, but one bit 1466 * shifted. I don't know why. 1467 */ 1468 case TIOCSDTR: 1469 ttydevsw_modem(tp, SER_DTR, 0); 1470 return (0); 1471 case TIOCCDTR: 1472 ttydevsw_modem(tp, 0, SER_DTR); 1473 return (0); 1474 case TIOCMSET: { 1475 int bits = *(int *)data; 1476 ttydevsw_modem(tp, 1477 (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1, 1478 ((~bits) & (TIOCM_DTR | TIOCM_RTS)) >> 1); 1479 return (0); 1480 } 1481 case TIOCMBIS: { 1482 int bits = *(int *)data; 1483 ttydevsw_modem(tp, (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1, 0); 1484 return (0); 1485 } 1486 case TIOCMBIC: { 1487 int bits = *(int *)data; 1488 ttydevsw_modem(tp, 0, (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1); 1489 return (0); 1490 } 1491 case TIOCMGET: 1492 *(int *)data = TIOCM_LE + (ttydevsw_modem(tp, 0, 0) << 1); 1493 return (0); 1494 1495 case FIOASYNC: 1496 if (*(int *)data) 1497 tp->t_flags |= TF_ASYNC; 1498 else 1499 tp->t_flags &= ~TF_ASYNC; 1500 return (0); 1501 case FIONBIO: 1502 /* This device supports non-blocking operation. */ 1503 return (0); 1504 case FIONREAD: 1505 *(int *)data = ttyinq_bytescanonicalized(&tp->t_inq); 1506 return (0); 1507 case FIONWRITE: 1508 case TIOCOUTQ: 1509 *(int *)data = ttyoutq_bytesused(&tp->t_outq); 1510 return (0); 1511 case FIOSETOWN: 1512 if (tp->t_session != NULL && !tty_is_ctty(tp, td->td_proc)) 1513 /* Not allowed to set ownership. */ 1514 return (ENOTTY); 1515 1516 /* Temporarily unlock the TTY to set ownership. */ 1517 tty_unlock(tp); 1518 error = fsetown(*(int *)data, &tp->t_sigio); 1519 tty_lock(tp); 1520 return (error); 1521 case FIOGETOWN: 1522 if (tp->t_session != NULL && !tty_is_ctty(tp, td->td_proc)) 1523 /* Not allowed to set ownership. */ 1524 return (ENOTTY); 1525 1526 /* Get ownership. */ 1527 *(int *)data = fgetown(&tp->t_sigio); 1528 return (0); 1529 case TIOCGETA: 1530 /* Obtain terminal flags through tcgetattr(). */ 1531 *(struct termios*)data = tp->t_termios; 1532 return (0); 1533 case TIOCSETA: 1534 case TIOCSETAW: 1535 case TIOCSETAF: { 1536 struct termios *t = data; 1537 1538 /* 1539 * Who makes up these funny rules? According to POSIX, 1540 * input baud rate is set equal to the output baud rate 1541 * when zero. 1542 */ 1543 if (t->c_ispeed == 0) 1544 t->c_ispeed = t->c_ospeed; 1545 1546 /* Discard any unsupported bits. */ 1547 t->c_iflag &= TTYSUP_IFLAG; 1548 t->c_oflag &= TTYSUP_OFLAG; 1549 t->c_lflag &= TTYSUP_LFLAG; 1550 t->c_cflag &= TTYSUP_CFLAG; 1551 1552 /* Set terminal flags through tcsetattr(). */ 1553 if (cmd == TIOCSETAW || cmd == TIOCSETAF) { 1554 error = tty_drain(tp, 0); 1555 if (error) 1556 return (error); 1557 if (cmd == TIOCSETAF) 1558 tty_flush(tp, FREAD); 1559 } 1560 1561 /* 1562 * Only call param() when the flags really change. 1563 */ 1564 if ((t->c_cflag & CIGNORE) == 0 && 1565 (tp->t_termios.c_cflag != t->c_cflag || 1566 ((tp->t_termios.c_iflag ^ t->c_iflag) & 1567 (IXON|IXOFF|IXANY)) || 1568 tp->t_termios.c_ispeed != t->c_ispeed || 1569 tp->t_termios.c_ospeed != t->c_ospeed)) { 1570 error = ttydevsw_param(tp, t); 1571 if (error) 1572 return (error); 1573 1574 /* XXX: CLOCAL? */ 1575 1576 tp->t_termios.c_cflag = t->c_cflag & ~CIGNORE; 1577 tp->t_termios.c_ispeed = t->c_ispeed; 1578 tp->t_termios.c_ospeed = t->c_ospeed; 1579 1580 /* Baud rate has changed - update watermarks. */ 1581 tty_watermarks(tp); 1582 } 1583 1584 /* Copy new non-device driver parameters. */ 1585 tp->t_termios.c_iflag = t->c_iflag; 1586 tp->t_termios.c_oflag = t->c_oflag; 1587 tp->t_termios.c_lflag = t->c_lflag; 1588 memcpy(&tp->t_termios.c_cc, t->c_cc, sizeof t->c_cc); 1589 1590 ttydisc_optimize(tp); 1591 1592 if ((t->c_lflag & ICANON) == 0) { 1593 /* 1594 * When in non-canonical mode, wake up all 1595 * readers. Canonicalize any partial input. VMIN 1596 * and VTIME could also be adjusted. 1597 */ 1598 ttyinq_canonicalize(&tp->t_inq); 1599 tty_wakeup(tp, FREAD); 1600 } 1601 1602 /* 1603 * For packet mode: notify the PTY consumer that VSTOP 1604 * and VSTART may have been changed. 1605 */ 1606 if (tp->t_termios.c_iflag & IXON && 1607 tp->t_termios.c_cc[VSTOP] == CTRL('S') && 1608 tp->t_termios.c_cc[VSTART] == CTRL('Q')) 1609 ttydevsw_pktnotify(tp, TIOCPKT_DOSTOP); 1610 else 1611 ttydevsw_pktnotify(tp, TIOCPKT_NOSTOP); 1612 return (0); 1613 } 1614 case TIOCGETD: 1615 /* For compatibility - we only support TTYDISC. */ 1616 *(int *)data = TTYDISC; 1617 return (0); 1618 case TIOCGPGRP: 1619 if (!tty_is_ctty(tp, td->td_proc)) 1620 return (ENOTTY); 1621 1622 if (tp->t_pgrp != NULL) 1623 *(int *)data = tp->t_pgrp->pg_id; 1624 else 1625 *(int *)data = NO_PID; 1626 return (0); 1627 case TIOCGSID: 1628 if (!tty_is_ctty(tp, td->td_proc)) 1629 return (ENOTTY); 1630 1631 MPASS(tp->t_session); 1632 *(int *)data = tp->t_session->s_sid; 1633 return (0); 1634 case TIOCSCTTY: { 1635 struct proc *p = td->td_proc; 1636 1637 /* XXX: This looks awful. */ 1638 tty_unlock(tp); 1639 sx_xlock(&proctree_lock); 1640 tty_lock(tp); 1641 1642 if (!SESS_LEADER(p)) { 1643 /* Only the session leader may do this. */ 1644 sx_xunlock(&proctree_lock); 1645 return (EPERM); 1646 } 1647 1648 if (tp->t_session != NULL && tp->t_session == p->p_session) { 1649 /* This is already our controlling TTY. */ 1650 sx_xunlock(&proctree_lock); 1651 return (0); 1652 } 1653 1654 if (p->p_session->s_ttyp != NULL || 1655 (tp->t_session != NULL && tp->t_session->s_ttyvp != NULL && 1656 tp->t_session->s_ttyvp->v_type != VBAD)) { 1657 /* 1658 * There is already a relation between a TTY and 1659 * a session, or the caller is not the session 1660 * leader. 1661 * 1662 * Allow the TTY to be stolen when the vnode is 1663 * invalid, but the reference to the TTY is 1664 * still active. This allows immediate reuse of 1665 * TTYs of which the session leader has been 1666 * killed or the TTY revoked. 1667 */ 1668 sx_xunlock(&proctree_lock); 1669 return (EPERM); 1670 } 1671 1672 /* Connect the session to the TTY. */ 1673 tp->t_session = p->p_session; 1674 tp->t_session->s_ttyp = tp; 1675 tp->t_sessioncnt++; 1676 sx_xunlock(&proctree_lock); 1677 1678 /* Assign foreground process group. */ 1679 tp->t_pgrp = p->p_pgrp; 1680 PROC_LOCK(p); 1681 p->p_flag |= P_CONTROLT; 1682 PROC_UNLOCK(p); 1683 1684 return (0); 1685 } 1686 case TIOCSPGRP: { 1687 struct pgrp *pg; 1688 1689 /* 1690 * XXX: Temporarily unlock the TTY to locate the process 1691 * group. This code would be lot nicer if we would ever 1692 * decompose proctree_lock. 1693 */ 1694 tty_unlock(tp); 1695 sx_slock(&proctree_lock); 1696 pg = pgfind(*(int *)data); 1697 if (pg != NULL) 1698 PGRP_UNLOCK(pg); 1699 if (pg == NULL || pg->pg_session != td->td_proc->p_session) { 1700 sx_sunlock(&proctree_lock); 1701 tty_lock(tp); 1702 return (EPERM); 1703 } 1704 tty_lock(tp); 1705 1706 /* 1707 * Determine if this TTY is the controlling TTY after 1708 * relocking the TTY. 1709 */ 1710 if (!tty_is_ctty(tp, td->td_proc)) { 1711 sx_sunlock(&proctree_lock); 1712 return (ENOTTY); 1713 } 1714 tp->t_pgrp = pg; 1715 sx_sunlock(&proctree_lock); 1716 1717 /* Wake up the background process groups. */ 1718 cv_broadcast(&tp->t_bgwait); 1719 return (0); 1720 } 1721 case TIOCFLUSH: { 1722 int flags = *(int *)data; 1723 1724 if (flags == 0) 1725 flags = (FREAD|FWRITE); 1726 else 1727 flags &= (FREAD|FWRITE); 1728 tty_flush(tp, flags); 1729 return (0); 1730 } 1731 case TIOCDRAIN: 1732 /* Drain TTY output. */ 1733 return tty_drain(tp, 0); 1734 case TIOCCONS: 1735 /* Set terminal as console TTY. */ 1736 if (*(int *)data) { 1737 error = priv_check(td, PRIV_TTY_CONSOLE); 1738 if (error) 1739 return (error); 1740 1741 /* 1742 * XXX: constty should really need to be locked! 1743 * XXX: allow disconnected constty's to be stolen! 1744 */ 1745 1746 if (constty == tp) 1747 return (0); 1748 if (constty != NULL) 1749 return (EBUSY); 1750 1751 tty_unlock(tp); 1752 constty_set(tp); 1753 tty_lock(tp); 1754 } else if (constty == tp) { 1755 constty_clear(); 1756 } 1757 return (0); 1758 case TIOCGWINSZ: 1759 /* Obtain window size. */ 1760 *(struct winsize*)data = tp->t_winsize; 1761 return (0); 1762 case TIOCSWINSZ: 1763 /* Set window size. */ 1764 tty_set_winsize(tp, data); 1765 return (0); 1766 case TIOCEXCL: 1767 tp->t_flags |= TF_EXCLUDE; 1768 return (0); 1769 case TIOCNXCL: 1770 tp->t_flags &= ~TF_EXCLUDE; 1771 return (0); 1772 case TIOCSTOP: 1773 tp->t_flags |= TF_STOPPED; 1774 ttydevsw_pktnotify(tp, TIOCPKT_STOP); 1775 return (0); 1776 case TIOCSTART: 1777 tp->t_flags &= ~TF_STOPPED; 1778 ttydevsw_outwakeup(tp); 1779 ttydevsw_pktnotify(tp, TIOCPKT_START); 1780 return (0); 1781 case TIOCSTAT: 1782 tty_info(tp); 1783 return (0); 1784 case TIOCSTI: 1785 if ((fflag & FREAD) == 0 && priv_check(td, PRIV_TTY_STI)) 1786 return (EPERM); 1787 if (!tty_is_ctty(tp, td->td_proc) && 1788 priv_check(td, PRIV_TTY_STI)) 1789 return (EACCES); 1790 ttydisc_rint(tp, *(char *)data, 0); 1791 ttydisc_rint_done(tp); 1792 return (0); 1793 } 1794 1795 #ifdef COMPAT_43TTY 1796 return tty_ioctl_compat(tp, cmd, data, fflag, td); 1797 #else /* !COMPAT_43TTY */ 1798 return (ENOIOCTL); 1799 #endif /* COMPAT_43TTY */ 1800 } 1801 1802 int 1803 tty_ioctl(struct tty *tp, u_long cmd, void *data, int fflag, struct thread *td) 1804 { 1805 int error; 1806 1807 tty_lock_assert(tp, MA_OWNED); 1808 1809 if (tty_gone(tp)) 1810 return (ENXIO); 1811 1812 error = ttydevsw_ioctl(tp, cmd, data, td); 1813 if (error == ENOIOCTL) 1814 error = tty_generic_ioctl(tp, cmd, data, fflag, td); 1815 1816 return (error); 1817 } 1818 1819 dev_t 1820 tty_udev(struct tty *tp) 1821 { 1822 if (tp->t_dev) 1823 return dev2udev(tp->t_dev); 1824 else 1825 return NODEV; 1826 } 1827 1828 int 1829 tty_checkoutq(struct tty *tp) 1830 { 1831 1832 /* 256 bytes should be enough to print a log message. */ 1833 return (ttyoutq_bytesleft(&tp->t_outq) >= 256); 1834 } 1835 1836 void 1837 tty_hiwat_in_block(struct tty *tp) 1838 { 1839 1840 if ((tp->t_flags & TF_HIWAT_IN) == 0 && 1841 tp->t_termios.c_iflag & IXOFF && 1842 tp->t_termios.c_cc[VSTOP] != _POSIX_VDISABLE) { 1843 /* 1844 * Input flow control. Only enter the high watermark when we 1845 * can successfully store the VSTOP character. 1846 */ 1847 if (ttyoutq_write_nofrag(&tp->t_outq, 1848 &tp->t_termios.c_cc[VSTOP], 1) == 0) 1849 tp->t_flags |= TF_HIWAT_IN; 1850 } else { 1851 /* No input flow control. */ 1852 tp->t_flags |= TF_HIWAT_IN; 1853 } 1854 } 1855 1856 void 1857 tty_hiwat_in_unblock(struct tty *tp) 1858 { 1859 1860 if (tp->t_flags & TF_HIWAT_IN && 1861 tp->t_termios.c_iflag & IXOFF && 1862 tp->t_termios.c_cc[VSTART] != _POSIX_VDISABLE) { 1863 /* 1864 * Input flow control. Only leave the high watermark when we 1865 * can successfully store the VSTART character. 1866 */ 1867 if (ttyoutq_write_nofrag(&tp->t_outq, 1868 &tp->t_termios.c_cc[VSTART], 1) == 0) 1869 tp->t_flags &= ~TF_HIWAT_IN; 1870 } else { 1871 /* No input flow control. */ 1872 tp->t_flags &= ~TF_HIWAT_IN; 1873 } 1874 1875 if (!tty_gone(tp)) 1876 ttydevsw_inwakeup(tp); 1877 } 1878 1879 /* 1880 * TTY hooks interface. 1881 */ 1882 1883 static int 1884 ttyhook_defrint(struct tty *tp, char c, int flags) 1885 { 1886 1887 if (ttyhook_rint_bypass(tp, &c, 1) != 1) 1888 return (-1); 1889 1890 return (0); 1891 } 1892 1893 int 1894 ttyhook_register(struct tty **rtp, struct proc *p, int fd, 1895 struct ttyhook *th, void *softc) 1896 { 1897 struct tty *tp; 1898 struct file *fp; 1899 struct cdev *dev; 1900 struct cdevsw *cdp; 1901 struct filedesc *fdp; 1902 cap_rights_t rights; 1903 int error, ref; 1904 1905 /* Validate the file descriptor. */ 1906 fdp = p->p_fd; 1907 error = fget_unlocked(fdp, fd, cap_rights_init(&rights, CAP_TTYHOOK), 1908 &fp, NULL); 1909 if (error != 0) 1910 return (error); 1911 if (fp->f_ops == &badfileops) { 1912 error = EBADF; 1913 goto done1; 1914 } 1915 1916 /* 1917 * Make sure the vnode is bound to a character device. 1918 * Unlocked check for the vnode type is ok there, because we 1919 * only shall prevent calling devvn_refthread on the file that 1920 * never has been opened over a character device. 1921 */ 1922 if (fp->f_type != DTYPE_VNODE || fp->f_vnode->v_type != VCHR) { 1923 error = EINVAL; 1924 goto done1; 1925 } 1926 1927 /* Make sure it is a TTY. */ 1928 cdp = devvn_refthread(fp->f_vnode, &dev, &ref); 1929 if (cdp == NULL) { 1930 error = ENXIO; 1931 goto done1; 1932 } 1933 if (dev != fp->f_data) { 1934 error = ENXIO; 1935 goto done2; 1936 } 1937 if (cdp != &ttydev_cdevsw) { 1938 error = ENOTTY; 1939 goto done2; 1940 } 1941 tp = dev->si_drv1; 1942 1943 /* Try to attach the hook to the TTY. */ 1944 error = EBUSY; 1945 tty_lock(tp); 1946 MPASS((tp->t_hook == NULL) == ((tp->t_flags & TF_HOOK) == 0)); 1947 if (tp->t_flags & TF_HOOK) 1948 goto done3; 1949 1950 tp->t_flags |= TF_HOOK; 1951 tp->t_hook = th; 1952 tp->t_hooksoftc = softc; 1953 *rtp = tp; 1954 error = 0; 1955 1956 /* Maybe we can switch into bypass mode now. */ 1957 ttydisc_optimize(tp); 1958 1959 /* Silently convert rint() calls to rint_bypass() when possible. */ 1960 if (!ttyhook_hashook(tp, rint) && ttyhook_hashook(tp, rint_bypass)) 1961 th->th_rint = ttyhook_defrint; 1962 1963 done3: tty_unlock(tp); 1964 done2: dev_relthread(dev, ref); 1965 done1: fdrop(fp, curthread); 1966 return (error); 1967 } 1968 1969 void 1970 ttyhook_unregister(struct tty *tp) 1971 { 1972 1973 tty_lock_assert(tp, MA_OWNED); 1974 MPASS(tp->t_flags & TF_HOOK); 1975 1976 /* Disconnect the hook. */ 1977 tp->t_flags &= ~TF_HOOK; 1978 tp->t_hook = NULL; 1979 1980 /* Maybe we need to leave bypass mode. */ 1981 ttydisc_optimize(tp); 1982 1983 /* Maybe deallocate the TTY as well. */ 1984 tty_rel_free(tp); 1985 } 1986 1987 /* 1988 * /dev/console handling. 1989 */ 1990 1991 static int 1992 ttyconsdev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 1993 { 1994 struct tty *tp; 1995 1996 /* System has no console device. */ 1997 if (dev_console_filename == NULL) 1998 return (ENXIO); 1999 2000 /* Look up corresponding TTY by device name. */ 2001 sx_slock(&tty_list_sx); 2002 TAILQ_FOREACH(tp, &tty_list, t_list) { 2003 if (strcmp(dev_console_filename, tty_devname(tp)) == 0) { 2004 dev_console->si_drv1 = tp; 2005 break; 2006 } 2007 } 2008 sx_sunlock(&tty_list_sx); 2009 2010 /* System console has no TTY associated. */ 2011 if (dev_console->si_drv1 == NULL) 2012 return (ENXIO); 2013 2014 return (ttydev_open(dev, oflags, devtype, td)); 2015 } 2016 2017 static int 2018 ttyconsdev_write(struct cdev *dev, struct uio *uio, int ioflag) 2019 { 2020 2021 log_console(uio); 2022 2023 return (ttydev_write(dev, uio, ioflag)); 2024 } 2025 2026 /* 2027 * /dev/console is a little different than normal TTY's. When opened, 2028 * it determines which TTY to use. When data gets written to it, it 2029 * will be logged in the kernel message buffer. 2030 */ 2031 static struct cdevsw ttyconsdev_cdevsw = { 2032 .d_version = D_VERSION, 2033 .d_open = ttyconsdev_open, 2034 .d_close = ttydev_close, 2035 .d_read = ttydev_read, 2036 .d_write = ttyconsdev_write, 2037 .d_ioctl = ttydev_ioctl, 2038 .d_kqfilter = ttydev_kqfilter, 2039 .d_poll = ttydev_poll, 2040 .d_mmap = ttydev_mmap, 2041 .d_name = "ttyconsdev", 2042 .d_flags = D_TTY, 2043 }; 2044 2045 static void 2046 ttyconsdev_init(void *unused) 2047 { 2048 2049 dev_console = make_dev_credf(MAKEDEV_ETERNAL, &ttyconsdev_cdevsw, 0, 2050 NULL, UID_ROOT, GID_WHEEL, 0600, "console"); 2051 } 2052 2053 SYSINIT(tty, SI_SUB_DRIVERS, SI_ORDER_FIRST, ttyconsdev_init, NULL); 2054 2055 void 2056 ttyconsdev_select(const char *name) 2057 { 2058 2059 dev_console_filename = name; 2060 } 2061 2062 /* 2063 * Debugging routines. 2064 */ 2065 2066 #include "opt_ddb.h" 2067 #ifdef DDB 2068 #include <ddb/ddb.h> 2069 #include <ddb/db_sym.h> 2070 2071 static struct { 2072 int flag; 2073 char val; 2074 } ttystates[] = { 2075 #if 0 2076 { TF_NOPREFIX, 'N' }, 2077 #endif 2078 { TF_INITLOCK, 'I' }, 2079 { TF_CALLOUT, 'C' }, 2080 2081 /* Keep these together -> 'Oi' and 'Oo'. */ 2082 { TF_OPENED, 'O' }, 2083 { TF_OPENED_IN, 'i' }, 2084 { TF_OPENED_OUT, 'o' }, 2085 { TF_OPENED_CONS, 'c' }, 2086 2087 { TF_GONE, 'G' }, 2088 { TF_OPENCLOSE, 'B' }, 2089 { TF_ASYNC, 'Y' }, 2090 { TF_LITERAL, 'L' }, 2091 2092 /* Keep these together -> 'Hi' and 'Ho'. */ 2093 { TF_HIWAT, 'H' }, 2094 { TF_HIWAT_IN, 'i' }, 2095 { TF_HIWAT_OUT, 'o' }, 2096 2097 { TF_STOPPED, 'S' }, 2098 { TF_EXCLUDE, 'X' }, 2099 { TF_BYPASS, 'l' }, 2100 { TF_ZOMBIE, 'Z' }, 2101 { TF_HOOK, 's' }, 2102 2103 /* Keep these together -> 'bi' and 'bo'. */ 2104 { TF_BUSY, 'b' }, 2105 { TF_BUSY_IN, 'i' }, 2106 { TF_BUSY_OUT, 'o' }, 2107 2108 { 0, '\0'}, 2109 }; 2110 2111 #define TTY_FLAG_BITS \ 2112 "\20\1NOPREFIX\2INITLOCK\3CALLOUT\4OPENED_IN\5OPENED_OUT\6GONE" \ 2113 "\7OPENCLOSE\10ASYNC\11LITERAL\12HIWAT_IN\13HIWAT_OUT\14STOPPED" \ 2114 "\15EXCLUDE\16BYPASS\17ZOMBIE\20HOOK" 2115 2116 #define DB_PRINTSYM(name, addr) \ 2117 db_printf("%s " #name ": ", sep); \ 2118 db_printsym((db_addr_t) addr, DB_STGY_ANY); \ 2119 db_printf("\n"); 2120 2121 static void 2122 _db_show_devsw(const char *sep, const struct ttydevsw *tsw) 2123 { 2124 db_printf("%sdevsw: ", sep); 2125 db_printsym((db_addr_t)tsw, DB_STGY_ANY); 2126 db_printf(" (%p)\n", tsw); 2127 DB_PRINTSYM(open, tsw->tsw_open); 2128 DB_PRINTSYM(close, tsw->tsw_close); 2129 DB_PRINTSYM(outwakeup, tsw->tsw_outwakeup); 2130 DB_PRINTSYM(inwakeup, tsw->tsw_inwakeup); 2131 DB_PRINTSYM(ioctl, tsw->tsw_ioctl); 2132 DB_PRINTSYM(param, tsw->tsw_param); 2133 DB_PRINTSYM(modem, tsw->tsw_modem); 2134 DB_PRINTSYM(mmap, tsw->tsw_mmap); 2135 DB_PRINTSYM(pktnotify, tsw->tsw_pktnotify); 2136 DB_PRINTSYM(free, tsw->tsw_free); 2137 } 2138 static void 2139 _db_show_hooks(const char *sep, const struct ttyhook *th) 2140 { 2141 db_printf("%shook: ", sep); 2142 db_printsym((db_addr_t)th, DB_STGY_ANY); 2143 db_printf(" (%p)\n", th); 2144 if (th == NULL) 2145 return; 2146 DB_PRINTSYM(rint, th->th_rint); 2147 DB_PRINTSYM(rint_bypass, th->th_rint_bypass); 2148 DB_PRINTSYM(rint_done, th->th_rint_done); 2149 DB_PRINTSYM(rint_poll, th->th_rint_poll); 2150 DB_PRINTSYM(getc_inject, th->th_getc_inject); 2151 DB_PRINTSYM(getc_capture, th->th_getc_capture); 2152 DB_PRINTSYM(getc_poll, th->th_getc_poll); 2153 DB_PRINTSYM(close, th->th_close); 2154 } 2155 2156 static void 2157 _db_show_termios(const char *name, const struct termios *t) 2158 { 2159 2160 db_printf("%s: iflag 0x%x oflag 0x%x cflag 0x%x " 2161 "lflag 0x%x ispeed %u ospeed %u\n", name, 2162 t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag, 2163 t->c_ispeed, t->c_ospeed); 2164 } 2165 2166 /* DDB command to show TTY statistics. */ 2167 DB_SHOW_COMMAND(tty, db_show_tty) 2168 { 2169 struct tty *tp; 2170 2171 if (!have_addr) { 2172 db_printf("usage: show tty <addr>\n"); 2173 return; 2174 } 2175 tp = (struct tty *)addr; 2176 2177 db_printf("0x%p: %s\n", tp, tty_devname(tp)); 2178 db_printf("\tmtx: %p\n", tp->t_mtx); 2179 db_printf("\tflags: %b\n", tp->t_flags, TTY_FLAG_BITS); 2180 db_printf("\trevokecnt: %u\n", tp->t_revokecnt); 2181 2182 /* Buffering mechanisms. */ 2183 db_printf("\tinq: %p begin %u linestart %u reprint %u end %u " 2184 "nblocks %u quota %u\n", &tp->t_inq, tp->t_inq.ti_begin, 2185 tp->t_inq.ti_linestart, tp->t_inq.ti_reprint, tp->t_inq.ti_end, 2186 tp->t_inq.ti_nblocks, tp->t_inq.ti_quota); 2187 db_printf("\toutq: %p begin %u end %u nblocks %u quota %u\n", 2188 &tp->t_outq, tp->t_outq.to_begin, tp->t_outq.to_end, 2189 tp->t_outq.to_nblocks, tp->t_outq.to_quota); 2190 db_printf("\tinlow: %zu\n", tp->t_inlow); 2191 db_printf("\toutlow: %zu\n", tp->t_outlow); 2192 _db_show_termios("\ttermios", &tp->t_termios); 2193 db_printf("\twinsize: row %u col %u xpixel %u ypixel %u\n", 2194 tp->t_winsize.ws_row, tp->t_winsize.ws_col, 2195 tp->t_winsize.ws_xpixel, tp->t_winsize.ws_ypixel); 2196 db_printf("\tcolumn: %u\n", tp->t_column); 2197 db_printf("\twritepos: %u\n", tp->t_writepos); 2198 db_printf("\tcompatflags: 0x%x\n", tp->t_compatflags); 2199 2200 /* Init/lock-state devices. */ 2201 _db_show_termios("\ttermios_init_in", &tp->t_termios_init_in); 2202 _db_show_termios("\ttermios_init_out", &tp->t_termios_init_out); 2203 _db_show_termios("\ttermios_lock_in", &tp->t_termios_lock_in); 2204 _db_show_termios("\ttermios_lock_out", &tp->t_termios_lock_out); 2205 2206 /* Hooks */ 2207 _db_show_devsw("\t", tp->t_devsw); 2208 _db_show_hooks("\t", tp->t_hook); 2209 2210 /* Process info. */ 2211 db_printf("\tpgrp: %p gid %d jobc %d\n", tp->t_pgrp, 2212 tp->t_pgrp ? tp->t_pgrp->pg_id : 0, 2213 tp->t_pgrp ? tp->t_pgrp->pg_jobc : 0); 2214 db_printf("\tsession: %p", tp->t_session); 2215 if (tp->t_session != NULL) 2216 db_printf(" count %u leader %p tty %p sid %d login %s", 2217 tp->t_session->s_count, tp->t_session->s_leader, 2218 tp->t_session->s_ttyp, tp->t_session->s_sid, 2219 tp->t_session->s_login); 2220 db_printf("\n"); 2221 db_printf("\tsessioncnt: %u\n", tp->t_sessioncnt); 2222 db_printf("\tdevswsoftc: %p\n", tp->t_devswsoftc); 2223 db_printf("\thooksoftc: %p\n", tp->t_hooksoftc); 2224 db_printf("\tdev: %p\n", tp->t_dev); 2225 } 2226 2227 /* DDB command to list TTYs. */ 2228 DB_SHOW_ALL_COMMAND(ttys, db_show_all_ttys) 2229 { 2230 struct tty *tp; 2231 size_t isiz, osiz; 2232 int i, j; 2233 2234 /* Make the output look like `pstat -t'. */ 2235 db_printf("PTR "); 2236 #if defined(__LP64__) 2237 db_printf(" "); 2238 #endif 2239 db_printf(" LINE INQ CAN LIN LOW OUTQ USE LOW " 2240 "COL SESS PGID STATE\n"); 2241 2242 TAILQ_FOREACH(tp, &tty_list, t_list) { 2243 isiz = tp->t_inq.ti_nblocks * TTYINQ_DATASIZE; 2244 osiz = tp->t_outq.to_nblocks * TTYOUTQ_DATASIZE; 2245 2246 db_printf("%p %10s %5zu %4u %4u %4zu %5zu %4u %4zu %5u %5d %5d ", 2247 tp, 2248 tty_devname(tp), 2249 isiz, 2250 tp->t_inq.ti_linestart - tp->t_inq.ti_begin, 2251 tp->t_inq.ti_end - tp->t_inq.ti_linestart, 2252 isiz - tp->t_inlow, 2253 osiz, 2254 tp->t_outq.to_end - tp->t_outq.to_begin, 2255 osiz - tp->t_outlow, 2256 MIN(tp->t_column, 99999), 2257 tp->t_session ? tp->t_session->s_sid : 0, 2258 tp->t_pgrp ? tp->t_pgrp->pg_id : 0); 2259 2260 /* Flag bits. */ 2261 for (i = j = 0; ttystates[i].flag; i++) 2262 if (tp->t_flags & ttystates[i].flag) { 2263 db_printf("%c", ttystates[i].val); 2264 j++; 2265 } 2266 if (j == 0) 2267 db_printf("-"); 2268 db_printf("\n"); 2269 } 2270 } 2271 #endif /* DDB */ 2272