1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 1983 Regents of the University of California. 8 * All rights reserved. The Berkeley software License Agreement 9 * specifies the terms and conditions for redistribution. 10 */ 11 12 /* 13 * PTY - Stream "pseudo-tty" device. For each "controller" side 14 * it connects to a "slave" side. 15 */ 16 17 #pragma ident "%Z%%M% %I% %E% SMI" 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/filio.h> 22 #include <sys/ioccom.h> 23 #include <sys/termios.h> 24 #include <sys/termio.h> 25 #include <sys/ttold.h> 26 #include <sys/stropts.h> 27 #include <sys/stream.h> 28 #include <sys/tty.h> 29 #include <sys/user.h> 30 #include <sys/conf.h> 31 #include <sys/file.h> 32 #include <sys/vnode.h> /* 1/0 on the vomit meter */ 33 #include <sys/proc.h> 34 #include <sys/uio.h> 35 #include <sys/errno.h> 36 #include <sys/strsubr.h> 37 #include <sys/poll.h> 38 #include <sys/sysmacros.h> 39 #include <sys/debug.h> 40 #include <sys/procset.h> 41 #include <sys/cred.h> 42 #include <sys/ptyvar.h> 43 #include <sys/suntty.h> 44 #include <sys/stat.h> 45 46 #include <sys/conf.h> 47 #include <sys/ddi.h> 48 #include <sys/sunddi.h> 49 50 extern int npty; /* number of pseudo-ttys configured in */ 51 extern struct pty *pty_softc; 52 extern struct pollhead ptcph; /* poll head for ptcpoll() use */ 53 54 int ptcopen(dev_t *, int, int, struct cred *); 55 int ptcclose(dev_t, int, int, struct cred *); 56 int ptcwrite(dev_t, struct uio *, struct cred *); 57 int ptcread(dev_t, struct uio *, struct cred *); 58 int ptcioctl(dev_t, int, intptr_t, int, struct cred *, int *); 59 int ptcpoll(dev_t, short, int, short *, struct pollhead **); 60 61 static int ptc_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 62 static int ptc_attach(dev_info_t *, ddi_attach_cmd_t); 63 static dev_info_t *ptc_dip; /* for dev-to-dip conversions */ 64 65 static void ptc_init(void), ptc_uninit(void); 66 67 static int makemsg(ssize_t count, struct uio *uiop, 68 struct pty *pty, mblk_t **mpp); 69 70 struct cb_ops ptc_cb_ops = { 71 ptcopen, /* open */ 72 ptcclose, /* close */ 73 nodev, /* strategy */ 74 nodev, /* print */ 75 nodev, /* dump */ 76 ptcread, /* read */ 77 ptcwrite, /* write */ 78 ptcioctl, /* ioctl */ 79 nodev, /* devmap */ 80 nodev, /* mmap */ 81 nodev, /* segmap */ 82 ptcpoll, /* poll */ 83 ddi_prop_op, /* prop_op */ 84 0, /* streamtab */ 85 D_NEW | D_MP /* Driver compatibility flag */ 86 }; 87 88 struct dev_ops ptc_ops = { 89 DEVO_REV, /* devo_rev */ 90 0, /* refcnt */ 91 ptc_info, /* info */ 92 nulldev, /* identify */ 93 nulldev, /* probe */ 94 ptc_attach, /* attach */ 95 nodev, /* detach */ 96 nodev, /* reset */ 97 &ptc_cb_ops, /* driver operations */ 98 (struct bus_ops *)0 /* bus operations */ 99 }; 100 101 #include <sys/types.h> 102 #include <sys/conf.h> 103 #include <sys/param.h> 104 #include <sys/systm.h> 105 #include <sys/errno.h> 106 #include <sys/modctl.h> 107 108 extern int dseekneg_flag; 109 extern struct mod_ops mod_driverops; 110 extern struct dev_ops ptc_ops; 111 112 /* 113 * Module linkage information for the kernel. 114 */ 115 116 static struct modldrv modldrv = { 117 &mod_driverops, /* Type of module. This one is a pseudo driver */ 118 "tty pseudo driver control 'ptc' %I%", 119 &ptc_ops, /* driver ops */ 120 }; 121 122 static struct modlinkage modlinkage = { 123 MODREV_1, 124 &modldrv, 125 NULL 126 }; 127 128 int 129 _init() 130 { 131 int rc; 132 133 if ((rc = mod_install(&modlinkage)) == 0) 134 ptc_init(); 135 return (rc); 136 } 137 138 139 int 140 _fini() 141 { 142 int rc; 143 144 if ((rc = mod_remove(&modlinkage)) == 0) 145 ptc_uninit(); 146 return (rc); 147 } 148 149 int 150 _info(struct modinfo *modinfop) 151 { 152 return (mod_info(&modlinkage, modinfop)); 153 } 154 155 static char *pty_banks = PTY_BANKS; 156 static char *pty_digits = PTY_DIGITS; 157 158 /* ARGSUSED */ 159 static int 160 ptc_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 161 { 162 char name[8]; 163 int pty_num; 164 char *pty_digit = pty_digits; 165 char *pty_bank = pty_banks; 166 167 for (pty_num = 0; pty_num < npty; pty_num++) { 168 (void) sprintf(name, "pty%c%c", *pty_bank, *pty_digit); 169 if (ddi_create_minor_node(devi, name, S_IFCHR, 170 pty_num, DDI_PSEUDO, NULL) == DDI_FAILURE) { 171 ddi_remove_minor_node(devi, NULL); 172 return (-1); 173 } 174 if (*(++pty_digit) == '\0') { 175 pty_digit = pty_digits; 176 if (*(++pty_bank) == '\0') 177 break; 178 } 179 } 180 ptc_dip = devi; 181 return (DDI_SUCCESS); 182 } 183 184 /* ARGSUSED */ 185 static int 186 ptc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 187 { 188 int error; 189 190 switch (infocmd) { 191 case DDI_INFO_DEVT2DEVINFO: 192 if (ptc_dip == NULL) { 193 *result = (void *)NULL; 194 error = DDI_FAILURE; 195 } else { 196 *result = (void *) ptc_dip; 197 error = DDI_SUCCESS; 198 } 199 break; 200 case DDI_INFO_DEVT2INSTANCE: 201 *result = (void *)0; 202 error = DDI_SUCCESS; 203 break; 204 default: 205 error = DDI_FAILURE; 206 } 207 return (error); 208 } 209 210 static void 211 ptc_init(void) 212 { 213 minor_t dev; 214 215 for (dev = 0; dev < npty; dev++) { 216 cv_init(&pty_softc[dev].pt_cv_flags, NULL, CV_DEFAULT, NULL); 217 cv_init(&pty_softc[dev].pt_cv_readq, NULL, CV_DEFAULT, NULL); 218 cv_init(&pty_softc[dev].pt_cv_writeq, NULL, CV_DEFAULT, NULL); 219 mutex_init(&pty_softc[dev].ptc_lock, NULL, MUTEX_DEFAULT, NULL); 220 } 221 } 222 223 static void 224 ptc_uninit(void) 225 { 226 minor_t dev; 227 228 for (dev = 0; dev < npty; dev++) { 229 cv_destroy(&pty_softc[dev].pt_cv_flags); 230 cv_destroy(&pty_softc[dev].pt_cv_readq); 231 cv_destroy(&pty_softc[dev].pt_cv_writeq); 232 mutex_destroy(&pty_softc[dev].ptc_lock); 233 } 234 } 235 236 /* 237 * Controller side. This is not, alas, a streams device; there are too 238 * many old features that we must support and that don't work well 239 * with streams. 240 */ 241 242 /*ARGSUSED*/ 243 int 244 ptcopen(dev_t *devp, int flag, int otyp, struct cred *cred) 245 { 246 dev_t dev = *devp; 247 struct pty *pty; 248 queue_t *q; 249 250 if (getminor(dev) >= npty) { 251 return (ENXIO); 252 } 253 pty = &pty_softc[getminor(dev)]; 254 mutex_enter(&pty->ptc_lock); 255 if (pty->pt_flags & PF_CARR_ON) { 256 mutex_exit(&pty->ptc_lock); 257 return (EIO); /* controller is exclusive use */ 258 /* XXX - should be EBUSY! */ 259 } 260 if (pty->pt_flags & PF_WOPEN) { 261 pty->pt_flags &= ~PF_WOPEN; 262 cv_broadcast(&pty->pt_cv_flags); 263 } 264 265 if ((q = pty->pt_ttycommon.t_readq) != NULL) { 266 /* 267 * Send an un-hangup to the slave, since "carrier" is 268 * coming back up. Make sure we're doing canonicalization. 269 */ 270 (void) putctl(q, M_UNHANGUP); 271 (void) putctl1(q, M_CTL, MC_DOCANON); 272 } 273 pty->pt_flags |= PF_CARR_ON; 274 pty->pt_send = 0; 275 pty->pt_ucntl = 0; 276 277 mutex_exit(&pty->ptc_lock); 278 return (0); 279 } 280 281 /*ARGSUSED1*/ 282 int 283 ptcclose(dev_t dev, int flag, int otyp, struct cred *cred) 284 { 285 struct pty *pty; 286 mblk_t *bp; 287 queue_t *q; 288 289 pty = &pty_softc[getminor(dev)]; 290 291 mutex_enter(&pty->ptc_lock); 292 if ((q = pty->pt_ttycommon.t_readq) != NULL) { 293 /* 294 * Send a hangup to the slave, since "carrier" is dropping. 295 */ 296 (void) putctl(q, M_HANGUP); 297 } 298 299 /* 300 * Clear out all the controller-side state. This also 301 * clears PF_CARR_ON, which is correct because the 302 * "carrier" is dropping since the controller process 303 * is going away. 304 */ 305 pty->pt_flags &= (PF_WOPEN|PF_STOPPED|PF_NOSTOP); 306 while ((bp = pty->pt_stuffqfirst) != NULL) { 307 if ((pty->pt_stuffqfirst = bp->b_next) == NULL) 308 pty->pt_stuffqlast = NULL; 309 else 310 pty->pt_stuffqfirst->b_prev = NULL; 311 pty->pt_stuffqlen--; 312 bp->b_next = bp->b_prev = NULL; 313 freemsg(bp); 314 } 315 mutex_exit(&pty->ptc_lock); 316 return (0); 317 } 318 319 int 320 ptcread(dev_t dev, struct uio *uio, struct cred *cred) 321 { 322 struct pty *pty = &pty_softc[getminor(dev)]; 323 mblk_t *bp, *nbp; 324 queue_t *q; 325 unsigned char tmp; 326 ssize_t cc; 327 int error; 328 off_t off; 329 330 #ifdef lint 331 cred = cred; 332 #endif 333 334 off = uio->uio_offset; 335 336 mutex_enter(&pty->ptc_lock); 337 338 for (;;) { 339 while (pty->pt_flags & PF_READ) { 340 pty->pt_flags |= PF_WREAD; 341 cv_wait(&pty->pt_cv_flags, &pty->ptc_lock); 342 } 343 pty->pt_flags |= PF_READ; 344 345 /* 346 * If there's a TIOCPKT packet waiting, pass it back. 347 */ 348 while (pty->pt_flags&(PF_PKT|PF_UCNTL) && pty->pt_send) { 349 tmp = pty->pt_send; 350 pty->pt_send = 0; 351 mutex_exit(&pty->ptc_lock); 352 error = ureadc((int)tmp, uio); 353 uio->uio_offset = off; 354 mutex_enter(&pty->ptc_lock); 355 if (error) { 356 pty->pt_send |= tmp; 357 goto out; 358 } 359 if (pty->pt_send == 0) 360 goto out; 361 } 362 363 /* 364 * If there's a user-control packet waiting, pass the 365 * "ioctl" code back. 366 */ 367 while ((pty->pt_flags & (PF_UCNTL|PF_43UCNTL)) && 368 pty->pt_ucntl) { 369 tmp = pty->pt_ucntl; 370 pty->pt_ucntl = 0; 371 mutex_exit(&pty->ptc_lock); 372 error = ureadc((int)tmp, uio); 373 uio->uio_offset = off; 374 mutex_enter(&pty->ptc_lock); 375 if (error) { 376 if (pty->pt_ucntl == 0) 377 pty->pt_ucntl = tmp; 378 goto out; 379 } 380 if (pty->pt_ucntl == 0) 381 goto out; 382 } 383 384 /* 385 * If there's any data waiting, pass it back. 386 */ 387 if ((q = pty->pt_ttycommon.t_writeq) != NULL && 388 q->q_first != NULL && 389 !(pty->pt_flags & PF_STOPPED)) { 390 if (pty->pt_flags & (PF_PKT|PF_UCNTL|PF_43UCNTL)) { 391 /* 392 * We're about to begin a move in packet or 393 * user-control mode; precede the data with a 394 * data header. 395 */ 396 mutex_exit(&pty->ptc_lock); 397 error = ureadc(TIOCPKT_DATA, uio); 398 uio->uio_offset = off; 399 mutex_enter(&pty->ptc_lock); 400 if (error != 0) 401 goto out; 402 if ((q = pty->pt_ttycommon.t_writeq) == NULL) 403 goto out; 404 } 405 if ((bp = getq(q)) == NULL) 406 goto out; 407 while (uio->uio_resid > 0) { 408 while ((cc = bp->b_wptr - bp->b_rptr) == 0) { 409 nbp = bp->b_cont; 410 freeb(bp); 411 if ((bp = nbp) == NULL) { 412 if ((q == NULL) || 413 (bp = getq(q)) == NULL) 414 goto out; 415 } 416 } 417 cc = MIN(cc, uio->uio_resid); 418 mutex_exit(&pty->ptc_lock); 419 error = uiomove((caddr_t)bp->b_rptr, 420 cc, UIO_READ, uio); 421 uio->uio_offset = off; 422 mutex_enter(&pty->ptc_lock); 423 if (error != 0) { 424 freemsg(bp); 425 goto out; 426 } 427 q = pty->pt_ttycommon.t_writeq; 428 bp->b_rptr += cc; 429 } 430 /* 431 * Strip off zero-length blocks from the front of 432 * what we're putting back on the queue. 433 */ 434 while ((bp->b_wptr - bp->b_rptr) == 0) { 435 nbp = bp->b_cont; 436 freeb(bp); 437 if ((bp = nbp) == NULL) 438 goto out; /* nothing left */ 439 } 440 if (q != NULL) 441 (void) putbq(q, bp); 442 else 443 freemsg(bp); 444 goto out; 445 } 446 447 /* 448 * If there's any TIOCSTI-stuffed characters, pass 449 * them back. (They currently arrive after all output; 450 * is this correct?) 451 */ 452 if (pty->pt_flags&PF_UCNTL && pty->pt_stuffqfirst != NULL) { 453 mutex_exit(&pty->ptc_lock); 454 error = ureadc(TIOCSTI&0xff, uio); 455 mutex_enter(&pty->ptc_lock); 456 while (error == 0 && 457 (bp = pty->pt_stuffqfirst) != NULL && 458 uio->uio_resid > 0) { 459 pty->pt_stuffqlen--; 460 if ((pty->pt_stuffqfirst = bp->b_next) == NULL) 461 pty->pt_stuffqlast = NULL; 462 else 463 pty->pt_stuffqfirst->b_prev = NULL; 464 mutex_exit(&pty->ptc_lock); 465 error = ureadc((int)*bp->b_rptr, uio); 466 bp->b_next = bp->b_prev = NULL; 467 freemsg(bp); 468 mutex_enter(&pty->ptc_lock); 469 } 470 uio->uio_offset = off; 471 goto out; 472 } 473 474 /* 475 * There's no data available. 476 * We want to block until the slave is open, and there's 477 * something to read; but if we lost the slave or we're NBIO, 478 * then return the appropriate error instead. POSIX-style 479 * non-block has top billing and gives -1 with errno = EAGAIN, 480 * BSD-style comes next and gives -1 with errno = EWOULDBLOCK, 481 * SVID-style comes last and gives 0. 482 */ 483 if (pty->pt_flags & PF_SLAVEGONE) { 484 error = EIO; 485 goto out; 486 } 487 if (uio->uio_fmode & FNONBLOCK) { 488 error = EAGAIN; 489 goto out; 490 } 491 if (pty->pt_flags & PF_NBIO) { 492 error = EWOULDBLOCK; 493 goto out; 494 } 495 if (uio->uio_fmode & FNDELAY) 496 goto out; 497 498 if (pty->pt_flags & PF_WREAD) 499 cv_broadcast(&pty->pt_cv_flags); 500 501 pty->pt_flags &= ~(PF_READ | PF_WREAD); 502 503 504 if (!cv_wait_sig(&pty->pt_cv_writeq, &pty->ptc_lock)) { 505 mutex_exit(&pty->ptc_lock); 506 return (EINTR); 507 } 508 } 509 510 out: 511 if (pty->pt_flags & PF_WREAD) 512 cv_broadcast(&pty->pt_cv_flags); 513 514 pty->pt_flags &= ~(PF_READ | PF_WREAD); 515 516 mutex_exit(&pty->ptc_lock); 517 return (error); 518 } 519 520 int 521 ptcwrite(dev_t dev, struct uio *uio, struct cred *cred) 522 { 523 struct pty *pty = &pty_softc[getminor(dev)]; 524 queue_t *q; 525 int written; 526 mblk_t *mp; 527 int fmode = 0; 528 int error = 0; 529 530 off_t off; 531 off = uio->uio_offset; 532 533 #ifdef lint 534 cred = cred; 535 #endif 536 537 538 mutex_enter(&pty->ptc_lock); 539 540 again: 541 while (pty->pt_flags & PF_WRITE) { 542 pty->pt_flags |= PF_WWRITE; 543 cv_wait(&pty->pt_cv_flags, &pty->ptc_lock); 544 } 545 546 pty->pt_flags |= PF_WRITE; 547 548 if ((q = pty->pt_ttycommon.t_readq) == NULL) { 549 550 /* 551 * Wait for slave to open. 552 */ 553 if (pty->pt_flags & PF_SLAVEGONE) { 554 error = EIO; 555 goto out; 556 } 557 if (uio->uio_fmode & FNONBLOCK) { 558 error = EAGAIN; 559 goto out; 560 } 561 if (pty->pt_flags & PF_NBIO) { 562 error = EWOULDBLOCK; 563 goto out; 564 } 565 if (uio->uio_fmode & FNDELAY) 566 goto out; 567 568 if (pty->pt_flags & PF_WWRITE) 569 cv_broadcast(&pty->pt_cv_flags); 570 571 pty->pt_flags &= ~(PF_WRITE | PF_WWRITE); 572 573 if (!cv_wait_sig(&pty->pt_cv_readq, &pty->ptc_lock)) { 574 mutex_exit(&pty->ptc_lock); 575 return (EINTR); 576 } 577 578 goto again; 579 } 580 581 /* 582 * If in remote mode, even zero-length writes generate messages. 583 */ 584 written = 0; 585 if ((pty->pt_flags & PF_REMOTE) || uio->uio_resid > 0) { 586 do { 587 while (!canput(q)) { 588 /* 589 * Wait for slave's read queue to unclog. 590 */ 591 if (pty->pt_flags & PF_SLAVEGONE) { 592 error = EIO; 593 goto out; 594 } 595 if (uio->uio_fmode & FNONBLOCK) { 596 if (!written) 597 error = EAGAIN; 598 goto out; 599 } 600 if (pty->pt_flags & PF_NBIO) { 601 if (!written) 602 error = EWOULDBLOCK; 603 goto out; 604 } 605 if (uio->uio_fmode & FNDELAY) 606 goto out; 607 608 if (pty->pt_flags & PF_WWRITE) 609 cv_broadcast(&pty->pt_cv_flags); 610 611 pty->pt_flags &= ~(PF_WRITE | PF_WWRITE); 612 613 if (!cv_wait_sig(&pty->pt_cv_readq, 614 &pty->ptc_lock)) { 615 mutex_exit(&pty->ptc_lock); 616 return (EINTR); 617 } 618 619 while (pty->pt_flags & PF_WRITE) { 620 pty->pt_flags |= PF_WWRITE; 621 cv_wait(&pty->pt_cv_flags, 622 &pty->ptc_lock); 623 } 624 625 pty->pt_flags |= PF_WRITE; 626 } 627 628 if ((pty->pt_flags & PF_NBIO) && 629 !(uio->uio_fmode & FNONBLOCK)) { 630 fmode = uio->uio_fmode; 631 uio->uio_fmode |= FNONBLOCK; 632 } 633 634 error = makemsg(uio->uio_resid, uio, pty, &mp); 635 uio->uio_offset = off; 636 if (fmode) 637 uio->uio_fmode = fmode; 638 if (error != 0) { 639 if (error != EAGAIN && error != EWOULDBLOCK) 640 goto out; 641 if (uio->uio_fmode & FNONBLOCK) { 642 if (!written) 643 error = EAGAIN; 644 goto out; 645 } 646 if (pty->pt_flags & PF_NBIO) { 647 if (!written) 648 error = EWOULDBLOCK; 649 goto out; 650 } 651 if (uio->uio_fmode & FNDELAY) 652 goto out; 653 cmn_err(CE_PANIC, 654 "ptcwrite: non null return from" 655 " makemsg"); 656 } 657 658 /* 659 * Check again for safety; since "uiomove" can take a 660 * page fault, there's no guarantee that "pt_flags" 661 * didn't change while it was happening. 662 */ 663 if ((q = pty->pt_ttycommon.t_readq) == NULL) { 664 if (mp) 665 freemsg(mp); 666 error = EIO; 667 goto out; 668 } 669 if (mp) 670 (void) putq(q, mp); 671 written = 1; 672 } while (uio->uio_resid > 0); 673 } 674 out: 675 if (pty->pt_flags & PF_WWRITE) 676 cv_broadcast(&pty->pt_cv_flags); 677 678 pty->pt_flags &= ~(PF_WRITE | PF_WWRITE); 679 680 mutex_exit(&pty->ptc_lock); 681 return (error); 682 } 683 684 #define copy_in(data, d_arg) \ 685 if (copyin((caddr_t)data, &d_arg, sizeof (int)) != 0) \ 686 return (EFAULT) 687 688 #define copy_out(d_arg, data) \ 689 if (copyout(&d_arg, (caddr_t)data, sizeof (int)) != 0) \ 690 return (EFAULT) 691 692 int 693 ptcioctl(dev_t dev, int cmd, intptr_t data, int flag, struct cred *cred, 694 int *rvalp) 695 { 696 struct pty *pty = &pty_softc[getminor(dev)]; 697 queue_t *q; 698 struct ttysize tty_arg; 699 struct winsize win_arg; 700 int d_arg; 701 int err; 702 703 switch (cmd) { 704 705 case TIOCPKT: 706 copy_in(data, d_arg); 707 mutex_enter(&pty->ptc_lock); 708 if (d_arg) { 709 if (pty->pt_flags & (PF_UCNTL|PF_43UCNTL)) { 710 mutex_exit(&pty->ptc_lock); 711 return (EINVAL); 712 } 713 pty->pt_flags |= PF_PKT; 714 } else 715 pty->pt_flags &= ~PF_PKT; 716 mutex_exit(&pty->ptc_lock); 717 break; 718 719 case TIOCUCNTL: 720 copy_in(data, d_arg); 721 mutex_enter(&pty->ptc_lock); 722 if (d_arg) { 723 if (pty->pt_flags & (PF_PKT|PF_UCNTL)) { 724 mutex_exit(&pty->ptc_lock); 725 return (EINVAL); 726 } 727 pty->pt_flags |= PF_43UCNTL; 728 } else 729 pty->pt_flags &= ~PF_43UCNTL; 730 mutex_exit(&pty->ptc_lock); 731 break; 732 733 case TIOCTCNTL: 734 copy_in(data, d_arg); 735 mutex_enter(&pty->ptc_lock); 736 if (d_arg) { 737 if (pty->pt_flags & PF_PKT) { 738 mutex_exit(&pty->ptc_lock); 739 return (EINVAL); 740 } 741 pty->pt_flags |= PF_UCNTL; 742 } else 743 pty->pt_flags &= ~PF_UCNTL; 744 mutex_exit(&pty->ptc_lock); 745 break; 746 747 case TIOCREMOTE: 748 copy_in(data, d_arg); 749 mutex_enter(&pty->ptc_lock); 750 if (d_arg) { 751 if ((q = pty->pt_ttycommon.t_readq) != NULL) 752 (void) putctl1(q, M_CTL, MC_NOCANON); 753 pty->pt_flags |= PF_REMOTE; 754 } else { 755 if ((q = pty->pt_ttycommon.t_readq) != NULL) 756 (void) putctl1(q, M_CTL, MC_DOCANON); 757 pty->pt_flags &= ~PF_REMOTE; 758 } 759 mutex_exit(&pty->ptc_lock); 760 break; 761 762 case TIOCSIGNAL: 763 /* 764 * Blast a M_PCSIG message up the slave stream; the 765 * signal number is the argument to the "ioctl". 766 */ 767 copy_in(data, d_arg); 768 mutex_enter(&pty->ptc_lock); 769 if ((q = pty->pt_ttycommon.t_readq) != NULL) 770 (void) putctl1(q, M_PCSIG, (int)d_arg); 771 mutex_exit(&pty->ptc_lock); 772 break; 773 774 case FIONBIO: 775 copy_in(data, d_arg); 776 mutex_enter(&pty->ptc_lock); 777 if (d_arg) 778 pty->pt_flags |= PF_NBIO; 779 else 780 pty->pt_flags &= ~PF_NBIO; 781 mutex_exit(&pty->ptc_lock); 782 break; 783 784 case FIOASYNC: 785 copy_in(data, d_arg); 786 mutex_enter(&pty->ptc_lock); 787 if (d_arg) 788 pty->pt_flags |= PF_ASYNC; 789 else 790 pty->pt_flags &= ~PF_ASYNC; 791 mutex_exit(&pty->ptc_lock); 792 break; 793 794 /* 795 * These, at least, can work on the controller-side process 796 * group. 797 */ 798 case FIOGETOWN: 799 mutex_enter(&pty->ptc_lock); 800 d_arg = -pty->pt_pgrp; 801 mutex_exit(&pty->ptc_lock); 802 copy_out(d_arg, data); 803 break; 804 805 case FIOSETOWN: 806 copy_in(data, d_arg); 807 mutex_enter(&pty->ptc_lock); 808 pty->pt_pgrp = (short)(-d_arg); 809 mutex_exit(&pty->ptc_lock); 810 break; 811 812 case FIONREAD: { 813 /* 814 * Return the total number of bytes of data in all messages 815 * in slave write queue, which is master read queue, unless a 816 * special message would be read. 817 */ 818 mblk_t *mp; 819 size_t count = 0; 820 821 mutex_enter(&pty->ptc_lock); 822 if (pty->pt_flags&(PF_PKT|PF_UCNTL) && pty->pt_send) 823 count = 1; /* will return 1 byte */ 824 else if ((pty->pt_flags & (PF_UCNTL|PF_43UCNTL)) && 825 pty->pt_ucntl) 826 count = 1; /* will return 1 byte */ 827 else if ((q = pty->pt_ttycommon.t_writeq) != NULL && 828 q->q_first != NULL && !(pty->pt_flags & PF_STOPPED)) { 829 /* 830 * Will return whatever data is queued up. 831 */ 832 for (mp = q->q_first; mp != NULL; mp = mp->b_next) 833 count += msgdsize(mp); 834 } else if ((pty->pt_flags & PF_UCNTL) && 835 pty->pt_stuffqfirst != NULL) { 836 /* 837 * Will return STI'ed data. 838 */ 839 count = pty->pt_stuffqlen + 1; 840 } 841 842 /* 843 * Under LP64 we could have more than INT_MAX bytes to report, 844 * but the interface is defined in terms of int, so we cap it. 845 */ 846 d_arg = MIN(count, INT_MAX); 847 mutex_exit(&pty->ptc_lock); 848 copy_out(d_arg, data); 849 break; 850 } 851 852 case TIOCSWINSZ: 853 /* 854 * Unfortunately, TIOCSWINSZ and the old TIOCSSIZE "ioctl"s 855 * share the same code. If the upper 16 bits of the number 856 * of lines is non-zero, it was probably a TIOCSWINSZ, 857 * with both "ws_row" and "ws_col" non-zero. 858 */ 859 if (copyin((caddr_t)data, 860 &tty_arg, sizeof (struct ttysize)) != 0) 861 return (EFAULT); 862 863 if ((tty_arg.ts_lines & 0xffff0000) != 0) { 864 /* 865 * It's a TIOCSWINSZ. 866 */ 867 win_arg = *(struct winsize *)&tty_arg; 868 869 mutex_enter(&pty->ptc_lock); 870 /* 871 * If the window size changed, send a SIGWINCH. 872 */ 873 if (bcmp(&pty->pt_ttycommon.t_size, 874 &win_arg, sizeof (struct winsize))) { 875 pty->pt_ttycommon.t_size = win_arg; 876 if ((q = pty->pt_ttycommon.t_readq) != NULL) 877 (void) putctl1(q, M_PCSIG, SIGWINCH); 878 } 879 mutex_exit(&pty->ptc_lock); 880 break; 881 } 882 /* FALLTHROUGH */ 883 884 case TIOCSSIZE: 885 if (copyin((caddr_t)data, 886 &tty_arg, sizeof (struct ttysize)) != 0) 887 return (EFAULT); 888 mutex_enter(&pty->ptc_lock); 889 pty->pt_ttycommon.t_size.ws_row = (ushort_t)tty_arg.ts_lines; 890 pty->pt_ttycommon.t_size.ws_col = (ushort_t)tty_arg.ts_cols; 891 pty->pt_ttycommon.t_size.ws_xpixel = 0; 892 pty->pt_ttycommon.t_size.ws_ypixel = 0; 893 mutex_exit(&pty->ptc_lock); 894 break; 895 896 case TIOCGWINSZ: 897 mutex_enter(&pty->ptc_lock); 898 win_arg = pty->pt_ttycommon.t_size; 899 mutex_exit(&pty->ptc_lock); 900 if (copyout(&win_arg, (caddr_t)data, 901 sizeof (struct winsize)) != 0) 902 return (EFAULT); 903 break; 904 905 case TIOCGSIZE: 906 mutex_enter(&pty->ptc_lock); 907 tty_arg.ts_lines = pty->pt_ttycommon.t_size.ws_row; 908 tty_arg.ts_cols = pty->pt_ttycommon.t_size.ws_col; 909 mutex_exit(&pty->ptc_lock); 910 if (copyout(&tty_arg, (caddr_t)data, 911 sizeof (struct ttysize)) != 0) 912 return (EFAULT); 913 break; 914 915 /* 916 * XXX These should not be here. The only reason why an 917 * "ioctl" on the controller side should get the 918 * slave side's process group is so that the process on 919 * the controller side can send a signal to the slave 920 * side's process group; however, this is better done 921 * with TIOCSIGNAL, both because it doesn't require us 922 * to know about the slave side's process group and because 923 * the controller side process may not have permission to 924 * send that signal to the entire process group. 925 * 926 * However, since vanilla 4BSD doesn't provide TIOCSIGNAL, 927 * we can't just get rid of them. 928 */ 929 case TIOCGPGRP: 930 case TIOCSPGRP: 931 /* 932 * This is amazingly disgusting, but the stupid semantics of 933 * 4BSD pseudo-ttys makes us do it. If we do one of these guys 934 * on the controller side, it really applies to the slave-side 935 * stream. It should NEVER have been possible to do ANY sort 936 * of tty operations on the controller side, but it's too late 937 * to fix that now. However, we won't waste our time implementing 938 * anything that the original pseudo-tty driver didn't handle. 939 */ 940 case TIOCGETP: 941 case TIOCSETP: 942 case TIOCSETN: 943 case TIOCGETC: 944 case TIOCSETC: 945 case TIOCGLTC: 946 case TIOCSLTC: 947 case TIOCLGET: 948 case TIOCLSET: 949 case TIOCLBIS: 950 case TIOCLBIC: 951 mutex_enter(&pty->ptc_lock); 952 if (pty->pt_vnode == NULL) { 953 mutex_exit(&pty->ptc_lock); 954 return (EIO); 955 } 956 pty->pt_flags |= PF_IOCTL; 957 mutex_exit(&pty->ptc_lock); 958 err = strioctl(pty->pt_vnode, cmd, data, flag, 959 U_TO_K, cred, rvalp); 960 mutex_enter(&pty->ptc_lock); 961 if (pty->pt_flags & PF_WAIT) 962 cv_signal(&pty->pt_cv_flags); 963 pty->pt_flags &= ~(PF_IOCTL|PF_WAIT); 964 mutex_exit(&pty->ptc_lock); 965 return (err); 966 967 default: 968 return (ENOTTY); 969 } 970 971 return (0); 972 } 973 974 975 int 976 ptcpoll(dev_t dev, 977 short events, 978 int anyyet, 979 short *reventsp, 980 struct pollhead **phpp) 981 { 982 struct pty *pty = &pty_softc[getminor(dev)]; 983 pollhead_t *php = &ptcph; 984 queue_t *q; 985 int pos = 0; 986 987 #ifdef lint 988 anyyet = anyyet; 989 #endif 990 polllock(php, &pty->ptc_lock); 991 992 ASSERT(MUTEX_HELD(&pty->ptc_lock)); 993 994 *reventsp = 0; 995 if (pty->pt_flags & PF_SLAVEGONE) { 996 if (events & (POLLIN|POLLRDNORM)) 997 *reventsp |= (events & (POLLIN|POLLRDNORM)); 998 if (events & (POLLOUT|POLLWRNORM)) 999 *reventsp |= (events & (POLLOUT|POLLWRNORM)); 1000 mutex_exit(&pty->ptc_lock); 1001 /* 1002 * A non NULL pollhead pointer should be returned in case 1003 * user polls for 0 events. 1004 */ 1005 *phpp = !anyyet && !*reventsp ? php : (struct pollhead *)NULL; 1006 return (0); 1007 } 1008 if (events & (POLLIN|POLLRDNORM)) { 1009 if ((q = pty->pt_ttycommon.t_writeq) != NULL && 1010 q->q_first != NULL && !(pty->pt_flags & PF_STOPPED)) { 1011 /* 1012 * Regular data is available. 1013 */ 1014 *reventsp |= (events & (POLLIN|POLLRDNORM)); 1015 pos++; 1016 } 1017 if (pty->pt_flags & (PF_PKT|PF_UCNTL) && pty->pt_send) { 1018 /* 1019 * A control packet is available. 1020 */ 1021 *reventsp |= (events & (POLLIN|POLLRDNORM)); 1022 pos++; 1023 } 1024 if ((pty->pt_flags & PF_UCNTL) && 1025 (pty->pt_ucntl || pty->pt_stuffqfirst != NULL)) { 1026 /* 1027 * "ioctl" or TIOCSTI data is available. 1028 */ 1029 *reventsp |= (events & (POLLIN|POLLRDNORM)); 1030 pos++; 1031 } 1032 if ((pty->pt_flags & PF_43UCNTL) && pty->pt_ucntl) { 1033 *reventsp |= (events & (POLLIN|POLLRDNORM)); 1034 pos++; 1035 } 1036 } 1037 if (events & (POLLOUT|POLLWRNORM)) { 1038 if ((q = pty->pt_ttycommon.t_readq) != NULL && 1039 canput(q)) { 1040 *reventsp |= (events & (POLLOUT|POLLWRNORM)); 1041 pos++; 1042 } 1043 } 1044 if (events & POLLERR) { 1045 *reventsp |= POLLERR; 1046 pos++; 1047 } 1048 if (events == 0) { /* "exceptional conditions" */ 1049 if (((pty->pt_flags & (PF_PKT|PF_UCNTL)) && pty->pt_send) || 1050 ((pty->pt_flags & PF_UCNTL) && 1051 (pty->pt_ucntl || pty->pt_stuffqfirst != NULL))) { 1052 pos++; 1053 } 1054 if ((pty->pt_flags & PF_43UCNTL) && pty->pt_ucntl) { 1055 pos++; 1056 } 1057 } 1058 1059 /* 1060 * Arrange to have poll waken up when event occurs. 1061 * if (!anyyet) 1062 */ 1063 if (!pos) { 1064 *phpp = php; 1065 *reventsp = 0; 1066 } 1067 1068 mutex_exit(&pty->ptc_lock); 1069 return (0); 1070 } 1071 1072 void 1073 gsignal(int pid, int sig) 1074 { 1075 procset_t set; 1076 sigsend_t v; 1077 1078 bzero(&v, sizeof (v)); 1079 v.sig = sig; 1080 v.perm = 0; 1081 v.checkperm = 1; 1082 v.value.sival_ptr = NULL; 1083 1084 setprocset(&set, POP_AND, P_PGID, -pid, P_ALL, P_MYID); 1085 (void) sigsendset(&set, &v); 1086 } 1087 1088 static int 1089 makemsg(ssize_t count, struct uio *uiop, struct pty *pty, mblk_t **mpp) 1090 { 1091 int pri = BPRI_LO; 1092 int error; 1093 mblk_t *bp = NULL; 1094 1095 ASSERT(MUTEX_HELD(&pty->ptc_lock)); 1096 1097 *mpp = NULL; 1098 1099 /* 1100 * Create data part of message, if any. 1101 */ 1102 if (count >= 0) { 1103 if ((bp = allocb(count, pri)) == NULL) 1104 return (ENOSR); 1105 1106 mutex_exit(&pty->ptc_lock); 1107 error = uiomove((caddr_t)bp->b_wptr, count, UIO_WRITE, uiop); 1108 mutex_enter(&pty->ptc_lock); 1109 if (error) { 1110 freeb(bp); 1111 return (error); 1112 } 1113 1114 bp->b_wptr += count; 1115 } 1116 1117 *mpp = bp; 1118 return (0); 1119 } 1120