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 130892 2004-06-21 22:57:16Z 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>
--- 70 unchanged lines hidden (view full) ---
112 u_char pt_ucntl;
113 struct tty *pt_tty;
114 struct cdev *devs, *devc;
115 struct prison *pt_prison;
116};
117
118#define PF_PKT 0x08 /* packet mode */
119#define PF_STOPPED 0x10 /* user told stopped */
120#define PF_REMOTE 0x20 /* remote and flow controlled input */
121#define PF_NOSTOP 0x40
122#define PF_UCNTL 0x80 /* user control mode */
123
124#define TSA_PTC_READ(tp) ((void *)&(tp)->t_outq.c_cf)
125#define TSA_PTC_WRITE(tp) ((void *)&(tp)->t_rawq.c_cl)
126#define TSA_PTS_READ(tp) ((void *)&(tp)->t_canq)
127
128static char *names = "pqrsPQRS";
--- 89 unchanged lines hidden (view full) ---
218 struct thread *td = curthread;
219 struct proc *p = td->td_proc;
220 struct tty *tp = dev->si_tty;
221 struct ptsc *pt = dev->si_drv1;
222 struct pgrp *pg;
223 int error = 0;
224
225again:
226 if (pt->pt_flags & PF_REMOTE) {
227 while (isbackground(p, tp)) {
228 sx_slock(&proctree_lock);
229 PROC_LOCK(p);
230 if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) ||
231 SIGISMEMBER(td->td_sigmask, SIGTTIN) ||
232 p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) {
233 PROC_UNLOCK(p);
234 sx_sunlock(&proctree_lock);
235 return (EIO);
236 }
237 pg = p->p_pgrp;
238 PROC_UNLOCK(p);
239 PGRP_LOCK(pg);
240 sx_sunlock(&proctree_lock);
241 pgsignal(pg, SIGTTIN, 1);
242 PGRP_UNLOCK(pg);
243 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ptsbg",
244 0);
245 if (error)
246 return (error);
247 }
248 if (tp->t_canq.c_cc == 0) {
249 if (flag & IO_NDELAY)
250 return (EWOULDBLOCK);
251 error = ttysleep(tp, TSA_PTS_READ(tp), TTIPRI | PCATCH,
252 "ptsin", 0);
253 if (error)
254 return (error);
255 goto again;
256 }
257 while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
258 if (ureadc(getc(&tp->t_canq), uio) < 0) {
259 error = EFAULT;
260 break;
261 }
262 if (tp->t_canq.c_cc == 1)
263 (void) getc(&tp->t_canq);
264 if (tp->t_canq.c_cc)
265 return (error);
266 } else
267 if (tp->t_oproc)
268 error = ttyld_read(tp, uio, flag);
269 ptcwakeup(tp, FWRITE);
270 return (error);
271}
272
273/*
274 * Write to pseudo-tty.
275 * Wakeups of controlling tty will happen
276 * indirectly, when tty driver calls ptsstart.
--- 195 unchanged lines hidden (view full) ---
472 if ((tp->t_state & TS_ISOPEN) &&
473 ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) ||
474 ((pt->pt_flags & PF_PKT) && pt->pt_send) ||
475 ((pt->pt_flags & PF_UCNTL) && pt->pt_ucntl)))
476 revents |= events & (POLLIN | POLLRDNORM);
477
478 if (events & (POLLOUT | POLLWRNORM))
479 if (tp->t_state & TS_ISOPEN &&
480 ((pt->pt_flags & PF_REMOTE) ?
481 (tp->t_canq.c_cc == 0) :
482 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
483 (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON)))))
484 revents |= events & (POLLOUT | POLLWRNORM);
485
486 if (events & POLLHUP)
487 if ((tp->t_state & TS_CARR_ON) == 0)
488 revents |= POLLHUP;
489
490 if (revents == 0) {
--- 17 unchanged lines hidden (view full) ---
508 u_char locbuf[BUFSIZ];
509 int cnt = 0;
510 struct ptsc *pt = dev->si_drv1;
511 int error = 0;
512
513again:
514 if ((tp->t_state&TS_ISOPEN) == 0)
515 goto block;
516 if (pt->pt_flags & PF_REMOTE) {
517 if (tp->t_canq.c_cc)
518 goto block;
519 while ((uio->uio_resid > 0 || cc > 0) &&
520 tp->t_canq.c_cc < TTYHOG - 1) {
521 if (cc == 0) {
522 cc = min(uio->uio_resid, BUFSIZ);
523 cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
524 cp = locbuf;
525 error = uiomove(cp, cc, uio);
526 if (error)
527 return (error);
528 /* check again for safety */
529 if ((tp->t_state & TS_ISOPEN) == 0) {
530 /* adjust as usual */
531 uio->uio_resid += cc;
532 return (EIO);
533 }
534 }
535 if (cc > 0) {
536 cc = b_to_q((char *)cp, cc, &tp->t_canq);
537 /*
538 * XXX we don't guarantee that the canq size
539 * is >= TTYHOG, so the above b_to_q() may
540 * leave some bytes uncopied. However, space
541 * is guaranteed for the null terminator if
542 * we don't fail here since (TTYHOG - 1) is
543 * not a multiple of CBSIZE.
544 */
545 if (cc > 0)
546 break;
547 }
548 }
549 /* adjust for data copied in but not written */
550 uio->uio_resid += cc;
551 (void) putc(0, &tp->t_canq);
552 ttwakeup(tp);
553 wakeup(TSA_PTS_READ(tp));
554 return (0);
555 }
556 while (uio->uio_resid > 0 || cc > 0) {
557 if (cc == 0) {
558 cc = min(uio->uio_resid, BUFSIZ);
559 cp = locbuf;
560 error = uiomove(cp, cc, uio);
561 if (error)
562 return (error);
563 /* check again for safety */
--- 74 unchanged lines hidden (view full) ---
638 case TIOCUCNTL:
639 if (*(int *)data) {
640 if (pt->pt_flags & PF_PKT)
641 return (EINVAL);
642 pt->pt_flags |= PF_UCNTL;
643 } else
644 pt->pt_flags &= ~PF_UCNTL;
645 return (0);
646
647 case TIOCREMOTE:
648 if (*(int *)data)
649 pt->pt_flags |= PF_REMOTE;
650 else
651 pt->pt_flags &= ~PF_REMOTE;
652 ttyflush(tp, FREAD|FWRITE);
653 return (0);
654 }
655
656 /*
657 * The rest of the ioctls shouldn't be called until
658 * the slave is open.
659 */
660 if ((tp->t_state & TS_ISOPEN) == 0)
661 return (EAGAIN);
--- 159 unchanged lines hidden ---
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 130892 2004-06-21 22:57:16Z 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>
--- 70 unchanged lines hidden (view full) ---
112 u_char pt_ucntl;
113 struct tty *pt_tty;
114 struct cdev *devs, *devc;
115 struct prison *pt_prison;
116};
117
118#define PF_PKT 0x08 /* packet mode */
119#define PF_STOPPED 0x10 /* user told stopped */
120#define PF_REMOTE 0x20 /* remote and flow controlled input */
121#define PF_NOSTOP 0x40
122#define PF_UCNTL 0x80 /* user control mode */
123
124#define TSA_PTC_READ(tp) ((void *)&(tp)->t_outq.c_cf)
125#define TSA_PTC_WRITE(tp) ((void *)&(tp)->t_rawq.c_cl)
126#define TSA_PTS_READ(tp) ((void *)&(tp)->t_canq)
127
128static char *names = "pqrsPQRS";
--- 89 unchanged lines hidden (view full) ---
218 struct thread *td = curthread;
219 struct proc *p = td->td_proc;
220 struct tty *tp = dev->si_tty;
221 struct ptsc *pt = dev->si_drv1;
222 struct pgrp *pg;
223 int error = 0;
224
225again:
226 if (pt->pt_flags & PF_REMOTE) {
227 while (isbackground(p, tp)) {
228 sx_slock(&proctree_lock);
229 PROC_LOCK(p);
230 if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) ||
231 SIGISMEMBER(td->td_sigmask, SIGTTIN) ||
232 p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) {
233 PROC_UNLOCK(p);
234 sx_sunlock(&proctree_lock);
235 return (EIO);
236 }
237 pg = p->p_pgrp;
238 PROC_UNLOCK(p);
239 PGRP_LOCK(pg);
240 sx_sunlock(&proctree_lock);
241 pgsignal(pg, SIGTTIN, 1);
242 PGRP_UNLOCK(pg);
243 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ptsbg",
244 0);
245 if (error)
246 return (error);
247 }
248 if (tp->t_canq.c_cc == 0) {
249 if (flag & IO_NDELAY)
250 return (EWOULDBLOCK);
251 error = ttysleep(tp, TSA_PTS_READ(tp), TTIPRI | PCATCH,
252 "ptsin", 0);
253 if (error)
254 return (error);
255 goto again;
256 }
257 while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
258 if (ureadc(getc(&tp->t_canq), uio) < 0) {
259 error = EFAULT;
260 break;
261 }
262 if (tp->t_canq.c_cc == 1)
263 (void) getc(&tp->t_canq);
264 if (tp->t_canq.c_cc)
265 return (error);
266 } else
267 if (tp->t_oproc)
268 error = ttyld_read(tp, uio, flag);
269 ptcwakeup(tp, FWRITE);
270 return (error);
271}
272
273/*
274 * Write to pseudo-tty.
275 * Wakeups of controlling tty will happen
276 * indirectly, when tty driver calls ptsstart.
--- 195 unchanged lines hidden (view full) ---
472 if ((tp->t_state & TS_ISOPEN) &&
473 ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) ||
474 ((pt->pt_flags & PF_PKT) && pt->pt_send) ||
475 ((pt->pt_flags & PF_UCNTL) && pt->pt_ucntl)))
476 revents |= events & (POLLIN | POLLRDNORM);
477
478 if (events & (POLLOUT | POLLWRNORM))
479 if (tp->t_state & TS_ISOPEN &&
480 ((pt->pt_flags & PF_REMOTE) ?
481 (tp->t_canq.c_cc == 0) :
482 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
483 (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON)))))
484 revents |= events & (POLLOUT | POLLWRNORM);
485
486 if (events & POLLHUP)
487 if ((tp->t_state & TS_CARR_ON) == 0)
488 revents |= POLLHUP;
489
490 if (revents == 0) {
--- 17 unchanged lines hidden (view full) ---
508 u_char locbuf[BUFSIZ];
509 int cnt = 0;
510 struct ptsc *pt = dev->si_drv1;
511 int error = 0;
512
513again:
514 if ((tp->t_state&TS_ISOPEN) == 0)
515 goto block;
516 if (pt->pt_flags & PF_REMOTE) {
517 if (tp->t_canq.c_cc)
518 goto block;
519 while ((uio->uio_resid > 0 || cc > 0) &&
520 tp->t_canq.c_cc < TTYHOG - 1) {
521 if (cc == 0) {
522 cc = min(uio->uio_resid, BUFSIZ);
523 cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
524 cp = locbuf;
525 error = uiomove(cp, cc, uio);
526 if (error)
527 return (error);
528 /* check again for safety */
529 if ((tp->t_state & TS_ISOPEN) == 0) {
530 /* adjust as usual */
531 uio->uio_resid += cc;
532 return (EIO);
533 }
534 }
535 if (cc > 0) {
536 cc = b_to_q((char *)cp, cc, &tp->t_canq);
537 /*
538 * XXX we don't guarantee that the canq size
539 * is >= TTYHOG, so the above b_to_q() may
540 * leave some bytes uncopied. However, space
541 * is guaranteed for the null terminator if
542 * we don't fail here since (TTYHOG - 1) is
543 * not a multiple of CBSIZE.
544 */
545 if (cc > 0)
546 break;
547 }
548 }
549 /* adjust for data copied in but not written */
550 uio->uio_resid += cc;
551 (void) putc(0, &tp->t_canq);
552 ttwakeup(tp);
553 wakeup(TSA_PTS_READ(tp));
554 return (0);
555 }
556 while (uio->uio_resid > 0 || cc > 0) {
557 if (cc == 0) {
558 cc = min(uio->uio_resid, BUFSIZ);
559 cp = locbuf;
560 error = uiomove(cp, cc, uio);
561 if (error)
562 return (error);
563 /* check again for safety */
--- 74 unchanged lines hidden (view full) ---
638 case TIOCUCNTL:
639 if (*(int *)data) {
640 if (pt->pt_flags & PF_PKT)
641 return (EINVAL);
642 pt->pt_flags |= PF_UCNTL;
643 } else
644 pt->pt_flags &= ~PF_UCNTL;
645 return (0);
646
647 case TIOCREMOTE:
648 if (*(int *)data)
649 pt->pt_flags |= PF_REMOTE;
650 else
651 pt->pt_flags &= ~PF_REMOTE;
652 ttyflush(tp, FREAD|FWRITE);
653 return (0);
654 }
655
656 /*
657 * The rest of the ioctls shouldn't be called until
658 * the slave is open.
659 */
660 if ((tp->t_state & TS_ISOPEN) == 0)
661 return (EAGAIN);
--- 159 unchanged lines hidden ---