1 /* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 34 * $FreeBSD: src/sys/kern/tty_pty.c,v 1.74.2.4 2002/02/20 19:58:13 dillon Exp $ 35 * $DragonFly: src/sys/kern/tty_pty.c,v 1.21 2008/08/13 10:29:38 swildner Exp $ 36 */ 37 38 /* 39 * Pseudo-teletype Driver 40 * (Actually two drivers, requiring two dev_ops structures) 41 */ 42 #include "use_pty.h" /* XXX */ 43 #include "opt_compat.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 48 #include <sys/ioctl_compat.h> 49 #endif 50 #include <sys/proc.h> 51 #include <sys/priv.h> 52 #include <sys/tty.h> 53 #include <sys/conf.h> 54 #include <sys/fcntl.h> 55 #include <sys/poll.h> 56 #include <sys/kernel.h> 57 #include <sys/vnode.h> 58 #include <sys/signalvar.h> 59 #include <sys/malloc.h> 60 #include <sys/device.h> 61 #include <sys/thread2.h> 62 #include <vfs/devfs/devfs.h> 63 64 DEVFS_DECLARE_CLONE_BITMAP(pty); 65 DEVFS_DECLARE_CLONE_BITMAP(pts); 66 67 MALLOC_DEFINE(M_PTY, "ptys", "pty data structures"); 68 69 static void ptsstart (struct tty *tp); 70 static void ptsstop (struct tty *tp, int rw); 71 static void ptcwakeup (struct tty *tp, int flag); 72 static void ptyinit (int n); 73 74 static d_open_t ptsopen; 75 static d_close_t ptsclose; 76 static d_read_t ptsread; 77 static d_write_t ptswrite; 78 static d_ioctl_t ptyioctl; 79 static d_open_t ptcopen; 80 static d_close_t ptcclose; 81 static d_read_t ptcread; 82 static d_write_t ptcwrite; 83 static d_poll_t ptcpoll; 84 static d_clone_t ptyclone; 85 86 #define CDEV_MAJOR_S 5 87 static struct dev_ops pts_ops = { 88 { "pts", CDEV_MAJOR_S, D_TTY | D_KQFILTER }, 89 .d_open = ptsopen, 90 .d_close = ptsclose, 91 .d_read = ptsread, 92 .d_write = ptswrite, 93 .d_ioctl = ptyioctl, 94 .d_poll = ttypoll, 95 .d_kqfilter = ttykqfilter, 96 .d_revoke = ttyrevoke 97 }; 98 99 #define CDEV_MAJOR_C 6 100 static struct dev_ops ptc_ops = { 101 { "ptc", CDEV_MAJOR_C, D_TTY | D_KQFILTER | D_MASTER }, 102 .d_open = ptcopen, 103 .d_close = ptcclose, 104 .d_read = ptcread, 105 .d_write = ptcwrite, 106 .d_ioctl = ptyioctl, 107 .d_poll = ptcpoll, 108 .d_kqfilter = ttykqfilter, 109 .d_revoke = ttyrevoke 110 }; 111 112 #define BUFSIZ 100 /* Chunk size iomoved to/from user */ 113 114 struct pt_ioctl { 115 int pt_flags; 116 struct selinfo pt_selr, pt_selw; 117 u_char pt_send; 118 u_char pt_ucntl; 119 struct tty pt_tty; 120 cdev_t devs, devc; 121 struct prison *pt_prison; 122 short ref_count; 123 }; 124 125 #define PF_PKT 0x08 /* packet mode */ 126 #define PF_STOPPED 0x10 /* user told stopped */ 127 #define PF_REMOTE 0x20 /* remote and flow controlled input */ 128 #define PF_NOSTOP 0x40 129 #define PF_UCNTL 0x80 /* user control mode */ 130 131 /* 132 * This function creates and initializes a pts/ptc pair 133 * 134 * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 135 * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 136 * 137 * XXX: define and add mapping of upper minor bits to allow more 138 * than 256 ptys. 139 */ 140 static void 141 ptyinit(int n) 142 { 143 cdev_t devs, devc; 144 char *names = "pqrsPQRS"; 145 struct pt_ioctl *pt; 146 147 /* For now we only map the lower 8 bits of the minor */ 148 if (n & ~0xff) 149 return; 150 151 pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO); 152 pt->devs = devs = make_dev(&pts_ops, n, 153 0, 0, 0666, "tty%c%r", names[n / 32], n % 32); 154 pt->devc = devc = make_dev(&ptc_ops, n, 155 0, 0, 0666, "pty%c%r", names[n / 32], n % 32); 156 157 devs->si_drv1 = devc->si_drv1 = pt; 158 devs->si_tty = devc->si_tty = &pt->pt_tty; 159 pt->pt_tty.t_dev = devs; 160 ttyregister(&pt->pt_tty); 161 } 162 163 static int 164 ptyclone(struct dev_clone_args *ap) 165 { 166 int unit; 167 struct pt_ioctl *pt; 168 169 unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), 256); 170 171 if (unit < 0) 172 return 1; 173 174 pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO); 175 pt->ref_count++; 176 pt->devc = ap->a_dev = make_only_dev(&ptc_ops, unit, ap->a_cred->cr_ruid, 0, 0600, "ptm/%d", unit); 177 pt->devs = make_dev(&pts_ops, unit, ap->a_cred->cr_ruid, 0, 0600, "pts/%d", unit); 178 179 //reference_dev(pt->devc); 180 //reference_dev(pt->devs); 181 182 pt->devs->si_drv1 = pt->devc->si_drv1 = pt; 183 pt->devs->si_tty = pt->devc->si_tty = &pt->pt_tty; 184 pt->pt_tty.t_dev = pt->devs; 185 ttyregister(&pt->pt_tty); 186 187 return 0; 188 } 189 190 /*ARGSUSED*/ 191 static int 192 ptsopen(struct dev_open_args *ap) 193 { 194 cdev_t dev = ap->a_head.a_dev; 195 struct tty *tp; 196 int error; 197 #if 0 198 int minr; 199 cdev_t nextdev; 200 #endif 201 struct pt_ioctl *pti; 202 203 #if 0 204 minr = lminor(dev); 205 /* 206 * REMOVED gross hack for devfs. also note that makedev() 207 * no longer exists in this form and reference counting makes 208 * this a problem if we don't clean it out later. 209 */ 210 if (minr < 255) { 211 nextdev = make_sub_dev(dev, minr + 1); 212 if (!nextdev->si_drv1) { 213 ptyinit(minr + 1); 214 } 215 } 216 #endif 217 if (!dev->si_drv1) 218 ptyinit(minor(dev)); 219 if (!dev->si_drv1) 220 return(ENXIO); 221 pti = dev->si_drv1; 222 tp = dev->si_tty; 223 if ((tp->t_state & TS_ISOPEN) == 0) { 224 ttychars(tp); /* Set up default chars */ 225 tp->t_iflag = TTYDEF_IFLAG; 226 tp->t_oflag = TTYDEF_OFLAG; 227 tp->t_lflag = TTYDEF_LFLAG; 228 tp->t_cflag = TTYDEF_CFLAG; 229 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 230 } else if ((tp->t_state & TS_XCLUDE) && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) { 231 return (EBUSY); 232 } else if (pti->pt_prison != ap->a_cred->cr_prison) { 233 return (EBUSY); 234 } 235 if (tp->t_oproc) /* Ctrlr still around. */ 236 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 237 while ((tp->t_state & TS_CARR_ON) == 0) { 238 if (ap->a_oflags & FNONBLOCK) 239 break; 240 error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ptsopn", 0); 241 if (error) 242 return (error); 243 } 244 error = (*linesw[tp->t_line].l_open)(dev, tp); 245 if (error == 0) 246 ptcwakeup(tp, FREAD|FWRITE); 247 248 #if 0 249 /* unix98 pty stuff */ 250 if ((!error) && (!memcmp(dev->si_name, "pts/", 4))) { 251 ((struct pt_ioctl *)dev->si_drv1)->ref_count++; 252 //reference_dev(dev); 253 //reference_dev(((struct pt_ioctl *)dev->si_drv1)->devc); 254 //devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(pts), dev->si_uminor-300); 255 } 256 #endif 257 258 return (error); 259 } 260 261 static int 262 ptsclose(struct dev_close_args *ap) 263 { 264 cdev_t dev = ap->a_head.a_dev; 265 struct tty *tp; 266 int err; 267 #if 0 268 /* unix98 pty stuff */ 269 if (!memcmp(dev->si_name, "pts/", 4)) { 270 if (--((struct pt_ioctl *)dev->si_drv1)->ref_count == 0) { 271 kfree(dev->si_drv1, M_PTY); 272 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty), dev->si_uminor); 273 destroy_dev(dev); 274 } 275 } 276 #endif 277 tp = dev->si_tty; 278 err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag); 279 ptsstop(tp, FREAD|FWRITE); 280 (void) ttyclose(tp); 281 return (err); 282 } 283 284 static int 285 ptsread(struct dev_read_args *ap) 286 { 287 cdev_t dev = ap->a_head.a_dev; 288 struct proc *p = curproc; 289 struct tty *tp = dev->si_tty; 290 struct pt_ioctl *pti = dev->si_drv1; 291 struct lwp *lp; 292 293 int error = 0; 294 295 lp = curthread->td_lwp; 296 297 again: 298 if (pti->pt_flags & PF_REMOTE) { 299 while (isbackground(p, tp)) { 300 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) || 301 SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) || 302 p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) 303 return (EIO); 304 pgsignal(p->p_pgrp, SIGTTIN, 1); 305 error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0); 306 if (error) 307 return (error); 308 } 309 if (tp->t_canq.c_cc == 0) { 310 if (ap->a_ioflag & IO_NDELAY) 311 return (EWOULDBLOCK); 312 error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH, 313 "ptsin", 0); 314 if (error) 315 return (error); 316 goto again; 317 } 318 while (tp->t_canq.c_cc > 1 && ap->a_uio->uio_resid > 0) 319 if (ureadc(clist_getc(&tp->t_canq), ap->a_uio) < 0) { 320 error = EFAULT; 321 break; 322 } 323 if (tp->t_canq.c_cc == 1) 324 clist_getc(&tp->t_canq); 325 if (tp->t_canq.c_cc) 326 return (error); 327 } else 328 if (tp->t_oproc) 329 error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag); 330 ptcwakeup(tp, FWRITE); 331 return (error); 332 } 333 334 /* 335 * Write to pseudo-tty. 336 * Wakeups of controlling tty will happen 337 * indirectly, when tty driver calls ptsstart. 338 */ 339 static int 340 ptswrite(struct dev_write_args *ap) 341 { 342 cdev_t dev = ap->a_head.a_dev; 343 struct tty *tp; 344 345 tp = dev->si_tty; 346 if (tp->t_oproc == 0) 347 return (EIO); 348 return ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag)); 349 } 350 351 /* 352 * Start output on pseudo-tty. 353 * Wake up process selecting or sleeping for input from controlling tty. 354 */ 355 static void 356 ptsstart(struct tty *tp) 357 { 358 struct pt_ioctl *pti = tp->t_dev->si_drv1; 359 360 if (tp->t_state & TS_TTSTOP) 361 return; 362 if (pti->pt_flags & PF_STOPPED) { 363 pti->pt_flags &= ~PF_STOPPED; 364 pti->pt_send = TIOCPKT_START; 365 } 366 ptcwakeup(tp, FREAD); 367 } 368 369 static void 370 ptcwakeup(struct tty *tp, int flag) 371 { 372 struct pt_ioctl *pti = tp->t_dev->si_drv1; 373 374 if (flag & FREAD) { 375 selwakeup(&pti->pt_selr); 376 wakeup(TSA_PTC_READ(tp)); 377 } 378 if (flag & FWRITE) { 379 selwakeup(&pti->pt_selw); 380 wakeup(TSA_PTC_WRITE(tp)); 381 } 382 } 383 384 static int 385 ptcopen(struct dev_open_args *ap) 386 { 387 cdev_t dev = ap->a_head.a_dev; 388 struct tty *tp; 389 struct pt_ioctl *pti; 390 391 if (!dev->si_drv1) 392 ptyinit(minor(dev)); 393 if (!dev->si_drv1) 394 return(ENXIO); 395 tp = dev->si_tty; 396 if (tp->t_oproc) 397 return (EIO); 398 tp->t_oproc = ptsstart; 399 tp->t_stop = ptsstop; 400 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 401 tp->t_lflag &= ~EXTPROC; 402 pti = dev->si_drv1; 403 pti->pt_prison = ap->a_cred->cr_prison; 404 pti->pt_flags = 0; 405 pti->pt_send = 0; 406 pti->pt_ucntl = 0; 407 pti->devs->si_uid = ap->a_cred->cr_uid; 408 return (0); 409 } 410 411 static int 412 ptcclose(struct dev_close_args *ap) 413 { 414 cdev_t dev = ap->a_head.a_dev; 415 struct tty *tp; 416 417 tp = dev->si_tty; 418 (void)(*linesw[tp->t_line].l_modem)(tp, 0); 419 420 /* 421 * XXX MDMBUF makes no sense for ptys but would inhibit the above 422 * l_modem(). CLOCAL makes sense but isn't supported. Special 423 * l_modem()s that ignore carrier drop make no sense for ptys but 424 * may be in use because other parts of the line discipline make 425 * sense for ptys. Recover by doing everything that a normal 426 * ttymodem() would have done except for sending a SIGHUP. 427 */ 428 if (tp->t_state & TS_ISOPEN) { 429 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED); 430 tp->t_state |= TS_ZOMBIE; 431 ttyflush(tp, FREAD | FWRITE); 432 tp->t_dev->si_uid = 0; 433 } 434 435 tp->t_oproc = 0; /* mark closed */ 436 #if 0 437 if (!memcmp(dev->si_name, "ptm/", 4)) { 438 ((struct pt_ioctl *)dev->si_drv1)->devc = NULL; 439 if (--((struct pt_ioctl *)dev->si_drv1)->ref_count == 0) { 440 kfree(dev->si_drv1, M_PTY); 441 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty), dev->si_uminor); 442 } 443 //release_dev(dev); 444 //release_dev(((struct pt_ioctl *)dev->si_drv1)->devs); 445 } 446 #endif 447 return (0); 448 } 449 450 static int 451 ptcread(struct dev_read_args *ap) 452 { 453 cdev_t dev = ap->a_head.a_dev; 454 struct tty *tp = dev->si_tty; 455 struct pt_ioctl *pti = dev->si_drv1; 456 char buf[BUFSIZ]; 457 int error = 0, cc; 458 459 /* 460 * We want to block until the slave 461 * is open, and there's something to read; 462 * but if we lost the slave or we're NBIO, 463 * then return the appropriate error instead. 464 */ 465 for (;;) { 466 if (tp->t_state&TS_ISOPEN) { 467 if (pti->pt_flags&PF_PKT && pti->pt_send) { 468 error = ureadc((int)pti->pt_send, ap->a_uio); 469 if (error) 470 return (error); 471 if (pti->pt_send & TIOCPKT_IOCTL) { 472 cc = min(ap->a_uio->uio_resid, 473 sizeof(tp->t_termios)); 474 uiomove((caddr_t)&tp->t_termios, cc, 475 ap->a_uio); 476 } 477 pti->pt_send = 0; 478 return (0); 479 } 480 if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) { 481 error = ureadc((int)pti->pt_ucntl, ap->a_uio); 482 if (error) 483 return (error); 484 pti->pt_ucntl = 0; 485 return (0); 486 } 487 if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) 488 break; 489 } 490 if ((tp->t_state & TS_CONNECTED) == 0) 491 return (0); /* EOF */ 492 if (ap->a_ioflag & IO_NDELAY) 493 return (EWOULDBLOCK); 494 error = tsleep(TSA_PTC_READ(tp), PCATCH, "ptcin", 0); 495 if (error) 496 return (error); 497 } 498 if (pti->pt_flags & (PF_PKT|PF_UCNTL)) 499 error = ureadc(0, ap->a_uio); 500 while (ap->a_uio->uio_resid > 0 && error == 0) { 501 cc = q_to_b(&tp->t_outq, buf, min(ap->a_uio->uio_resid, BUFSIZ)); 502 if (cc <= 0) 503 break; 504 error = uiomove(buf, cc, ap->a_uio); 505 } 506 ttwwakeup(tp); 507 return (error); 508 } 509 510 static void 511 ptsstop(struct tty *tp, int flush) 512 { 513 struct pt_ioctl *pti = tp->t_dev->si_drv1; 514 int flag; 515 516 /* note: FLUSHREAD and FLUSHWRITE already ok */ 517 if (flush == 0) { 518 flush = TIOCPKT_STOP; 519 pti->pt_flags |= PF_STOPPED; 520 } else 521 pti->pt_flags &= ~PF_STOPPED; 522 pti->pt_send |= flush; 523 /* change of perspective */ 524 flag = 0; 525 if (flush & FREAD) 526 flag |= FWRITE; 527 if (flush & FWRITE) 528 flag |= FREAD; 529 ptcwakeup(tp, flag); 530 } 531 532 static int 533 ptcpoll(struct dev_poll_args *ap) 534 { 535 cdev_t dev = ap->a_head.a_dev; 536 struct tty *tp = dev->si_tty; 537 struct pt_ioctl *pti = dev->si_drv1; 538 int revents = 0; 539 540 if ((tp->t_state & TS_CONNECTED) == 0) { 541 ap->a_events = seltrue(dev, ap->a_events) | POLLHUP; 542 return(0); 543 } 544 545 /* 546 * Need to block timeouts (ttrstart). 547 */ 548 crit_enter(); 549 550 if (ap->a_events & (POLLIN | POLLRDNORM)) 551 if ((tp->t_state & TS_ISOPEN) && 552 ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) || 553 ((pti->pt_flags & PF_PKT) && pti->pt_send) || 554 ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) 555 revents |= ap->a_events & (POLLIN | POLLRDNORM); 556 557 if (ap->a_events & (POLLOUT | POLLWRNORM)) 558 if (tp->t_state & TS_ISOPEN && 559 ((pti->pt_flags & PF_REMOTE) ? 560 (tp->t_canq.c_cc == 0) : 561 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) || 562 (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) 563 revents |= ap->a_events & (POLLOUT | POLLWRNORM); 564 565 if (ap->a_events & POLLHUP) 566 if ((tp->t_state & TS_CARR_ON) == 0) 567 revents |= POLLHUP; 568 569 if (revents == 0) { 570 if (ap->a_events & (POLLIN | POLLRDNORM)) 571 selrecord(curthread, &pti->pt_selr); 572 573 if (ap->a_events & (POLLOUT | POLLWRNORM)) 574 selrecord(curthread, &pti->pt_selw); 575 } 576 crit_exit(); 577 578 ap->a_events = revents; 579 return (0); 580 } 581 582 static int 583 ptcwrite(struct dev_write_args *ap) 584 { 585 cdev_t dev = ap->a_head.a_dev; 586 struct tty *tp = dev->si_tty; 587 u_char *cp = 0; 588 int cc = 0; 589 u_char locbuf[BUFSIZ]; 590 int cnt = 0; 591 struct pt_ioctl *pti = dev->si_drv1; 592 int error = 0; 593 594 again: 595 if ((tp->t_state&TS_ISOPEN) == 0) 596 goto block; 597 if (pti->pt_flags & PF_REMOTE) { 598 if (tp->t_canq.c_cc) 599 goto block; 600 while ((ap->a_uio->uio_resid > 0 || cc > 0) && 601 tp->t_canq.c_cc < TTYHOG - 1) { 602 if (cc == 0) { 603 cc = min(ap->a_uio->uio_resid, BUFSIZ); 604 cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc); 605 cp = locbuf; 606 error = uiomove((caddr_t)cp, cc, ap->a_uio); 607 if (error) 608 return (error); 609 /* check again for safety */ 610 if ((tp->t_state & TS_ISOPEN) == 0) { 611 /* adjust as usual */ 612 ap->a_uio->uio_resid += cc; 613 return (EIO); 614 } 615 } 616 if (cc > 0) { 617 cc = b_to_q((char *)cp, cc, &tp->t_canq); 618 /* 619 * XXX we don't guarantee that the canq size 620 * is >= TTYHOG, so the above b_to_q() may 621 * leave some bytes uncopied. However, space 622 * is guaranteed for the null terminator if 623 * we don't fail here since (TTYHOG - 1) is 624 * not a multiple of CBSIZE. 625 */ 626 if (cc > 0) 627 break; 628 } 629 } 630 /* adjust for data copied in but not written */ 631 ap->a_uio->uio_resid += cc; 632 clist_putc(0, &tp->t_canq); 633 ttwakeup(tp); 634 wakeup(TSA_PTS_READ(tp)); 635 return (0); 636 } 637 while (ap->a_uio->uio_resid > 0 || cc > 0) { 638 if (cc == 0) { 639 cc = min(ap->a_uio->uio_resid, BUFSIZ); 640 cp = locbuf; 641 error = uiomove((caddr_t)cp, cc, ap->a_uio); 642 if (error) 643 return (error); 644 /* check again for safety */ 645 if ((tp->t_state & TS_ISOPEN) == 0) { 646 /* adjust for data copied in but not written */ 647 ap->a_uio->uio_resid += cc; 648 return (EIO); 649 } 650 } 651 while (cc > 0) { 652 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 && 653 (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) { 654 wakeup(TSA_HUP_OR_INPUT(tp)); 655 goto block; 656 } 657 (*linesw[tp->t_line].l_rint)(*cp++, tp); 658 cnt++; 659 cc--; 660 } 661 cc = 0; 662 } 663 return (0); 664 block: 665 /* 666 * Come here to wait for slave to open, for space 667 * in outq, or space in rawq, or an empty canq. 668 */ 669 if ((tp->t_state & TS_CONNECTED) == 0) { 670 /* adjust for data copied in but not written */ 671 ap->a_uio->uio_resid += cc; 672 return (EIO); 673 } 674 if (ap->a_ioflag & IO_NDELAY) { 675 /* adjust for data copied in but not written */ 676 ap->a_uio->uio_resid += cc; 677 if (cnt == 0) 678 return (EWOULDBLOCK); 679 return (0); 680 } 681 error = tsleep(TSA_PTC_WRITE(tp), PCATCH, "ptcout", 0); 682 if (error) { 683 /* adjust for data copied in but not written */ 684 ap->a_uio->uio_resid += cc; 685 return (error); 686 } 687 goto again; 688 } 689 690 /*ARGSUSED*/ 691 static int 692 ptyioctl(struct dev_ioctl_args *ap) 693 { 694 cdev_t dev = ap->a_head.a_dev; 695 struct tty *tp = dev->si_tty; 696 struct pt_ioctl *pti = dev->si_drv1; 697 u_char *cc = tp->t_cc; 698 int stop, error; 699 700 if (dev_dflags(dev) & D_MASTER) { 701 switch (ap->a_cmd) { 702 703 case TIOCGPGRP: 704 /* 705 * We avoid calling ttioctl on the controller since, 706 * in that case, tp must be the controlling terminal. 707 */ 708 *(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0; 709 return (0); 710 711 case TIOCPKT: 712 if (*(int *)ap->a_data) { 713 if (pti->pt_flags & PF_UCNTL) 714 return (EINVAL); 715 pti->pt_flags |= PF_PKT; 716 } else 717 pti->pt_flags &= ~PF_PKT; 718 return (0); 719 720 case TIOCUCNTL: 721 if (*(int *)ap->a_data) { 722 if (pti->pt_flags & PF_PKT) 723 return (EINVAL); 724 pti->pt_flags |= PF_UCNTL; 725 } else 726 pti->pt_flags &= ~PF_UCNTL; 727 return (0); 728 729 case TIOCREMOTE: 730 if (*(int *)ap->a_data) 731 pti->pt_flags |= PF_REMOTE; 732 else 733 pti->pt_flags &= ~PF_REMOTE; 734 ttyflush(tp, FREAD|FWRITE); 735 return (0); 736 } 737 738 /* 739 * The rest of the ioctls shouldn't be called until 740 * the slave is open. 741 */ 742 if ((tp->t_state & TS_ISOPEN) == 0) 743 return (EAGAIN); 744 745 switch (ap->a_cmd) { 746 #ifdef COMPAT_43 747 case TIOCSETP: 748 case TIOCSETN: 749 #endif 750 case TIOCSETD: 751 case TIOCSETA: 752 case TIOCSETAW: 753 case TIOCSETAF: 754 /* 755 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG. 756 * ttywflush(tp) will hang if there are characters in 757 * the outq. 758 */ 759 ndflush(&tp->t_outq, tp->t_outq.c_cc); 760 break; 761 762 case TIOCSIG: 763 if (*(unsigned int *)ap->a_data >= NSIG || 764 *(unsigned int *)ap->a_data == 0) 765 return(EINVAL); 766 if ((tp->t_lflag&NOFLSH) == 0) 767 ttyflush(tp, FREAD|FWRITE); 768 pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1); 769 if ((*(unsigned int *)ap->a_data == SIGINFO) && 770 ((tp->t_lflag&NOKERNINFO) == 0)) 771 ttyinfo(tp); 772 return(0); 773 } 774 } 775 if (ap->a_cmd == TIOCEXT) { 776 /* 777 * When the EXTPROC bit is being toggled, we need 778 * to send an TIOCPKT_IOCTL if the packet driver 779 * is turned on. 780 */ 781 if (*(int *)ap->a_data) { 782 if (pti->pt_flags & PF_PKT) { 783 pti->pt_send |= TIOCPKT_IOCTL; 784 ptcwakeup(tp, FREAD); 785 } 786 tp->t_lflag |= EXTPROC; 787 } else { 788 if ((tp->t_lflag & EXTPROC) && 789 (pti->pt_flags & PF_PKT)) { 790 pti->pt_send |= TIOCPKT_IOCTL; 791 ptcwakeup(tp, FREAD); 792 } 793 tp->t_lflag &= ~EXTPROC; 794 } 795 return(0); 796 } 797 error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data, 798 ap->a_fflag, ap->a_cred); 799 if (error == ENOIOCTL) 800 error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag); 801 if (error == ENOIOCTL) { 802 if (pti->pt_flags & PF_UCNTL && 803 (ap->a_cmd & ~0xff) == UIOCCMD(0)) { 804 if (ap->a_cmd & 0xff) { 805 pti->pt_ucntl = (u_char)ap->a_cmd; 806 ptcwakeup(tp, FREAD); 807 } 808 return (0); 809 } 810 error = ENOTTY; 811 } 812 /* 813 * If external processing and packet mode send ioctl packet. 814 */ 815 if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) { 816 switch(ap->a_cmd) { 817 case TIOCSETA: 818 case TIOCSETAW: 819 case TIOCSETAF: 820 #ifdef COMPAT_43 821 case TIOCSETP: 822 case TIOCSETN: 823 #endif 824 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 825 case TIOCSETC: 826 case TIOCSLTC: 827 case TIOCLBIS: 828 case TIOCLBIC: 829 case TIOCLSET: 830 #endif 831 pti->pt_send |= TIOCPKT_IOCTL; 832 ptcwakeup(tp, FREAD); 833 default: 834 break; 835 } 836 } 837 stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s')) 838 && CCEQ(cc[VSTART], CTRL('q')); 839 if (pti->pt_flags & PF_NOSTOP) { 840 if (stop) { 841 pti->pt_send &= ~TIOCPKT_NOSTOP; 842 pti->pt_send |= TIOCPKT_DOSTOP; 843 pti->pt_flags &= ~PF_NOSTOP; 844 ptcwakeup(tp, FREAD); 845 } 846 } else { 847 if (!stop) { 848 pti->pt_send &= ~TIOCPKT_DOSTOP; 849 pti->pt_send |= TIOCPKT_NOSTOP; 850 pti->pt_flags |= PF_NOSTOP; 851 ptcwakeup(tp, FREAD); 852 } 853 } 854 return (error); 855 } 856 857 858 static void ptc_drvinit (void *unused); 859 860 static void 861 ptc_drvinit(void *unused) 862 { 863 int i; 864 dev_ops_add(&pts_ops, 0, 0); 865 dev_ops_add(&ptc_ops, 0, 0); 866 867 devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(pty)); 868 devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(pts)); 869 870 #if 0 871 /* Unix98 pty stuff, leave out for now */ 872 make_dev(&ptc_ops, 0, 0, 0, 0666, "ptmx"); 873 devfs_clone_handler_add("ptmx", ptyclone); 874 #endif 875 for (i = 0; i < 256; i++) { 876 ptyinit(i); 877 } 878 } 879 880 SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL) 881