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