pty.c (130259) | pty.c (130262) |
---|---|
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 --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 30 */ 31 32#include <sys/cdefs.h> | 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 --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/kern/tty_pty.c 130259 2004-06-09 09:09:54Z phk $"); | 33__FBSDID("$FreeBSD: head/sys/kern/tty_pty.c 130262 2004-06-09 10:16:14Z phk $"); |
34 35/* 36 * Pseudo-teletype Driver 37 * (Actually two drivers, requiring two entries in 'cdevsw') 38 */ 39#include "opt_compat.h" 40#include "opt_tty.h" 41#include <sys/param.h> --- 114 unchanged lines hidden (view full) --- 156 devs->si_drv1 = devc->si_drv1 = pt; 157 devs->si_tty = devc->si_tty = pt->pt_tty; 158 pt->pt_tty->t_dev = devs; 159 return (devc); 160} 161 162/*ARGSUSED*/ 163static int | 34 35/* 36 * Pseudo-teletype Driver 37 * (Actually two drivers, requiring two entries in 'cdevsw') 38 */ 39#include "opt_compat.h" 40#include "opt_tty.h" 41#include <sys/param.h> --- 114 unchanged lines hidden (view full) --- 156 devs->si_drv1 = devc->si_drv1 = pt; 157 devs->si_tty = devc->si_tty = pt->pt_tty; 158 pt->pt_tty->t_dev = devs; 159 return (devc); 160} 161 162/*ARGSUSED*/ 163static int |
164ptsopen(dev, flag, devtype, td) 165 dev_t dev; 166 int flag, devtype; 167 struct thread *td; | 164ptsopen(dev_t dev, int flag, int devtype, struct thread *td) |
168{ 169 struct tty *tp; 170 int error; 171 struct pt_ioctl *pti; 172 173 if (!dev->si_drv1) 174 return(ENXIO); 175 pti = dev->si_drv1; --- 21 unchanged lines hidden (view full) --- 197 } 198 error = ttyld_open(tp, dev); 199 if (error == 0) 200 ptcwakeup(tp, FREAD|FWRITE); 201 return (error); 202} 203 204static int | 165{ 166 struct tty *tp; 167 int error; 168 struct pt_ioctl *pti; 169 170 if (!dev->si_drv1) 171 return(ENXIO); 172 pti = dev->si_drv1; --- 21 unchanged lines hidden (view full) --- 194 } 195 error = ttyld_open(tp, dev); 196 if (error == 0) 197 ptcwakeup(tp, FREAD|FWRITE); 198 return (error); 199} 200 201static int |
205ptsclose(dev, flag, mode, td) 206 dev_t dev; 207 int flag, mode; 208 struct thread *td; | 202ptsclose(dev_t dev, int flag, int mode, struct thread *td) |
209{ 210 struct tty *tp; 211 int err; 212 213 tp = dev->si_tty; 214 err = ttyld_close(tp, flag); 215 (void) ttyclose(tp); 216 return (err); 217} 218 219static int | 203{ 204 struct tty *tp; 205 int err; 206 207 tp = dev->si_tty; 208 err = ttyld_close(tp, flag); 209 (void) ttyclose(tp); 210 return (err); 211} 212 213static int |
220ptsread(dev, uio, flag) 221 dev_t dev; 222 struct uio *uio; 223 int flag; | 214ptsread(dev_t dev, struct uio *uio, int flag) |
224{ 225 struct thread *td = curthread; 226 struct proc *p = td->td_proc; 227 struct tty *tp = dev->si_tty; 228 struct pt_ioctl *pti = dev->si_drv1; 229 struct pgrp *pg; 230 int error = 0; 231 --- 46 unchanged lines hidden (view full) --- 278} 279 280/* 281 * Write to pseudo-tty. 282 * Wakeups of controlling tty will happen 283 * indirectly, when tty driver calls ptsstart. 284 */ 285static int | 215{ 216 struct thread *td = curthread; 217 struct proc *p = td->td_proc; 218 struct tty *tp = dev->si_tty; 219 struct pt_ioctl *pti = dev->si_drv1; 220 struct pgrp *pg; 221 int error = 0; 222 --- 46 unchanged lines hidden (view full) --- 269} 270 271/* 272 * Write to pseudo-tty. 273 * Wakeups of controlling tty will happen 274 * indirectly, when tty driver calls ptsstart. 275 */ 276static int |
286ptswrite(dev, uio, flag) 287 dev_t dev; 288 struct uio *uio; 289 int flag; | 277ptswrite(dev_t dev, struct uio *uio, int flag) |
290{ 291 struct tty *tp; 292 293 tp = dev->si_tty; 294 if (tp->t_oproc == 0) 295 return (EIO); 296 return (ttyld_write(tp, uio, flag)); 297} 298 299/* 300 * Start output on pseudo-tty. 301 * Wake up process selecting or sleeping for input from controlling tty. 302 */ 303static void | 278{ 279 struct tty *tp; 280 281 tp = dev->si_tty; 282 if (tp->t_oproc == 0) 283 return (EIO); 284 return (ttyld_write(tp, uio, flag)); 285} 286 287/* 288 * Start output on pseudo-tty. 289 * Wake up process selecting or sleeping for input from controlling tty. 290 */ 291static void |
304ptsstart(tp) 305 struct tty *tp; | 292ptsstart(struct tty *tp) |
306{ 307 struct pt_ioctl *pti = tp->t_dev->si_drv1; 308 309 if (tp->t_state & TS_TTSTOP) 310 return; 311 if (pti->pt_flags & PF_STOPPED) { 312 pti->pt_flags &= ~PF_STOPPED; 313 pti->pt_send = TIOCPKT_START; 314 } 315 ptcwakeup(tp, FREAD); 316} 317 318static void | 293{ 294 struct pt_ioctl *pti = tp->t_dev->si_drv1; 295 296 if (tp->t_state & TS_TTSTOP) 297 return; 298 if (pti->pt_flags & PF_STOPPED) { 299 pti->pt_flags &= ~PF_STOPPED; 300 pti->pt_send = TIOCPKT_START; 301 } 302 ptcwakeup(tp, FREAD); 303} 304 305static void |
319ptcwakeup(tp, flag) 320 struct tty *tp; 321 int flag; | 306ptcwakeup(struct tty *tp, int flag) |
322{ 323 struct pt_ioctl *pti = tp->t_dev->si_drv1; 324 325 if (flag & FREAD) { 326 selwakeuppri(&pti->pt_selr, TTIPRI); 327 wakeup(TSA_PTC_READ(tp)); 328 } 329 if (flag & FWRITE) { 330 selwakeuppri(&pti->pt_selw, TTOPRI); 331 wakeup(TSA_PTC_WRITE(tp)); 332 } 333} 334 335static int | 307{ 308 struct pt_ioctl *pti = tp->t_dev->si_drv1; 309 310 if (flag & FREAD) { 311 selwakeuppri(&pti->pt_selr, TTIPRI); 312 wakeup(TSA_PTC_READ(tp)); 313 } 314 if (flag & FWRITE) { 315 selwakeuppri(&pti->pt_selw, TTOPRI); 316 wakeup(TSA_PTC_WRITE(tp)); 317 } 318} 319 320static int |
336ptcopen(dev, flag, devtype, td) 337 dev_t dev; 338 int flag, devtype; 339 struct thread *td; | 321ptcopen(dev_t dev, int flag, int devtype, struct thread *td) |
340{ 341 struct tty *tp; 342 struct pt_ioctl *pti; 343 344 if (!dev->si_drv1) 345 ptyinit(dev); 346 if (!dev->si_drv1) 347 return(ENXIO); --- 9 unchanged lines hidden (view full) --- 357 pti->pt_prison = td->td_ucred->cr_prison; 358 pti->pt_flags = 0; 359 pti->pt_send = 0; 360 pti->pt_ucntl = 0; 361 return (0); 362} 363 364static int | 322{ 323 struct tty *tp; 324 struct pt_ioctl *pti; 325 326 if (!dev->si_drv1) 327 ptyinit(dev); 328 if (!dev->si_drv1) 329 return(ENXIO); --- 9 unchanged lines hidden (view full) --- 339 pti->pt_prison = td->td_ucred->cr_prison; 340 pti->pt_flags = 0; 341 pti->pt_send = 0; 342 pti->pt_ucntl = 0; 343 return (0); 344} 345 346static int |
365ptcclose(dev, flags, fmt, td) 366 dev_t dev; 367 int flags; 368 int fmt; 369 struct thread *td; | 347ptcclose(dev_t dev, int flags, int fmt, struct thread *td) |
370{ 371 struct tty *tp; 372 373 tp = dev->si_tty; 374 (void)ttyld_modem(tp, 0); 375 376 /* 377 * XXX MDMBUF makes no sense for ptys but would inhibit the above --- 9 unchanged lines hidden (view full) --- 387 ttyflush(tp, FREAD | FWRITE); 388 } 389 390 tp->t_oproc = 0; /* mark closed */ 391 return (0); 392} 393 394static int | 348{ 349 struct tty *tp; 350 351 tp = dev->si_tty; 352 (void)ttyld_modem(tp, 0); 353 354 /* 355 * XXX MDMBUF makes no sense for ptys but would inhibit the above --- 9 unchanged lines hidden (view full) --- 365 ttyflush(tp, FREAD | FWRITE); 366 } 367 368 tp->t_oproc = 0; /* mark closed */ 369 return (0); 370} 371 372static int |
395ptcread(dev, uio, flag) 396 dev_t dev; 397 struct uio *uio; 398 int flag; | 373ptcread(dev_t dev, struct uio *uio, int flag) |
399{ 400 struct tty *tp = dev->si_tty; 401 struct pt_ioctl *pti = dev->si_drv1; 402 char buf[BUFSIZ]; 403 int error = 0, cc; 404 405 /* 406 * We want to block until the slave --- 41 unchanged lines hidden (view full) --- 448 break; 449 error = uiomove(buf, cc, uio); 450 } 451 ttwwakeup(tp); 452 return (error); 453} 454 455static void | 374{ 375 struct tty *tp = dev->si_tty; 376 struct pt_ioctl *pti = dev->si_drv1; 377 char buf[BUFSIZ]; 378 int error = 0, cc; 379 380 /* 381 * We want to block until the slave --- 41 unchanged lines hidden (view full) --- 423 break; 424 error = uiomove(buf, cc, uio); 425 } 426 ttwwakeup(tp); 427 return (error); 428} 429 430static void |
456ptsstop(tp, flush) 457 struct tty *tp; 458 int flush; | 431ptsstop(struct tty *tp, int flush) |
459{ 460 struct pt_ioctl *pti = tp->t_dev->si_drv1; 461 int flag; 462 463 /* note: FLUSHREAD and FLUSHWRITE already ok */ 464 if (flush == 0) { 465 flush = TIOCPKT_STOP; 466 pti->pt_flags |= PF_STOPPED; --- 5 unchanged lines hidden (view full) --- 472 if (flush & FREAD) 473 flag |= FWRITE; 474 if (flush & FWRITE) 475 flag |= FREAD; 476 ptcwakeup(tp, flag); 477} 478 479static int | 432{ 433 struct pt_ioctl *pti = tp->t_dev->si_drv1; 434 int flag; 435 436 /* note: FLUSHREAD and FLUSHWRITE already ok */ 437 if (flush == 0) { 438 flush = TIOCPKT_STOP; 439 pti->pt_flags |= PF_STOPPED; --- 5 unchanged lines hidden (view full) --- 445 if (flush & FREAD) 446 flag |= FWRITE; 447 if (flush & FWRITE) 448 flag |= FREAD; 449 ptcwakeup(tp, flag); 450} 451 452static int |
480ptcpoll(dev, events, td) 481 dev_t dev; 482 int events; 483 struct thread *td; | 453ptcpoll(dev_t dev, int events, struct thread *td) |
484{ 485 struct tty *tp = dev->si_tty; 486 struct pt_ioctl *pti = dev->si_drv1; 487 int revents = 0; 488 int s; 489 490 if ((tp->t_state & TS_CONNECTED) == 0) 491 return (events & --- 31 unchanged lines hidden (view full) --- 523 selrecord(td, &pti->pt_selw); 524 } 525 splx(s); 526 527 return (revents); 528} 529 530static int | 454{ 455 struct tty *tp = dev->si_tty; 456 struct pt_ioctl *pti = dev->si_drv1; 457 int revents = 0; 458 int s; 459 460 if ((tp->t_state & TS_CONNECTED) == 0) 461 return (events & --- 31 unchanged lines hidden (view full) --- 493 selrecord(td, &pti->pt_selw); 494 } 495 splx(s); 496 497 return (revents); 498} 499 500static int |
531ptcwrite(dev, uio, flag) 532 dev_t dev; 533 struct uio *uio; 534 int flag; | 501ptcwrite(dev_t dev, struct uio *uio, int flag) |
535{ 536 struct tty *tp = dev->si_tty; 537 u_char *cp = 0; 538 int cc = 0; 539 u_char locbuf[BUFSIZ]; 540 int cnt = 0; 541 struct pt_ioctl *pti = dev->si_drv1; 542 int error = 0; --- 91 unchanged lines hidden (view full) --- 634 uio->uio_resid += cc; 635 return (error); 636 } 637 goto again; 638} 639 640/*ARGSUSED*/ 641static int | 502{ 503 struct tty *tp = dev->si_tty; 504 u_char *cp = 0; 505 int cc = 0; 506 u_char locbuf[BUFSIZ]; 507 int cnt = 0; 508 struct pt_ioctl *pti = dev->si_drv1; 509 int error = 0; --- 91 unchanged lines hidden (view full) --- 601 uio->uio_resid += cc; 602 return (error); 603 } 604 goto again; 605} 606 607/*ARGSUSED*/ 608static int |
642ptyioctl(dev, cmd, data, flag, td) 643 dev_t dev; 644 u_long cmd; 645 caddr_t data; 646 int flag; 647 struct thread *td; | 609ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) |
648{ 649 struct tty *tp = dev->si_tty; 650 struct pt_ioctl *pti = dev->si_drv1; 651 u_char *cc = tp->t_cc; 652 int stop, error; 653 654 if (devsw(dev)->d_open == ptcopen) { 655 switch (cmd) { --- 149 unchanged lines hidden (view full) --- 805 pti->pt_send |= TIOCPKT_NOSTOP; 806 pti->pt_flags |= PF_NOSTOP; 807 ptcwakeup(tp, FREAD); 808 } 809 } 810 return (error); 811} 812 | 610{ 611 struct tty *tp = dev->si_tty; 612 struct pt_ioctl *pti = dev->si_drv1; 613 u_char *cc = tp->t_cc; 614 int stop, error; 615 616 if (devsw(dev)->d_open == ptcopen) { 617 switch (cmd) { --- 149 unchanged lines hidden (view full) --- 767 pti->pt_send |= TIOCPKT_NOSTOP; 768 pti->pt_flags |= PF_NOSTOP; 769 ptcwakeup(tp, FREAD); 770 } 771 } 772 return (error); 773} 774 |
813 814static void ptc_drvinit(void *unused); 815 816static void pty_clone(void *arg, char *name, int namelen, dev_t *dev); 817 | |
818static void | 775static void |
819pty_clone(arg, name, namelen, dev) 820 void *arg; 821 char *name; 822 int namelen; 823 dev_t *dev; | 776pty_clone(void *arg, char *name, int namelen, dev_t *dev) |
824{ 825 int u; 826 827 if (*dev != NODEV) 828 return; 829 if (bcmp(name, "pty", 3) != 0) 830 return; 831 if (name[5] != '\0') --- 17 unchanged lines hidden (view full) --- 849 return; 850 *dev = make_dev(&ptc_cdevsw, u, 851 UID_ROOT, GID_WHEEL, 0666, "pty%c%r", names[u / 32], u % 32); 852 (*dev)->si_flags |= SI_CHEAPCLONE; 853 return; 854} 855 856static void | 777{ 778 int u; 779 780 if (*dev != NODEV) 781 return; 782 if (bcmp(name, "pty", 3) != 0) 783 return; 784 if (name[5] != '\0') --- 17 unchanged lines hidden (view full) --- 802 return; 803 *dev = make_dev(&ptc_cdevsw, u, 804 UID_ROOT, GID_WHEEL, 0666, "pty%c%r", names[u / 32], u % 32); 805 (*dev)->si_flags |= SI_CHEAPCLONE; 806 return; 807} 808 809static void |
857ptc_drvinit(unused) 858 void *unused; | 810ptc_drvinit(void *unused) |
859{ 860 861 EVENTHANDLER_REGISTER(dev_clone, pty_clone, 0, 1000); 862} 863 864SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL) | 811{ 812 813 EVENTHANDLER_REGISTER(dev_clone, pty_clone, 0, 1000); 814} 815 816SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL) |