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