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 --- 17 unchanged lines hidden (view full) --- 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: head/sys/kern/tty_pty.c 111742 2003-03-02 15:56:49Z des $ |
35 */ 36 37/* 38 * Pseudo-teletype Driver 39 * (Actually two drivers, requiring two entries in 'cdevsw') 40 */ 41#include "opt_compat.h" 42#include <sys/param.h> --- 88 unchanged lines hidden (view full) --- 131 132static char *names = "pqrsPQRS"; 133/* 134 * This function creates and initializes a pts/ptc pair 135 * 136 * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 137 * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 138 * |
139 * XXX: define and add mapping of upper minor bits to allow more |
140 * than 256 ptys. 141 */ 142static dev_t 143ptyinit(dev_t devc) 144{ 145 dev_t devs; 146 struct pt_ioctl *pt; 147 int n; --- 19 unchanged lines hidden (view full) --- 167 168/*ARGSUSED*/ 169static int 170ptsopen(dev, flag, devtype, td) 171 dev_t dev; 172 int flag, devtype; 173 struct thread *td; 174{ |
175 struct tty *tp; |
176 int error; 177 struct pt_ioctl *pti; 178 179 if (!dev->si_drv1) |
180 return(ENXIO); |
181 pti = dev->si_drv1; 182 tp = dev->si_tty; 183 if ((tp->t_state & TS_ISOPEN) == 0) { 184 ttychars(tp); /* Set up default chars */ 185 tp->t_iflag = TTYDEF_IFLAG; 186 tp->t_oflag = TTYDEF_OFLAG; 187 tp->t_lflag = TTYDEF_LFLAG; 188 tp->t_cflag = TTYDEF_CFLAG; --- 20 unchanged lines hidden (view full) --- 209} 210 211static int 212ptsclose(dev, flag, mode, td) 213 dev_t dev; 214 int flag, mode; 215 struct thread *td; 216{ |
217 struct tty *tp; |
218 int err; 219 220 tp = dev->si_tty; 221 err = (*linesw[tp->t_line].l_close)(tp, flag); 222 ptsstop(tp, FREAD|FWRITE); 223 (void) ttyclose(tp); 224 return (err); 225} 226 227static int 228ptsread(dev, uio, flag) 229 dev_t dev; 230 struct uio *uio; 231 int flag; 232{ 233 struct thread *td = curthread; 234 struct proc *p = td->td_proc; |
235 struct tty *tp = dev->si_tty; 236 struct pt_ioctl *pti = dev->si_drv1; |
237 struct pgrp *pg; 238 int error = 0; 239 240again: 241 if (pti->pt_flags & PF_REMOTE) { 242 while (isbackground(p, tp)) { 243 sx_slock(&proctree_lock); 244 PROC_LOCK(p); --- 46 unchanged lines hidden (view full) --- 291 * indirectly, when tty driver calls ptsstart. 292 */ 293static int 294ptswrite(dev, uio, flag) 295 dev_t dev; 296 struct uio *uio; 297 int flag; 298{ |
299 struct tty *tp; |
300 301 tp = dev->si_tty; 302 if (tp->t_oproc == 0) 303 return (EIO); 304 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 305} 306 307/* 308 * Start output on pseudo-tty. 309 * Wake up process selecting or sleeping for input from controlling tty. 310 */ 311static void 312ptsstart(tp) 313 struct tty *tp; 314{ |
315 struct pt_ioctl *pti = tp->t_dev->si_drv1; |
316 317 if (tp->t_state & TS_TTSTOP) 318 return; 319 if (pti->pt_flags & PF_STOPPED) { 320 pti->pt_flags &= ~PF_STOPPED; 321 pti->pt_send = TIOCPKT_START; 322 } 323 ptcwakeup(tp, FREAD); --- 17 unchanged lines hidden (view full) --- 341} 342 343static int 344ptcopen(dev, flag, devtype, td) 345 dev_t dev; 346 int flag, devtype; 347 struct thread *td; 348{ |
349 struct tty *tp; |
350 struct pt_ioctl *pti; 351 352 if (!dev->si_drv1) 353 ptyinit(dev); 354 if (!dev->si_drv1) |
355 return(ENXIO); |
356 tp = dev->si_tty; 357 if (tp->t_oproc) 358 return (EIO); 359 tp->t_timeout = -1; 360 tp->t_oproc = ptsstart; 361 tp->t_stop = ptsstop; 362 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 363 tp->t_lflag &= ~EXTPROC; --- 7 unchanged lines hidden (view full) --- 371 372static int 373ptcclose(dev, flags, fmt, td) 374 dev_t dev; 375 int flags; 376 int fmt; 377 struct thread *td; 378{ |
379 struct tty *tp; |
380 381 tp = dev->si_tty; 382 (void)(*linesw[tp->t_line].l_modem)(tp, 0); 383 384 /* 385 * XXX MDMBUF makes no sense for ptys but would inhibit the above 386 * l_modem(). CLOCAL makes sense but isn't supported. Special 387 * l_modem()s that ignore carrier drop make no sense for ptys but --- 12 unchanged lines hidden (view full) --- 400} 401 402static int 403ptcread(dev, uio, flag) 404 dev_t dev; 405 struct uio *uio; 406 int flag; 407{ |
408 struct tty *tp = dev->si_tty; |
409 struct pt_ioctl *pti = dev->si_drv1; 410 char buf[BUFSIZ]; 411 int error = 0, cc; 412 413 /* 414 * We want to block until the slave 415 * is open, and there's something to read; 416 * but if we lost the slave or we're NBIO, --- 40 unchanged lines hidden (view full) --- 457 error = uiomove(buf, cc, uio); 458 } 459 ttwwakeup(tp); 460 return (error); 461} 462 463static void 464ptsstop(tp, flush) |
465 struct tty *tp; |
466 int flush; 467{ 468 struct pt_ioctl *pti = tp->t_dev->si_drv1; 469 int flag; 470 471 /* note: FLUSHREAD and FLUSHWRITE already ok */ 472 if (flush == 0) { 473 flush = TIOCPKT_STOP; --- 11 unchanged lines hidden (view full) --- 485} 486 487static int 488ptcpoll(dev, events, td) 489 dev_t dev; 490 int events; 491 struct thread *td; 492{ |
493 struct tty *tp = dev->si_tty; |
494 struct pt_ioctl *pti = dev->si_drv1; 495 int revents = 0; 496 int s; 497 498 if ((tp->t_state & TS_CONNECTED) == 0) 499 return (seltrue(dev, events, td) | POLLHUP); 500 501 /* --- 6 unchanged lines hidden (view full) --- 508 ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) || 509 ((pti->pt_flags & PF_PKT) && pti->pt_send) || 510 ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) 511 revents |= events & (POLLIN | POLLRDNORM); 512 513 if (events & (POLLOUT | POLLWRNORM)) 514 if (tp->t_state & TS_ISOPEN && 515 ((pti->pt_flags & PF_REMOTE) ? |
516 (tp->t_canq.c_cc == 0) : |
517 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) || 518 (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) 519 revents |= events & (POLLOUT | POLLWRNORM); 520 521 if (events & POLLHUP) 522 if ((tp->t_state & TS_CARR_ON) == 0) 523 revents |= POLLHUP; 524 525 if (revents == 0) { 526 if (events & (POLLIN | POLLRDNORM)) 527 selrecord(td, &pti->pt_selr); 528 |
529 if (events & (POLLOUT | POLLWRNORM)) |
530 selrecord(td, &pti->pt_selw); 531 } 532 splx(s); 533 534 return (revents); 535} 536 537static int 538ptcwrite(dev, uio, flag) 539 dev_t dev; |
540 struct uio *uio; |
541 int flag; 542{ |
543 struct tty *tp = dev->si_tty; 544 u_char *cp = 0; 545 int cc = 0; |
546 u_char locbuf[BUFSIZ]; 547 int cnt = 0; 548 struct pt_ioctl *pti = dev->si_drv1; 549 int error = 0; 550 551again: 552 if ((tp->t_state&TS_ISOPEN) == 0) 553 goto block; --- 94 unchanged lines hidden (view full) --- 648static int 649ptyioctl(dev, cmd, data, flag, td) 650 dev_t dev; 651 u_long cmd; 652 caddr_t data; 653 int flag; 654 struct thread *td; 655{ |
656 struct tty *tp = dev->si_tty; 657 struct pt_ioctl *pti = dev->si_drv1; 658 u_char *cc = tp->t_cc; |
659 int stop, error; 660 661 if (devsw(dev)->d_open == ptcopen) { 662 switch (cmd) { 663 664 case TIOCGPGRP: 665 /* 666 * We avoid calling ttioctl on the controller since, --- 25 unchanged lines hidden (view full) --- 692 pti->pt_flags |= PF_REMOTE; 693 else 694 pti->pt_flags &= ~PF_REMOTE; 695 ttyflush(tp, FREAD|FWRITE); 696 return (0); 697 } 698 699 /* |
700 * The rest of the ioctls shouldn't be called until |
701 * the slave is open. 702 */ 703 if ((tp->t_state & TS_ISOPEN) == 0) 704 return (EAGAIN); 705 706 switch (cmd) { 707#ifdef COMPAT_43 708 case TIOCSETP: --- 164 unchanged lines hidden --- |