1 /* $NetBSD: tty_pty.c,v 1.71 2003/07/23 13:10:28 dsl Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 36 */ 37 38 /* 39 * Pseudo-teletype Driver 40 * (Actually two drivers, requiring two entries in 'cdevsw') 41 */ 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: tty_pty.c,v 1.71 2003/07/23 13:10:28 dsl Exp $"); 45 46 #include "opt_compat_sunos.h" 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/ioctl.h> 51 #include <sys/proc.h> 52 #include <sys/tty.h> 53 #include <sys/file.h> 54 #include <sys/uio.h> 55 #include <sys/kernel.h> 56 #include <sys/vnode.h> 57 #include <sys/signalvar.h> 58 #include <sys/uio.h> 59 #include <sys/conf.h> 60 #include <sys/poll.h> 61 #include <sys/malloc.h> 62 63 #define DEFAULT_NPTYS 16 /* default number of initial ptys */ 64 #define DEFAULT_MAXPTYS 992 /* default maximum number of ptys */ 65 66 /* Macros to clear/set/test flags. */ 67 #define SET(t, f) (t) |= (f) 68 #define CLR(t, f) (t) &= ~((unsigned)(f)) 69 #define ISSET(t, f) ((t) & (f)) 70 71 #define BUFSIZ 100 /* Chunk size iomoved to/from user */ 72 73 /* 74 * pts == /dev/tty[pqrs]? 75 * ptc == /dev/pty[pqrs]? 76 */ 77 struct pt_softc { 78 struct tty *pt_tty; 79 int pt_flags; 80 struct selinfo pt_selr, pt_selw; 81 u_char pt_send; 82 u_char pt_ucntl; 83 }; 84 85 static struct pt_softc **pt_softc = NULL; /* pty array */ 86 static int npty = 0; /* for pstat -t */ 87 static int maxptys = DEFAULT_MAXPTYS; /* maximum number of ptys (sysctable) */ 88 static struct simplelock pt_softc_mutex = SIMPLELOCK_INITIALIZER; 89 90 #define PF_PKT 0x08 /* packet mode */ 91 #define PF_STOPPED 0x10 /* user told stopped */ 92 #define PF_REMOTE 0x20 /* remote and flow controlled input */ 93 #define PF_NOSTOP 0x40 94 #define PF_UCNTL 0x80 /* user control mode */ 95 96 void ptyattach __P((int)); 97 void ptcwakeup __P((struct tty *, int)); 98 void ptsstart __P((struct tty *)); 99 int pty_maxptys __P((int, int)); 100 101 static struct pt_softc **ptyarralloc __P((int)); 102 static int check_pty(int); 103 104 dev_type_open(ptcopen); 105 dev_type_close(ptcclose); 106 dev_type_read(ptcread); 107 dev_type_write(ptcwrite); 108 dev_type_poll(ptcpoll); 109 dev_type_kqfilter(ptckqfilter); 110 111 dev_type_open(ptsopen); 112 dev_type_close(ptsclose); 113 dev_type_read(ptsread); 114 dev_type_write(ptswrite); 115 dev_type_stop(ptsstop); 116 dev_type_poll(ptspoll); 117 118 dev_type_ioctl(ptyioctl); 119 dev_type_tty(ptytty); 120 121 const struct cdevsw ptc_cdevsw = { 122 ptcopen, ptcclose, ptcread, ptcwrite, ptyioctl, 123 nullstop, ptytty, ptcpoll, nommap, ptckqfilter, D_TTY 124 }; 125 126 const struct cdevsw pts_cdevsw = { 127 ptsopen, ptsclose, ptsread, ptswrite, ptyioctl, 128 ptsstop, ptytty, ptspoll, nommap, ttykqfilter, D_TTY 129 }; 130 131 #if defined(pmax) 132 const struct cdevsw ptc_ultrix_cdevsw = { 133 ptcopen, ptcclose, ptcread, ptcwrite, ptyioctl, 134 nullstop, ptytty, ptcpoll, nommap, ptckqfilter, D_TTY 135 }; 136 137 const struct cdevsw pts_ultrix_cdevsw = { 138 ptsopen, ptsclose, ptsread, ptswrite, ptyioctl, 139 ptsstop, ptytty, ptspoll, nommap, ttykqfilter, D_TTY 140 }; 141 #endif /* defined(pmax) */ 142 143 /* 144 * Allocate and zero array of nelem elements. 145 */ 146 static struct pt_softc ** 147 ptyarralloc(nelem) 148 int nelem; 149 { 150 struct pt_softc **pt; 151 nelem += 10; 152 pt = malloc(nelem * sizeof *pt, M_DEVBUF, M_WAITOK | M_ZERO); 153 return pt; 154 } 155 156 /* 157 * Check if the minor is correct and ensure necessary structures 158 * are properly allocated. 159 */ 160 static int 161 check_pty(int ptn) 162 { 163 struct pt_softc *pti; 164 165 if (ptn >= npty) { 166 struct pt_softc **newpt, **oldpt; 167 int newnpty; 168 169 /* check if the requested pty can be granted */ 170 if (ptn >= maxptys) { 171 limit_reached: 172 tablefull("pty", "increase kern.maxptys"); 173 return (ENXIO); 174 } 175 176 /* Allocate a larger pty array */ 177 for (newnpty = npty; newnpty <= ptn;) 178 newnpty *= 2; 179 if (newnpty > maxptys) 180 newnpty = maxptys; 181 newpt = ptyarralloc(newnpty); 182 183 /* 184 * Now grab the pty array mutex - we need to ensure 185 * that the pty array is consistent while copying it's 186 * content to newly allocated, larger space; we also 187 * need to be safe against pty_maxptys(). 188 */ 189 simple_lock(&pt_softc_mutex); 190 191 if (newnpty >= maxptys) { 192 /* limit cut away beneath us... */ 193 newnpty = maxptys; 194 if (ptn >= newnpty) { 195 simple_unlock(&pt_softc_mutex); 196 free(newpt, M_DEVBUF); 197 goto limit_reached; 198 } 199 } 200 201 /* 202 * If the pty array was not enlarged while we were waiting 203 * for mutex, copy current contents of pt_softc[] to newly 204 * allocated array and start using the new bigger array. 205 */ 206 if (newnpty > npty) { 207 memcpy(newpt, pt_softc, npty*sizeof(struct pt_softc *)); 208 oldpt = pt_softc; 209 pt_softc = newpt; 210 npty = newnpty; 211 } else { 212 /* was enlarged when waited for lock, free new space */ 213 oldpt = newpt; 214 } 215 216 simple_unlock(&pt_softc_mutex); 217 free(oldpt, M_DEVBUF); 218 } 219 220 /* 221 * If the entry is not yet allocated, allocate one. The mutex is 222 * needed so that the state of pt_softc[] array is consistant 223 * in case it has been lengthened above. 224 */ 225 if (!pt_softc[ptn]) { 226 MALLOC(pti, struct pt_softc *, sizeof(struct pt_softc), 227 M_DEVBUF, M_WAITOK); 228 memset(pti, 0, sizeof(struct pt_softc)); 229 230 pti->pt_tty = ttymalloc(); 231 232 simple_lock(&pt_softc_mutex); 233 234 /* 235 * Check the entry again - it might have been 236 * added while we were waiting for mutex. 237 */ 238 if (!pt_softc[ptn]) { 239 tty_attach(pti->pt_tty); 240 pt_softc[ptn] = pti; 241 } else { 242 ttyfree(pti->pt_tty); 243 free(pti, M_DEVBUF); 244 } 245 246 simple_unlock(&pt_softc_mutex); 247 } 248 249 return (0); 250 } 251 252 /* 253 * Set maxpty in thread-safe way. Returns 0 in case of error, otherwise 254 * new value of maxptys. 255 */ 256 int 257 pty_maxptys(newmax, set) 258 int newmax, set; 259 { 260 if (!set) 261 return (maxptys); 262 263 /* 264 * We have to grab the pt_softc lock, so that we would pick correct 265 * value of npty (might be modified in check_pty()). 266 */ 267 simple_lock(&pt_softc_mutex); 268 269 /* 270 * The value cannot be set to value lower than the highest pty 271 * number ever allocated. 272 */ 273 if (newmax >= npty) 274 maxptys = newmax; 275 else 276 newmax = 0; 277 278 simple_unlock(&pt_softc_mutex); 279 280 return newmax; 281 } 282 283 /* 284 * Establish n (or default if n is 1) ptys in the system. 285 */ 286 void 287 ptyattach(n) 288 int n; 289 { 290 /* maybe should allow 0 => none? */ 291 if (n <= 1) 292 n = DEFAULT_NPTYS; 293 pt_softc = ptyarralloc(n); 294 npty = n; 295 } 296 297 /*ARGSUSED*/ 298 int 299 ptsopen(dev, flag, devtype, p) 300 dev_t dev; 301 int flag, devtype; 302 struct proc *p; 303 { 304 struct pt_softc *pti; 305 struct tty *tp; 306 int error; 307 int ptn = minor(dev); 308 309 if ((error = check_pty(ptn))) 310 return (error); 311 312 pti = pt_softc[ptn]; 313 tp = pti->pt_tty; 314 315 if (!ISSET(tp->t_state, TS_ISOPEN)) { 316 ttychars(tp); /* Set up default chars */ 317 tp->t_iflag = TTYDEF_IFLAG; 318 tp->t_oflag = TTYDEF_OFLAG; 319 tp->t_lflag = TTYDEF_LFLAG; 320 tp->t_cflag = TTYDEF_CFLAG; 321 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 322 ttsetwater(tp); /* would be done in xxparam() */ 323 } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) 324 return (EBUSY); 325 if (tp->t_oproc) /* Ctrlr still around. */ 326 SET(tp->t_state, TS_CARR_ON); 327 328 if (!ISSET(flag, O_NONBLOCK)) { 329 TTY_LOCK(tp); 330 while (!ISSET(tp->t_state, TS_CARR_ON)) { 331 tp->t_wopen++; 332 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 333 ttopen, 0); 334 tp->t_wopen--; 335 if (error) { 336 TTY_UNLOCK(tp); 337 return (error); 338 } 339 } 340 TTY_UNLOCK(tp); 341 } 342 error = (*tp->t_linesw->l_open)(dev, tp); 343 ptcwakeup(tp, FREAD|FWRITE); 344 return (error); 345 } 346 347 int 348 ptsclose(dev, flag, mode, p) 349 dev_t dev; 350 int flag, mode; 351 struct proc *p; 352 { 353 struct pt_softc *pti = pt_softc[minor(dev)]; 354 struct tty *tp = pti->pt_tty; 355 int error; 356 357 error = (*tp->t_linesw->l_close)(tp, flag); 358 error |= ttyclose(tp); 359 ptcwakeup(tp, FREAD|FWRITE); 360 return (error); 361 } 362 363 int 364 ptsread(dev, uio, flag) 365 dev_t dev; 366 struct uio *uio; 367 int flag; 368 { 369 struct proc *p = curproc; 370 struct pt_softc *pti = pt_softc[minor(dev)]; 371 struct tty *tp = pti->pt_tty; 372 int error = 0; 373 int cc; 374 375 again: 376 if (pti->pt_flags & PF_REMOTE) { 377 while (isbackground(p, tp)) { 378 if (sigismasked(p, SIGTTIN) || 379 p->p_pgrp->pg_jobc == 0 || 380 p->p_flag & P_PPWAIT) 381 return (EIO); 382 pgsignal(p->p_pgrp, SIGTTIN, 1); 383 TTY_LOCK(tp); 384 error = ttysleep(tp, (caddr_t)&lbolt, 385 TTIPRI | PCATCH | PNORELOCK, ttybg, 0); 386 if (error) 387 return (error); 388 } 389 TTY_LOCK(tp); 390 if (tp->t_canq.c_cc == 0) { 391 if (flag & IO_NDELAY) { 392 TTY_UNLOCK(tp); 393 return (EWOULDBLOCK); 394 } 395 error = ttysleep(tp, (caddr_t)&tp->t_canq, 396 TTIPRI | PCATCH | PNORELOCK, ttyin, 0); 397 if (error) 398 return (error); 399 goto again; 400 } 401 while(error == 0 && tp->t_canq.c_cc > 1 && uio->uio_resid > 0) { 402 TTY_UNLOCK(tp); 403 error = ureadc(getc(&tp->t_canq), uio); 404 TTY_LOCK(tp); 405 /* Re-check terminal state here? */ 406 } 407 if (tp->t_canq.c_cc == 1) 408 (void) getc(&tp->t_canq); 409 cc = tp->t_canq.c_cc; 410 TTY_UNLOCK(tp); 411 if (cc) 412 return (error); 413 } else 414 if (tp->t_oproc) 415 error = (*tp->t_linesw->l_read)(tp, uio, flag); 416 ptcwakeup(tp, FWRITE); 417 return (error); 418 } 419 420 /* 421 * Write to pseudo-tty. 422 * Wakeups of controlling tty will happen 423 * indirectly, when tty driver calls ptsstart. 424 */ 425 int 426 ptswrite(dev, uio, flag) 427 dev_t dev; 428 struct uio *uio; 429 int flag; 430 { 431 struct pt_softc *pti = pt_softc[minor(dev)]; 432 struct tty *tp = pti->pt_tty; 433 434 if (tp->t_oproc == 0) 435 return (EIO); 436 return ((*tp->t_linesw->l_write)(tp, uio, flag)); 437 } 438 439 /* 440 * Poll pseudo-tty. 441 */ 442 int 443 ptspoll(dev, events, p) 444 dev_t dev; 445 int events; 446 struct proc *p; 447 { 448 struct pt_softc *pti = pt_softc[minor(dev)]; 449 struct tty *tp = pti->pt_tty; 450 451 if (tp->t_oproc == 0) 452 return (EIO); 453 454 return ((*tp->t_linesw->l_poll)(tp, events, p)); 455 } 456 457 /* 458 * Start output on pseudo-tty. 459 * Wake up process polling or sleeping for input from controlling tty. 460 * Called with tty slock held. 461 */ 462 void 463 ptsstart(tp) 464 struct tty *tp; 465 { 466 struct pt_softc *pti = pt_softc[minor(tp->t_dev)]; 467 468 if (ISSET(tp->t_state, TS_TTSTOP)) 469 return; 470 if (pti->pt_flags & PF_STOPPED) { 471 pti->pt_flags &= ~PF_STOPPED; 472 pti->pt_send = TIOCPKT_START; 473 } 474 475 selnotify(&pti->pt_selr, 0); 476 wakeup((caddr_t)&tp->t_outq.c_cf); 477 } 478 479 /* 480 * Stop output. 481 * Called with tty slock held. 482 */ 483 void 484 ptsstop(tp, flush) 485 struct tty *tp; 486 int flush; 487 { 488 struct pt_softc *pti = pt_softc[minor(tp->t_dev)]; 489 490 /* note: FLUSHREAD and FLUSHWRITE already ok */ 491 if (flush == 0) { 492 flush = TIOCPKT_STOP; 493 pti->pt_flags |= PF_STOPPED; 494 } else 495 pti->pt_flags &= ~PF_STOPPED; 496 pti->pt_send |= flush; 497 498 /* change of perspective */ 499 if (flush & FREAD) { 500 selnotify(&pti->pt_selw, 0); 501 wakeup((caddr_t)&tp->t_rawq.c_cf); 502 } 503 if (flush & FWRITE) { 504 selnotify(&pti->pt_selr, 0); 505 wakeup((caddr_t)&tp->t_outq.c_cf); 506 } 507 } 508 509 void 510 ptcwakeup(tp, flag) 511 struct tty *tp; 512 int flag; 513 { 514 struct pt_softc *pti = pt_softc[minor(tp->t_dev)]; 515 516 TTY_LOCK(tp); 517 if (flag & FREAD) { 518 selnotify(&pti->pt_selr, 0); 519 wakeup((caddr_t)&tp->t_outq.c_cf); 520 } 521 if (flag & FWRITE) { 522 selnotify(&pti->pt_selw, 0); 523 wakeup((caddr_t)&tp->t_rawq.c_cf); 524 } 525 TTY_UNLOCK(tp); 526 } 527 528 /*ARGSUSED*/ 529 int 530 ptcopen(dev, flag, devtype, p) 531 dev_t dev; 532 int flag, devtype; 533 struct proc *p; 534 { 535 struct pt_softc *pti; 536 struct tty *tp; 537 int error; 538 int ptn = minor(dev); 539 540 if ((error = check_pty(ptn))) 541 return (error); 542 543 pti = pt_softc[ptn]; 544 tp = pti->pt_tty; 545 546 TTY_LOCK(tp); 547 if (tp->t_oproc) { 548 TTY_UNLOCK(tp); 549 return (EIO); 550 } 551 tp->t_oproc = ptsstart; 552 TTY_UNLOCK(tp); 553 (void)(*tp->t_linesw->l_modem)(tp, 1); 554 CLR(tp->t_lflag, EXTPROC); 555 pti->pt_flags = 0; 556 pti->pt_send = 0; 557 pti->pt_ucntl = 0; 558 return (0); 559 } 560 561 /*ARGSUSED*/ 562 int 563 ptcclose(dev, flag, devtype, p) 564 dev_t dev; 565 int flag, devtype; 566 struct proc *p; 567 { 568 struct pt_softc *pti = pt_softc[minor(dev)]; 569 struct tty *tp = pti->pt_tty; 570 571 (void)(*tp->t_linesw->l_modem)(tp, 0); 572 CLR(tp->t_state, TS_CARR_ON); 573 TTY_LOCK(tp); 574 tp->t_oproc = 0; /* mark closed */ 575 TTY_UNLOCK(tp); 576 return (0); 577 } 578 579 int 580 ptcread(dev, uio, flag) 581 dev_t dev; 582 struct uio *uio; 583 int flag; 584 { 585 struct pt_softc *pti = pt_softc[minor(dev)]; 586 struct tty *tp = pti->pt_tty; 587 u_char buf[BUFSIZ]; 588 int error = 0, cc; 589 590 /* 591 * We want to block until the slave 592 * is open, and there's something to read; 593 * but if we lost the slave or we're NBIO, 594 * then return the appropriate error instead. 595 */ 596 TTY_LOCK(tp); 597 for (;;) { 598 if (ISSET(tp->t_state, TS_ISOPEN)) { 599 if (pti->pt_flags & PF_PKT && pti->pt_send) { 600 TTY_UNLOCK(tp); 601 error = ureadc((int)pti->pt_send, uio); 602 if (error) 603 return (error); 604 /* 605 * Since we don't have the tty locked, there's 606 * a risk of messing up `t_termios'. This is 607 * relevant only if the tty got closed and then 608 * opened again while we were out uiomoving. 609 */ 610 if (pti->pt_send & TIOCPKT_IOCTL) { 611 cc = min(uio->uio_resid, 612 sizeof(tp->t_termios)); 613 uiomove((caddr_t) &tp->t_termios, 614 cc, uio); 615 } 616 pti->pt_send = 0; 617 return (0); 618 } 619 if (pti->pt_flags & PF_UCNTL && pti->pt_ucntl) { 620 TTY_UNLOCK(tp); 621 error = ureadc((int)pti->pt_ucntl, uio); 622 if (error) 623 return (error); 624 pti->pt_ucntl = 0; 625 return (0); 626 } 627 if (tp->t_outq.c_cc && !ISSET(tp->t_state, TS_TTSTOP)) 628 break; 629 } 630 if (!ISSET(tp->t_state, TS_CARR_ON)) { 631 error = 0; /* EOF */ 632 goto out; 633 } 634 if (flag & IO_NDELAY) { 635 error = EWOULDBLOCK; 636 goto out; 637 } 638 error = ltsleep((caddr_t)&tp->t_outq.c_cf, TTIPRI | PCATCH, 639 ttyin, 0, &tp->t_slock); 640 if (error) 641 goto out; 642 } 643 644 if (pti->pt_flags & (PF_PKT|PF_UCNTL)) { 645 TTY_UNLOCK(tp); 646 error = ureadc(0, uio); 647 TTY_LOCK(tp); 648 if (error == 0 && !ISSET(tp->t_state, TS_ISOPEN)) 649 error = EIO; 650 } 651 while (uio->uio_resid > 0 && error == 0) { 652 cc = q_to_b(&tp->t_outq, buf, min(uio->uio_resid, BUFSIZ)); 653 if (cc <= 0) 654 break; 655 TTY_UNLOCK(tp); 656 error = uiomove(buf, cc, uio); 657 TTY_LOCK(tp); 658 if (error == 0 && !ISSET(tp->t_state, TS_ISOPEN)) 659 error = EIO; 660 } 661 662 if (tp->t_outq.c_cc <= tp->t_lowat) { 663 if (ISSET(tp->t_state, TS_ASLEEP)) { 664 CLR(tp->t_state, TS_ASLEEP); 665 wakeup((caddr_t)&tp->t_outq); 666 } 667 selnotify(&tp->t_wsel, 0); 668 } 669 out: 670 TTY_UNLOCK(tp); 671 return (error); 672 } 673 674 675 int 676 ptcwrite(dev, uio, flag) 677 dev_t dev; 678 struct uio *uio; 679 int flag; 680 { 681 struct pt_softc *pti = pt_softc[minor(dev)]; 682 struct tty *tp = pti->pt_tty; 683 u_char *cp = NULL; 684 int cc = 0; 685 u_char locbuf[BUFSIZ]; 686 int cnt = 0; 687 int error = 0; 688 689 again: 690 TTY_LOCK(tp); 691 if (!ISSET(tp->t_state, TS_ISOPEN)) 692 goto block; 693 if (pti->pt_flags & PF_REMOTE) { 694 if (tp->t_canq.c_cc) 695 goto block; 696 while (uio->uio_resid > 0 && tp->t_canq.c_cc < TTYHOG - 1) { 697 if (cc == 0) { 698 cc = min(uio->uio_resid, BUFSIZ); 699 cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc); 700 cp = locbuf; 701 TTY_UNLOCK(tp); 702 error = uiomove((caddr_t)cp, cc, uio); 703 if (error) 704 return (error); 705 TTY_LOCK(tp); 706 /* check again for safety */ 707 if (!ISSET(tp->t_state, TS_ISOPEN)) { 708 error = EIO; 709 goto out; 710 } 711 } 712 if (cc) 713 (void) b_to_q(cp, cc, &tp->t_canq); 714 cc = 0; 715 } 716 (void) putc(0, &tp->t_canq); 717 ttwakeup(tp); 718 wakeup((caddr_t)&tp->t_canq); 719 error = 0; 720 goto out; 721 } 722 while (uio->uio_resid > 0) { 723 if (cc == 0) { 724 cc = min(uio->uio_resid, BUFSIZ); 725 cp = locbuf; 726 TTY_UNLOCK(tp); 727 error = uiomove((caddr_t)cp, cc, uio); 728 if (error) 729 return (error); 730 TTY_LOCK(tp); 731 /* check again for safety */ 732 if (!ISSET(tp->t_state, TS_ISOPEN)) { 733 error = EIO; 734 goto out; 735 } 736 } 737 while (cc > 0) { 738 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 && 739 (tp->t_canq.c_cc > 0 || !ISSET(tp->t_lflag, ICANON))) { 740 wakeup((caddr_t)&tp->t_rawq); 741 goto block; 742 } 743 /* XXX - should change l_rint to be called with lock 744 * see also tty.c:ttyinput_wlock() 745 */ 746 TTY_UNLOCK(tp); 747 (*tp->t_linesw->l_rint)(*cp++, tp); 748 TTY_LOCK(tp); 749 cnt++; 750 cc--; 751 } 752 cc = 0; 753 } 754 error = 0; 755 goto out; 756 757 block: 758 /* 759 * Come here to wait for slave to open, for space 760 * in outq, or space in rawq. 761 */ 762 if (!ISSET(tp->t_state, TS_CARR_ON)) { 763 error = EIO; 764 goto out; 765 } 766 if (flag & IO_NDELAY) { 767 /* adjust for data copied in but not written */ 768 uio->uio_resid += cc; 769 error = cnt == 0 ? EWOULDBLOCK : 0; 770 goto out; 771 } 772 error = ltsleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI | PCATCH | PNORELOCK, 773 ttyout, 0, &tp->t_slock); 774 if (error) { 775 /* adjust for data copied in but not written */ 776 uio->uio_resid += cc; 777 return (error); 778 } 779 goto again; 780 781 out: 782 TTY_UNLOCK(tp); 783 return (error); 784 } 785 786 int 787 ptcpoll(dev, events, p) 788 dev_t dev; 789 int events; 790 struct proc *p; 791 { 792 struct pt_softc *pti = pt_softc[minor(dev)]; 793 struct tty *tp = pti->pt_tty; 794 int revents = 0; 795 int s = splsoftclock(); 796 797 if (events & (POLLIN | POLLRDNORM)) 798 if (ISSET(tp->t_state, TS_ISOPEN) && 799 ((tp->t_outq.c_cc > 0 && !ISSET(tp->t_state, TS_TTSTOP)) || 800 ((pti->pt_flags & PF_PKT) && pti->pt_send) || 801 ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) 802 revents |= events & (POLLIN | POLLRDNORM); 803 804 if (events & (POLLOUT | POLLWRNORM)) 805 if (ISSET(tp->t_state, TS_ISOPEN) && 806 ((pti->pt_flags & PF_REMOTE) ? 807 (tp->t_canq.c_cc == 0) : 808 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2) || 809 (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON))))) 810 revents |= events & (POLLOUT | POLLWRNORM); 811 812 if (events & POLLHUP) 813 if (!ISSET(tp->t_state, TS_CARR_ON)) 814 revents |= POLLHUP; 815 816 if (revents == 0) { 817 if (events & (POLLIN | POLLHUP | POLLRDNORM)) 818 selrecord(p, &pti->pt_selr); 819 820 if (events & (POLLOUT | POLLWRNORM)) 821 selrecord(p, &pti->pt_selw); 822 } 823 824 splx(s); 825 return (revents); 826 } 827 828 static void 829 filt_ptcrdetach(struct knote *kn) 830 { 831 struct pt_softc *pti; 832 int s; 833 834 pti = kn->kn_hook; 835 s = spltty(); 836 SLIST_REMOVE(&pti->pt_selr.sel_klist, kn, knote, kn_selnext); 837 splx(s); 838 } 839 840 static int 841 filt_ptcread(struct knote *kn, long hint) 842 { 843 struct pt_softc *pti; 844 struct tty *tp; 845 int canread; 846 847 pti = kn->kn_hook; 848 tp = pti->pt_tty; 849 850 canread = (ISSET(tp->t_state, TS_ISOPEN) && 851 ((tp->t_outq.c_cc > 0 && !ISSET(tp->t_state, TS_TTSTOP)) || 852 ((pti->pt_flags & PF_PKT) && pti->pt_send) || 853 ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))); 854 855 if (canread) { 856 /* 857 * c_cc is number of characters after output post-processing; 858 * the amount of data actually read(2) depends on 859 * setting of input flags for the terminal. 860 */ 861 kn->kn_data = tp->t_outq.c_cc; 862 if (((pti->pt_flags & PF_PKT) && pti->pt_send) || 863 ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) 864 kn->kn_data++; 865 } 866 867 return (canread); 868 } 869 870 static void 871 filt_ptcwdetach(struct knote *kn) 872 { 873 struct pt_softc *pti; 874 int s; 875 876 pti = kn->kn_hook; 877 s = spltty(); 878 SLIST_REMOVE(&pti->pt_selw.sel_klist, kn, knote, kn_selnext); 879 splx(s); 880 } 881 882 static int 883 filt_ptcwrite(struct knote *kn, long hint) 884 { 885 struct pt_softc *pti; 886 struct tty *tp; 887 int canwrite; 888 int nwrite; 889 890 pti = kn->kn_hook; 891 tp = pti->pt_tty; 892 893 canwrite = (ISSET(tp->t_state, TS_ISOPEN) && 894 ((pti->pt_flags & PF_REMOTE) ? 895 (tp->t_canq.c_cc == 0) : 896 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2) || 897 (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON))))); 898 899 if (canwrite) { 900 if (pti->pt_flags & PF_REMOTE) 901 nwrite = tp->t_canq.c_cn; 902 else { 903 /* this is guaranteed to be > 0 due to above check */ 904 nwrite = tp->t_canq.c_cn 905 - (tp->t_rawq.c_cc + tp->t_canq.c_cc); 906 } 907 kn->kn_data = nwrite; 908 } 909 910 return (canwrite); 911 } 912 913 static const struct filterops ptcread_filtops = 914 { 1, NULL, filt_ptcrdetach, filt_ptcread }; 915 static const struct filterops ptcwrite_filtops = 916 { 1, NULL, filt_ptcwdetach, filt_ptcwrite }; 917 918 int 919 ptckqfilter(dev_t dev, struct knote *kn) 920 { 921 struct pt_softc *pti = pt_softc[minor(dev)]; 922 struct klist *klist; 923 int s; 924 925 switch (kn->kn_filter) { 926 case EVFILT_READ: 927 klist = &pti->pt_selr.sel_klist; 928 kn->kn_fop = &ptcread_filtops; 929 break; 930 case EVFILT_WRITE: 931 klist = &pti->pt_selw.sel_klist; 932 kn->kn_fop = &ptcwrite_filtops; 933 break; 934 default: 935 return (1); 936 } 937 938 kn->kn_hook = pti; 939 940 s = spltty(); 941 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 942 splx(s); 943 944 return (0); 945 } 946 947 struct tty * 948 ptytty(dev) 949 dev_t dev; 950 { 951 struct pt_softc *pti = pt_softc[minor(dev)]; 952 struct tty *tp = pti->pt_tty; 953 954 return (tp); 955 } 956 957 /*ARGSUSED*/ 958 int 959 ptyioctl(dev, cmd, data, flag, p) 960 dev_t dev; 961 u_long cmd; 962 caddr_t data; 963 int flag; 964 struct proc *p; 965 { 966 struct pt_softc *pti = pt_softc[minor(dev)]; 967 struct tty *tp = pti->pt_tty; 968 const struct cdevsw *cdev; 969 u_char *cc = tp->t_cc; 970 int stop, error, sig; 971 972 cdev = cdevsw_lookup(dev); 973 /* 974 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG. 975 * ttywflush(tp) will hang if there are characters in the outq. 976 */ 977 if (cmd == TIOCEXT) { 978 /* 979 * When the EXTPROC bit is being toggled, we need 980 * to send an TIOCPKT_IOCTL if the packet driver 981 * is turned on. 982 */ 983 if (*(int *)data) { 984 if (pti->pt_flags & PF_PKT) { 985 pti->pt_send |= TIOCPKT_IOCTL; 986 ptcwakeup(tp, FREAD); 987 } 988 SET(tp->t_lflag, EXTPROC); 989 } else { 990 if (ISSET(tp->t_lflag, EXTPROC) && 991 (pti->pt_flags & PF_PKT)) { 992 pti->pt_send |= TIOCPKT_IOCTL; 993 ptcwakeup(tp, FREAD); 994 } 995 CLR(tp->t_lflag, EXTPROC); 996 } 997 return(0); 998 } 999 1000 if (cdev != NULL && cdev->d_open == ptcopen) 1001 switch (cmd) { 1002 1003 case TIOCGPGRP: 1004 /* 1005 * We avoid calling ttioctl on the controller since, 1006 * in that case, tp must be the controlling terminal. 1007 */ 1008 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0; 1009 return (0); 1010 1011 case TIOCPKT: 1012 if (*(int *)data) { 1013 if (pti->pt_flags & PF_UCNTL) 1014 return (EINVAL); 1015 pti->pt_flags |= PF_PKT; 1016 } else 1017 pti->pt_flags &= ~PF_PKT; 1018 return (0); 1019 1020 case TIOCUCNTL: 1021 if (*(int *)data) { 1022 if (pti->pt_flags & PF_PKT) 1023 return (EINVAL); 1024 pti->pt_flags |= PF_UCNTL; 1025 } else 1026 pti->pt_flags &= ~PF_UCNTL; 1027 return (0); 1028 1029 case TIOCREMOTE: 1030 if (*(int *)data) 1031 pti->pt_flags |= PF_REMOTE; 1032 else 1033 pti->pt_flags &= ~PF_REMOTE; 1034 TTY_LOCK(tp); 1035 ttyflush(tp, FREAD|FWRITE); 1036 TTY_UNLOCK(tp); 1037 return (0); 1038 1039 #ifdef COMPAT_OLDTTY 1040 case TIOCSETP: 1041 case TIOCSETN: 1042 #endif 1043 case TIOCSETD: 1044 case TIOCSETA: 1045 case TIOCSETAW: 1046 case TIOCSETAF: 1047 TTY_LOCK(tp); 1048 ndflush(&tp->t_outq, tp->t_outq.c_cc); 1049 TTY_UNLOCK(tp); 1050 break; 1051 1052 case TIOCSIG: 1053 sig = (int)(long)*(caddr_t *)data; 1054 if (sig <= 0 || sig >= NSIG) 1055 return (EINVAL); 1056 TTY_LOCK(tp); 1057 if (!ISSET(tp->t_lflag, NOFLSH)) 1058 ttyflush(tp, FREAD|FWRITE); 1059 if ((sig == SIGINFO) && 1060 (!ISSET(tp->t_lflag, NOKERNINFO))) 1061 ttyinfo(tp); 1062 TTY_UNLOCK(tp); 1063 pgsignal(tp->t_pgrp, sig, 1); 1064 return(0); 1065 } 1066 1067 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p); 1068 if (error == EPASSTHROUGH) 1069 error = ttioctl(tp, cmd, data, flag, p); 1070 if (error == EPASSTHROUGH) { 1071 if (pti->pt_flags & PF_UCNTL && 1072 (cmd & ~0xff) == UIOCCMD(0)) { 1073 if (cmd & 0xff) { 1074 pti->pt_ucntl = (u_char)cmd; 1075 ptcwakeup(tp, FREAD); 1076 } 1077 return (0); 1078 } 1079 } 1080 /* 1081 * If external processing and packet mode send ioctl packet. 1082 */ 1083 if (ISSET(tp->t_lflag, EXTPROC) && (pti->pt_flags & PF_PKT)) { 1084 switch(cmd) { 1085 case TIOCSETA: 1086 case TIOCSETAW: 1087 case TIOCSETAF: 1088 #ifdef COMPAT_OLDTTY 1089 case TIOCSETP: 1090 case TIOCSETN: 1091 case TIOCSETC: 1092 case TIOCSLTC: 1093 case TIOCLBIS: 1094 case TIOCLBIC: 1095 case TIOCLSET: 1096 #endif 1097 pti->pt_send |= TIOCPKT_IOCTL; 1098 ptcwakeup(tp, FREAD); 1099 default: 1100 break; 1101 } 1102 } 1103 stop = ISSET(tp->t_iflag, IXON) && CCEQ(cc[VSTOP], CTRL('s')) 1104 && CCEQ(cc[VSTART], CTRL('q')); 1105 if (pti->pt_flags & PF_NOSTOP) { 1106 if (stop) { 1107 pti->pt_send &= ~TIOCPKT_NOSTOP; 1108 pti->pt_send |= TIOCPKT_DOSTOP; 1109 pti->pt_flags &= ~PF_NOSTOP; 1110 ptcwakeup(tp, FREAD); 1111 } 1112 } else { 1113 if (!stop) { 1114 pti->pt_send &= ~TIOCPKT_DOSTOP; 1115 pti->pt_send |= TIOCPKT_NOSTOP; 1116 pti->pt_flags |= PF_NOSTOP; 1117 ptcwakeup(tp, FREAD); 1118 } 1119 } 1120 return (error); 1121 } 1122