1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 30 #pragma ident "%Z%%M% %I% %E% SMI" /* SVR4 1.13 */ 31 32 /* 33 * Pseudo Terminal Slave Driver. 34 * 35 * The pseudo-tty subsystem simulates a terminal connection, where the master 36 * side represents the terminal and the slave represents the user process's 37 * special device end point. The master device is set up as a cloned device 38 * where its major device number is the major for the clone device and its minor 39 * device number is the major for the ptm driver. There are no nodes in the file 40 * system for master devices. The master pseudo driver is opened using the 41 * open(2) system call with /dev/ptmx as the device parameter. The clone open 42 * finds the next available minor device for the ptm major device. 43 * 44 * A master device is available only if it and its corresponding slave device 45 * are not already open. When the master device is opened, the corresponding 46 * slave device is automatically locked out. Only one open is allowed on a 47 * master device. Multiple opens are allowed on the slave device. After both 48 * the master and slave have been opened, the user has two file descriptors 49 * which are the end points of a full duplex connection composed of two streams 50 * which are automatically connected at the master and slave drivers. The user 51 * may then push modules onto either side of the stream pair. 52 * 53 * The master and slave drivers pass all messages to their adjacent queues. 54 * Only the M_FLUSH needs some processing. Because the read queue of one side 55 * is connected to the write queue of the other, the FLUSHR flag is changed to 56 * the FLUSHW flag and vice versa. When the master device is closed an M_HANGUP 57 * message is sent to the slave device which will render the device 58 * unusable. The process on the slave side gets the EIO when attempting to write 59 * on that stream but it will be able to read any data remaining on the stream 60 * head read queue. When all the data has been read, read() returns 0 61 * indicating that the stream can no longer be used. On the last close of the 62 * slave device, a 0-length message is sent to the master device. When the 63 * application on the master side issues a read() or getmsg() and 0 is returned, 64 * the user of the master device decides whether to issue a close() that 65 * dismantles the pseudo-terminal subsystem. If the master device is not closed, 66 * the pseudo-tty subsystem will be available to another user to open the slave 67 * device. 68 * 69 * Synchronization: 70 * 71 * All global data synchronization between ptm/pts is done via global 72 * ptms_lock mutex which is initialized at system boot time from 73 * ptms_initspace (called from space.c). 74 * 75 * Individual fields of pt_ttys structure (except ptm_rdq, pts_rdq and 76 * pt_nullmsg) are protected by pt_ttys.pt_lock mutex. 77 * 78 * PT_ENTER_READ/PT_ENTER_WRITE are reference counter based read-write locks 79 * which allow reader locks to be reacquired by the same thread (usual 80 * reader/writer locks can't be used for that purpose since it is illegal for 81 * a thread to acquire a lock it already holds, even as a reader). The sole 82 * purpose of these macros is to guarantee that the peer queue will not 83 * disappear (due to closing peer) while it is used. It is safe to use 84 * PT_ENTER_READ/PT_EXIT_READ brackets across calls like putq/putnext (since 85 * they are not real locks but reference counts). 86 * 87 * PT_ENTER_WRITE/PT_EXIT_WRITE brackets are used ONLY in master/slave 88 * open/close paths to modify ptm_rdq and pts_rdq fields. These fields should 89 * be set to appropriate queues *after* qprocson() is called during open (to 90 * prevent peer from accessing the queue with incomplete plumbing) and set to 91 * NULL before qprocsoff() is called during close. 92 * 93 * The pt_nullmsg field is only used in open/close routines and it is also 94 * protected by PT_ENTER_WRITE/PT_EXIT_WRITE brackets to avoid extra mutex 95 * holds. 96 * 97 * Lock Ordering: 98 * 99 * If both ptms_lock and per-pty lock should be held, ptms_lock should always 100 * be entered first, followed by per-pty lock. 101 * 102 * See ptms.h, ptm.c and ptms_conf.c fore more information. 103 * 104 */ 105 106 #include <sys/types.h> 107 #include <sys/param.h> 108 #include <sys/sysmacros.h> 109 #include <sys/stream.h> 110 #include <sys/stropts.h> 111 #include <sys/stat.h> 112 #include <sys/errno.h> 113 #include <sys/debug.h> 114 #include <sys/cmn_err.h> 115 #include <sys/ptms.h> 116 #include <sys/systm.h> 117 #include <sys/modctl.h> 118 #include <sys/conf.h> 119 #include <sys/ddi.h> 120 #include <sys/sunddi.h> 121 #include <sys/cred.h> 122 #include <sys/zone.h> 123 124 #ifdef DEBUG 125 int pts_debug = 0; 126 #define DBG(a) if (pts_debug) cmn_err(CE_NOTE, a) 127 #else 128 #define DBG(a) 129 #endif 130 131 static int ptsopen(queue_t *, dev_t *, int, int, cred_t *); 132 static int ptsclose(queue_t *, int, cred_t *); 133 static void ptswput(queue_t *, mblk_t *); 134 static void ptsrsrv(queue_t *); 135 static void ptswsrv(queue_t *); 136 137 /* 138 * Slave Stream Pseudo Terminal Module: stream data structure definitions 139 */ 140 static struct module_info pts_info = { 141 0xface, 142 "pts", 143 0, 144 512, 145 512, 146 128 147 }; 148 149 static struct qinit ptsrint = { 150 NULL, 151 (int (*)()) ptsrsrv, 152 ptsopen, 153 ptsclose, 154 NULL, 155 &pts_info, 156 NULL 157 }; 158 159 static struct qinit ptswint = { 160 (int (*)()) ptswput, 161 (int (*)()) ptswsrv, 162 NULL, 163 NULL, 164 NULL, 165 &pts_info, 166 NULL 167 }; 168 169 static struct streamtab ptsinfo = { 170 &ptsrint, 171 &ptswint, 172 NULL, 173 NULL 174 }; 175 176 static int pts_devinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 177 static int pts_attach(dev_info_t *, ddi_attach_cmd_t); 178 static int pts_detach(dev_info_t *, ddi_detach_cmd_t); 179 180 #define PTS_CONF_FLAG (D_NEW | D_MP) 181 182 /* 183 * this will define (struct cb_ops cb_pts_ops) and (struct dev_ops pts_ops) 184 */ 185 DDI_DEFINE_STREAM_OPS(pts_ops, nulldev, nulldev, \ 186 pts_attach, pts_detach, nodev, \ 187 pts_devinfo, PTS_CONF_FLAG, &ptsinfo); 188 189 /* 190 * Module linkage information for the kernel. 191 */ 192 193 static struct modldrv modldrv = { 194 &mod_driverops, /* Type of module. This one is a pseudo driver */ 195 "Slave Stream Pseudo Terminal driver 'pts'", 196 &pts_ops, /* driver ops */ 197 }; 198 199 static struct modlinkage modlinkage = { 200 MODREV_1, 201 &modldrv, 202 NULL 203 }; 204 205 int 206 _init(void) 207 { 208 int rc; 209 210 if ((rc = mod_install(&modlinkage)) == 0) 211 ptms_init(); 212 return (rc); 213 } 214 215 216 int 217 _fini(void) 218 { 219 return (mod_remove(&modlinkage)); 220 } 221 222 int 223 _info(struct modinfo *modinfop) 224 { 225 return (mod_info(&modlinkage, modinfop)); 226 } 227 228 static int 229 pts_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 230 { 231 if (cmd != DDI_ATTACH) 232 return (DDI_FAILURE); 233 234 return (ptms_create_pts_nodes(devi)); 235 } 236 237 static int 238 pts_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 239 { 240 if (cmd != DDI_DETACH) 241 return (DDI_FAILURE); 242 243 return (ptms_destroy_pts_nodes(devi)); 244 } 245 246 /*ARGSUSED*/ 247 static int 248 pts_devinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 249 void **result) 250 { 251 int error; 252 253 switch (infocmd) { 254 case DDI_INFO_DEVT2DEVINFO: 255 if (pts_dip == NULL) { 256 error = DDI_FAILURE; 257 } else { 258 *result = (void *)pts_dip; 259 error = DDI_SUCCESS; 260 } 261 break; 262 case DDI_INFO_DEVT2INSTANCE: 263 *result = (void *)0; 264 error = DDI_SUCCESS; 265 break; 266 default: 267 error = DDI_FAILURE; 268 } 269 return (error); 270 } 271 272 /* ARGSUSED */ 273 /* 274 * Open the slave device. Reject a clone open and do not allow the 275 * driver to be pushed. If the slave/master pair is locked or if 276 * the master is not open, return EACCESS. 277 * Upon success, store the write queue pointer in private data and 278 * set the PTSOPEN bit in the pt_state field. 279 */ 280 static int 281 ptsopen( 282 queue_t *rqp, /* pointer to the read side queue */ 283 dev_t *devp, /* pointer to stream tail's dev */ 284 int oflag, /* the user open(2) supplied flags */ 285 int sflag, /* open state flag */ 286 cred_t *credp) /* credentials */ 287 { 288 struct pt_ttys *ptsp; 289 mblk_t *mp; 290 mblk_t *mop; /* ptr to a setopts message block */ 291 minor_t dminor = getminor(*devp); 292 struct stroptions *sop; 293 294 DDBG("entering ptsopen(%d)", dminor); 295 296 if (sflag != 0) { 297 return (EINVAL); 298 } 299 300 mutex_enter(&ptms_lock); 301 ptsp = ptms_minor2ptty(dminor); 302 303 if (ptsp == NULL) { 304 mutex_exit(&ptms_lock); 305 return (ENXIO); 306 } 307 mutex_enter(&ptsp->pt_lock); 308 309 /* 310 * Prevent opens from zones other than the one blessed by ptm. We 311 * can't even allow the global zone to open all pts's, as it would 312 * otherwise inproperly be able to claim pts's already opened by zones. 313 */ 314 if (ptsp->pt_zoneid != getzoneid()) { 315 mutex_exit(&ptsp->pt_lock); 316 mutex_exit(&ptms_lock); 317 return (EPERM); 318 } 319 320 /* 321 * Allow reopen of this device. 322 */ 323 if (rqp->q_ptr != NULL) { 324 mutex_exit(&ptsp->pt_lock); 325 mutex_exit(&ptms_lock); 326 return (0); 327 } 328 329 DDBGP("ptsopen: p = %p\n", (uintptr_t)ptsp); 330 DDBG("ptsopen: state = %x\n", ptsp->pt_state); 331 332 333 ASSERT(ptsp->pt_minor == dminor); 334 335 if ((ptsp->pt_state & PTLOCK) || !(ptsp->pt_state & PTMOPEN)) { 336 mutex_exit(&ptsp->pt_lock); 337 mutex_exit(&ptms_lock); 338 return (EAGAIN); 339 } 340 341 /* 342 * if already, open simply return... 343 */ 344 if (ptsp->pt_state & PTSOPEN) { 345 mutex_exit(&ptsp->pt_lock); 346 mutex_exit(&ptms_lock); 347 return (0); 348 } 349 350 /* 351 * Allocate message block for setting stream head options. 352 */ 353 if ((mop = allocb(sizeof (struct stroptions), BPRI_MED)) == NULL) { 354 mutex_exit(&ptsp->pt_lock); 355 mutex_exit(&ptms_lock); 356 return (ENOMEM); 357 } 358 359 /* 360 * Slave should send zero-length message to a master when it is 361 * closing. If memory is low at that time, master will not detect slave 362 * closes, this pty will not be deallocated. So, preallocate this 363 * zero-length message block early. 364 */ 365 if ((mp = allocb(0, BPRI_MED)) == NULL) { 366 mutex_exit(&ptsp->pt_lock); 367 mutex_exit(&ptms_lock); 368 freemsg(mop); 369 return (ENOMEM); 370 } 371 372 ptsp->pt_state |= PTSOPEN; 373 374 WR(rqp)->q_ptr = rqp->q_ptr = ptsp; 375 376 mutex_exit(&ptsp->pt_lock); 377 mutex_exit(&ptms_lock); 378 379 qprocson(rqp); 380 381 /* 382 * After qprocson pts driver is fully plumbed into the stream and can 383 * send/receive messages. Setting pts_rdq will allow master side to send 384 * messages to the slave. This setting can't occur before qprocson() is 385 * finished because slave is not ready to process them. 386 */ 387 PT_ENTER_WRITE(ptsp); 388 ptsp->pts_rdq = rqp; 389 ASSERT(ptsp->pt_nullmsg == NULL); 390 ptsp->pt_nullmsg = mp; 391 PT_EXIT_WRITE(ptsp); 392 393 /* 394 * set up hi/lo water marks on stream head read queue 395 * and add controlling tty if not set 396 */ 397 398 mop->b_datap->db_type = M_SETOPTS; 399 mop->b_wptr += sizeof (struct stroptions); 400 sop = (struct stroptions *)mop->b_rptr; 401 sop->so_flags = SO_HIWAT | SO_LOWAT | SO_ISTTY; 402 sop->so_hiwat = 512; 403 sop->so_lowat = 256; 404 putnext(rqp, mop); 405 406 return (0); 407 } 408 409 410 411 /* 412 * Find the address to private data identifying the slave's write 413 * queue. Send a 0-length msg up the slave's read queue to designate 414 * the master is closing. Uattach the master from the slave by nulling 415 * out master's write queue field in private data. 416 */ 417 /*ARGSUSED1*/ 418 static int 419 ptsclose(queue_t *rqp, int flag, cred_t *credp) 420 { 421 struct pt_ttys *ptsp; 422 queue_t *wqp; 423 mblk_t *mp; 424 mblk_t *bp; 425 426 /* 427 * q_ptr should never be NULL in the close routine and it is checked in 428 * DEBUG kernel by ASSERT. For non-DEBUG kernel the attempt is made to 429 * behave gracefully. 430 */ 431 ASSERT(rqp->q_ptr != NULL); 432 if (rqp->q_ptr == NULL) { 433 qprocsoff(rqp); 434 return (0); 435 } 436 437 ptsp = (struct pt_ttys *)rqp->q_ptr; 438 439 /* 440 * Slave is going to close and doesn't want any new messages coming 441 * from the master side, so set pts_rdq to NULL. This should be done 442 * before call to qprocsoff() since slave can't process additional 443 * messages from the master after qprocsoff is called. 444 */ 445 PT_ENTER_WRITE(ptsp); 446 mp = ptsp->pt_nullmsg; 447 ptsp->pt_nullmsg = NULL; 448 ptsp->pts_rdq = NULL; 449 PT_EXIT_WRITE(ptsp); 450 451 /* 452 * Drain the ouput 453 */ 454 wqp = WR(rqp); 455 PT_ENTER_READ(ptsp); 456 while ((bp = getq(wqp)) != NULL) { 457 if (ptsp->ptm_rdq) { 458 putnext(ptsp->ptm_rdq, bp); 459 } else if (bp->b_datap->db_type == M_IOCTL) { 460 bp->b_datap->db_type = M_IOCNAK; 461 freemsg(bp->b_cont); 462 bp->b_cont = NULL; 463 qreply(wqp, bp); 464 } else { 465 freemsg(bp); 466 } 467 } 468 /* 469 * qenable master side write queue so that it can flush 470 * its messages as slaves's read queue is going away 471 */ 472 if (ptsp->ptm_rdq) { 473 if (mp) 474 putnext(ptsp->ptm_rdq, mp); 475 else 476 qenable(WR(ptsp->ptm_rdq)); 477 } else 478 freemsg(mp); 479 PT_EXIT_READ(ptsp); 480 481 qprocsoff(rqp); 482 483 rqp->q_ptr = NULL; 484 WR(rqp)->q_ptr = NULL; 485 486 ptms_close(ptsp, PTSOPEN | PTSTTY); 487 488 return (0); 489 } 490 491 492 /* 493 * The wput procedure will only handle flush messages. 494 * All other messages are queued and the write side 495 * service procedure sends them off to the master side. 496 */ 497 static void 498 ptswput(queue_t *qp, mblk_t *mp) 499 { 500 struct pt_ttys *ptsp; 501 struct iocblk *iocp; 502 unsigned char type = mp->b_datap->db_type; 503 504 DBG(("entering ptswput\n")); 505 ASSERT(qp->q_ptr); 506 507 ptsp = (struct pt_ttys *)qp->q_ptr; 508 PT_ENTER_READ(ptsp); 509 if (ptsp->ptm_rdq == NULL) { 510 DBG(("in write put proc but no master\n")); 511 /* 512 * NAK ioctl as slave side read queue is gone. 513 * Or else free the message. 514 */ 515 if (mp->b_datap->db_type == M_IOCTL) { 516 mp->b_datap->db_type = M_IOCNAK; 517 freemsg(mp->b_cont); 518 mp->b_cont = NULL; 519 qreply(qp, mp); 520 } else 521 freemsg(mp); 522 PT_EXIT_READ(ptsp); 523 return; 524 } 525 526 if (type >= QPCTL) { 527 switch (type) { 528 529 /* 530 * if write queue request, flush slave's write 531 * queue and send FLUSHR to ptm. If read queue 532 * request, send FLUSHR to ptm. 533 */ 534 case M_FLUSH: 535 DBG(("pts got flush request\n")); 536 if (*mp->b_rptr & FLUSHW) { 537 538 DBG(("got FLUSHW, flush pts write Q\n")); 539 if (*mp->b_rptr & FLUSHBAND) 540 /* 541 * if it is a FLUSHBAND, do flushband. 542 */ 543 flushband(qp, *(mp->b_rptr + 1), FLUSHDATA); 544 else 545 flushq(qp, FLUSHDATA); 546 547 *mp->b_rptr &= ~FLUSHW; 548 if ((*mp->b_rptr & FLUSHR) == 0) { 549 /* 550 * FLUSHW only. Change to FLUSHR and putnext 551 * to ptm, then we are done. 552 */ 553 *mp->b_rptr |= FLUSHR; 554 if (ptsp->ptm_rdq) 555 putnext(ptsp->ptm_rdq, mp); 556 break; 557 } else { 558 mblk_t *nmp; 559 560 /* It is a FLUSHRW. Duplicate the mblk */ 561 nmp = copyb(mp); 562 if (nmp) { 563 /* 564 * Change FLUSHW to FLUSHR before 565 * putnext to ptm. 566 */ 567 DBG(("putnext nmp(FLUSHR) to ptm\n")); 568 *nmp->b_rptr |= FLUSHR; 569 if (ptsp->ptm_rdq) 570 putnext(ptsp->ptm_rdq, nmp); 571 } 572 } 573 } 574 /* 575 * Since the packet module will toss any 576 * M_FLUSHES sent to the master's stream head 577 * read queue, we simply turn it around here. 578 */ 579 if (*mp->b_rptr & FLUSHR) { 580 ASSERT(RD(qp)->q_first == NULL); 581 DBG(("qreply(qp) turning FLUSHR around\n")); 582 qreply(qp, mp); 583 } else { 584 freemsg(mp); 585 } 586 break; 587 588 case M_READ: 589 /* Caused by ldterm - can not pass to master */ 590 freemsg(mp); 591 break; 592 593 default: 594 if (ptsp->ptm_rdq) 595 putnext(ptsp->ptm_rdq, mp); 596 break; 597 } 598 PT_EXIT_READ(ptsp); 599 return; 600 } 601 602 switch (type) { 603 604 case M_IOCTL: 605 /* 606 * For case PTSSTTY set the flag PTSTTY and ACK 607 * the ioctl so that the user program can push 608 * the associated modules to get tty semantics. 609 * See bugid 4025044 610 */ 611 iocp = (struct iocblk *)mp->b_rptr; 612 switch (iocp->ioc_cmd) { 613 default: 614 break; 615 616 case PTSSTTY: 617 if (ptsp->pt_state & PTSTTY) { 618 mp->b_datap->db_type = M_IOCNAK; 619 iocp->ioc_error = EEXIST; 620 } else { 621 mp->b_datap->db_type = M_IOCACK; 622 mutex_enter(&ptsp->pt_lock); 623 ptsp->pt_state |= PTSTTY; 624 mutex_exit(&ptsp->pt_lock); 625 iocp->ioc_error = 0; 626 } 627 iocp->ioc_count = 0; 628 qreply(qp, mp); 629 PT_EXIT_READ(ptsp); 630 return; 631 } 632 633 default: 634 /* 635 * send other messages to the master 636 */ 637 DBG(("put msg on slave's write queue\n")); 638 (void) putq(qp, mp); 639 break; 640 } 641 642 PT_EXIT_READ(ptsp); 643 DBG(("return from ptswput()\n")); 644 } 645 646 647 /* 648 * enable the write side of the master. This triggers the 649 * master to send any messages queued on its write side to 650 * the read side of this slave. 651 */ 652 static void 653 ptsrsrv(queue_t *qp) 654 { 655 struct pt_ttys *ptsp; 656 657 DBG(("entering ptsrsrv\n")); 658 ASSERT(qp->q_ptr); 659 660 ptsp = (struct pt_ttys *)qp->q_ptr; 661 PT_ENTER_READ(ptsp); 662 if (ptsp->ptm_rdq == NULL) { 663 DBG(("in read srv proc but no master\n")); 664 PT_EXIT_READ(ptsp); 665 return; 666 } 667 qenable(WR(ptsp->ptm_rdq)); 668 PT_EXIT_READ(ptsp); 669 DBG(("leaving ptsrsrv\n")); 670 } 671 672 /* 673 * If there are messages on this queue that can be sent to 674 * master, send them via putnext(). Else, if queued messages 675 * cannot be sent, leave them on this queue. If priority 676 * messages on this queue, send them to master no matter what. 677 */ 678 static void 679 ptswsrv(queue_t *qp) 680 { 681 struct pt_ttys *ptsp; 682 queue_t *ptm_rdq; 683 mblk_t *mp; 684 685 DBG(("entering ptswsrv\n")); 686 ASSERT(qp->q_ptr); 687 688 ptsp = (struct pt_ttys *)qp->q_ptr; 689 PT_ENTER_READ(ptsp); 690 if (ptsp->ptm_rdq == NULL) { 691 DBG(("in write srv proc but no master\n")); 692 /* 693 * Free messages on the write queue and send 694 * NAK for any M_IOCTL type messages to wakeup 695 * the user process waiting for ACK/NAK from 696 * the ioctl invocation 697 */ 698 while ((mp = getq(qp)) != NULL) { 699 if (mp->b_datap->db_type == M_IOCTL) { 700 mp->b_datap->db_type = M_IOCNAK; 701 freemsg(mp->b_cont); 702 mp->b_cont = NULL; 703 qreply(qp, mp); 704 } else 705 freemsg(mp); 706 } 707 PT_EXIT_READ(ptsp); 708 return; 709 } else { 710 ptm_rdq = ptsp->ptm_rdq; 711 } 712 713 /* 714 * while there are messages on this write queue... 715 */ 716 while ((mp = getq(qp)) != NULL) { 717 /* 718 * if don't have control message and cannot put 719 * msg. on master's read queue, put it back on 720 * this queue. 721 */ 722 if (mp->b_datap->db_type <= QPCTL && 723 !bcanputnext(ptm_rdq, mp->b_band)) { 724 DBG(("put msg. back on Q\n")); 725 (void) putbq(qp, mp); 726 break; 727 } 728 /* 729 * else send the message up master's stream 730 */ 731 DBG(("send message to master\n")); 732 putnext(ptm_rdq, mp); 733 } 734 DBG(("leaving ptswsrv\n")); 735 PT_EXIT_READ(ptsp); 736 } 737