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