X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/600f7f072ed61fd173a4d410ea60644c533a32e5..3c83a5bcf148390bb116f44ccadccc6968bb181b:/sys/kern/tty_pty.c diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index 8642c01c50..bc5bb54b0c 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)tty_pty.c 7.21 (Berkeley) 5/30/91 - * $Id$ + * $Id: tty_pty.c,v 1.13 1994/04/20 18:37:10 ache Exp $ */ /* @@ -51,6 +51,7 @@ #include "uio.h" #include "kernel.h" #include "vnode.h" +#include "signalvar.h" #if NPTY == 1 #undef NPTY @@ -59,11 +60,13 @@ #define BUFSIZ 100 /* Chunk size iomoved to/from user */ +static void ptcwakeup(struct tty *, int); + /* * pts == /dev/tty[pqrs]? * ptc == /dev/pty[pqrs]? */ -struct tty pt_tty[NPTY]; +struct tty *pt_tty[NPTY]; struct pt_ioctl { int pt_flags; pid_t pt_selr, pt_selw; @@ -72,17 +75,22 @@ struct pt_ioctl { } pt_ioctl[NPTY]; int npty = NPTY; /* for pstat -t */ -#define PF_RCOLL 0x01 -#define PF_WCOLL 0x02 -#define PF_PKT 0x08 /* packet mode */ -#define PF_STOPPED 0x10 /* user told stopped */ -#define PF_REMOTE 0x20 /* remote and flow controlled input */ -#define PF_NOSTOP 0x40 -#define PF_UCNTL 0x80 /* user control mode */ +#define PF_RCOLL 0x0001 +#define PF_WCOLL 0x0002 +#define PF_PKT 0x0008 /* packet mode */ +#define PF_STOPPED 0x0010 /* user told stopped */ +#define PF_REMOTE 0x0020 /* remote and flow controlled input */ +#define PF_NOSTOP 0x0040 +#define PF_UCNTL 0x0080 /* user control mode */ +#define PF_COPEN 0x0100 /* master open */ +#define PF_SOPEN 0x0200 /* slave open */ /*ARGSUSED*/ +int ptsopen(dev, flag, devtype, p) dev_t dev; + int flag; + int devtype; struct proc *p; { register struct tty *tp; @@ -93,9 +101,8 @@ ptsopen(dev, flag, devtype, p) #endif if (minor(dev) >= NPTY) return (ENXIO); - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)] = ttymalloc(pt_tty[minor(dev)]); if ((tp->t_state & TS_ISOPEN) == 0) { - tp->t_state |= TS_WOPEN; ttychars(tp); /* Set up default chars */ tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; @@ -108,18 +115,21 @@ ptsopen(dev, flag, devtype, p) if (tp->t_oproc) /* Ctrlr still around. */ tp->t_state |= TS_CARR_ON; while ((tp->t_state & TS_CARR_ON) == 0) { - tp->t_state |= TS_WOPEN; if (flag&FNONBLOCK) break; - if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH, - ttopen, 0)) + if (error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH, + "ptsopn", 0)) return (error); } error = (*linesw[tp->t_line].l_open)(dev, tp, flag); - ptcwakeup(tp, FREAD|FWRITE); + if (error == 0) { + ptcwakeup(tp, FREAD|FWRITE); + pt_ioctl[minor(dev)].pt_flags |= PF_SOPEN; + } return (error); } +int ptsclose(dev, flag, mode, p) dev_t dev; int flag, mode; @@ -127,19 +137,28 @@ ptsclose(dev, flag, mode, p) { register struct tty *tp; - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)]; + ptcwakeup(tp, FREAD|FWRITE); (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); - ptcwakeup(tp, FREAD|FWRITE); + pt_ioctl[minor(dev)].pt_flags &= ~PF_SOPEN; + if ((pt_ioctl[minor(dev)].pt_flags & PF_COPEN) == 0) { + ttyfree(tp); +#ifdef broken /* session holds a ref to the tty; can't deallocate */ + pt_tty[minor(dev)] = (struct tty *)NULL; +#endif + } return(0); } +int ptsread(dev, uio, flag) dev_t dev; struct uio *uio; + int flag; { struct proc *p = curproc; - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; register struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; int error = 0; @@ -153,25 +172,25 @@ again: return (EIO); pgsignal(p->p_pgrp, SIGTTIN, 1); if (error = ttysleep(tp, (caddr_t)&lbolt, - TTIPRI | PCATCH, ttybg, 0)) + TTIPRI | PCATCH, "ptsbg", 0)) return (error); } - if (RB_LEN(&tp->t_can) == 0) { + if (RB_LEN(tp->t_can) == 0) { if (flag & IO_NDELAY) return (EWOULDBLOCK); - if (error = ttysleep(tp, (caddr_t)&tp->t_can, - TTIPRI | PCATCH, ttyin, 0)) + if (error = ttysleep(tp, (caddr_t)tp->t_can, + TTIPRI | PCATCH, "ptsin", 0)) return (error); goto again; } - while (RB_LEN(&tp->t_can) > 1 && uio->uio_resid > 0) - if (ureadc(getc(&tp->t_can), uio) < 0) { + while (RB_LEN(tp->t_can) > 1 && uio->uio_resid > 0) + if (ureadc(getc(tp->t_can), uio) < 0) { error = EFAULT; break; } - if (RB_LEN(&tp->t_can) == 1) - (void) getc(&tp->t_can); - if (RB_LEN(&tp->t_can)) + if (RB_LEN(tp->t_can) == 1) + (void) getc(tp->t_can); + if (RB_LEN(tp->t_can)) return (error); } else if (tp->t_oproc) @@ -185,13 +204,15 @@ again: * Wakeups of controlling tty will happen * indirectly, when tty driver calls ptsstart. */ +int ptswrite(dev, uio, flag) dev_t dev; struct uio *uio; + int flag; { register struct tty *tp; - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)]; if (tp->t_oproc == 0) return (EIO); return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); @@ -201,6 +222,7 @@ ptswrite(dev, uio, flag) * Start output on pseudo-tty. * Wake up process selecting or sleeping for input from controlling tty. */ +void ptsstart(tp) struct tty *tp; { @@ -215,8 +237,10 @@ ptsstart(tp) ptcwakeup(tp, FREAD); } +static void ptcwakeup(tp, flag) struct tty *tp; + int flag; { struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)]; @@ -226,7 +250,7 @@ ptcwakeup(tp, flag) pti->pt_selr = 0; pti->pt_flags &= ~PF_RCOLL; } - wakeup((caddr_t)&tp->t_out.rb_tl); + wakeup(TSA_PTC_READ(tp)); } if (flag & FWRITE) { if (pti->pt_selw) { @@ -234,13 +258,14 @@ ptcwakeup(tp, flag) pti->pt_selw = 0; pti->pt_flags &= ~PF_WCOLL; } - wakeup((caddr_t)&tp->t_raw.rb_hd); + wakeup(TSA_PTC_WRITE(tp)); } } /*ARGSUSED*/ +int #ifdef __STDC__ -ptcopen(dev_t dev, int flag, int devtype, struct proc *p) +ptcopen(int /*dev_t*/ dev, int flag, int devtype, struct proc *p) #else ptcopen(dev, flag, devtype, p) dev_t dev; @@ -253,43 +278,54 @@ ptcopen(dev, flag, devtype, p) if (minor(dev) >= NPTY) return (ENXIO); - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)] = ttymalloc(pt_tty[minor(dev)]); if (tp->t_oproc) return (EIO); tp->t_oproc = ptsstart; (void)(*linesw[tp->t_line].l_modem)(tp, 1); tp->t_lflag &= ~EXTPROC; pti = &pt_ioctl[minor(dev)]; - pti->pt_flags = 0; + pti->pt_flags &= PF_SOPEN; + pti->pt_flags |= PF_COPEN; pti->pt_send = 0; pti->pt_ucntl = 0; return (0); } extern struct tty *constty; /* -hv- 06.Oct.92*/ + +int ptcclose(dev) dev_t dev; { register struct tty *tp; - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)]; (void)(*linesw[tp->t_line].l_modem)(tp, 0); tp->t_state &= ~TS_CARR_ON; tp->t_oproc = 0; /* mark closed */ tp->t_session = 0; -/* XXX -hv- 6.Oct.92 this prevents the "hanging console bug" with X11 */ if (constty==tp) constty = 0; + pt_ioctl[minor(dev)].pt_flags &= ~PF_COPEN; + if ((pt_ioctl[minor(dev)].pt_flags & PF_SOPEN) == 0) { + ttyfree(tp); +#ifdef broken /* session holds a ref to the tty; can't deallocate */ + pt_tty[minor(dev)] = (struct tty *)NULL; +#endif + } return (0); } +int ptcread(dev, uio, flag) dev_t dev; struct uio *uio; + int flag; { - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; char buf[BUFSIZ]; int error = 0, cc; @@ -321,15 +357,15 @@ ptcread(dev, uio, flag) pti->pt_ucntl = 0; return (0); } - if (RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) + if (RB_LEN(tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) break; } if ((tp->t_state&TS_CARR_ON) == 0) return (0); /* EOF */ if (flag & IO_NDELAY) return (EWOULDBLOCK); - if (error = tsleep((caddr_t)&tp->t_out.rb_tl, TTIPRI | PCATCH, - ttyin, 0)) + if (error = tsleep(TSA_PTC_READ(tp), TTIPRI | PCATCH, + "ptcin", 0)) return (error); } if (pti->pt_flags & (PF_PKT|PF_UCNTL)) @@ -338,31 +374,23 @@ ptcread(dev, uio, flag) #ifdef was cc = q_to_b(&tp->t_outq, buf, MIN(uio->uio_resid, BUFSIZ)); #else - cc = min(MIN(uio->uio_resid, BUFSIZ), RB_CONTIGGET(&tp->t_out)); + cc = min(MIN(uio->uio_resid, BUFSIZ), RB_CONTIGGET(tp->t_out)); if (cc) { - bcopy(tp->t_out.rb_hd, buf, cc); - tp->t_out.rb_hd = - RB_ROLLOVER(&tp->t_out, tp->t_out.rb_hd+cc); + bcopy(tp->t_out->rb_hd, buf, cc); + tp->t_out->rb_hd = + RB_ROLLOVER(tp->t_out, tp->t_out->rb_hd+cc); } #endif if (cc <= 0) break; error = uiomove(buf, cc, uio); } - if (RB_LEN(&tp->t_out) <= tp->t_lowat) { - if (tp->t_state&TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t)&tp->t_out); - } - if (tp->t_wsel) { - selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); - tp->t_wsel = 0; - tp->t_state &= ~TS_WCOLL; - } - } + if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel) + ttwwakeup(tp); return (error); } +void ptsstop(tp, flush) register struct tty *tp; int flush; @@ -386,12 +414,13 @@ ptsstop(tp, flush) ptcwakeup(tp, flag); } +int ptcselect(dev, rw, p) dev_t dev; int rw; struct proc *p; { - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; struct proc *prev; int s; @@ -406,7 +435,7 @@ ptcselect(dev, rw, p) */ s = spltty(); if ((tp->t_state&TS_ISOPEN) && - RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) { + RB_LEN(tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) { splx(s); return (1); } @@ -428,12 +457,12 @@ ptcselect(dev, rw, p) case FWRITE: if (tp->t_state&TS_ISOPEN) { if (pti->pt_flags & PF_REMOTE) { - if (RB_LEN(&tp->t_can) == 0) + if (RB_LEN(tp->t_can) == 0) return (1); } else { - if (RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can) < TTYHOG-2) + if (RB_LEN(tp->t_raw) + RB_LEN(tp->t_can) < TTYHOG-2) return (1); - if (RB_LEN(&tp->t_can) == 0 && (tp->t_iflag&ICANON)) + if (RB_LEN(tp->t_can) == 0 && (tp->t_iflag&ICANON)) return (1); } } @@ -447,12 +476,14 @@ ptcselect(dev, rw, p) return (0); } +int ptcwrite(dev, uio, flag) dev_t dev; register struct uio *uio; + int flag; { - register struct tty *tp = &pt_tty[minor(dev)]; - register u_char *cp; + register struct tty *tp = pt_tty[minor(dev)]; + register u_char *cp = 0; register int cc = 0; u_char locbuf[BUFSIZ]; int cnt = 0; @@ -463,12 +494,12 @@ again: if ((tp->t_state&TS_ISOPEN) == 0) goto block; if (pti->pt_flags & PF_REMOTE) { - if (RB_LEN(&tp->t_can)) + if (RB_LEN(tp->t_can)) goto block; - while (uio->uio_resid > 0 && RB_LEN(&tp->t_can) < TTYHOG - 1) { + while (uio->uio_resid > 0 && RB_LEN(tp->t_can) < TTYHOG - 1) { if (cc == 0) { cc = min(uio->uio_resid, BUFSIZ); - cc = min(cc, RB_CONTIGPUT(&tp->t_can)); + cc = min(cc, RB_CONTIGPUT(tp->t_can)); cp = locbuf; error = uiomove((caddr_t)cp, cc, uio); if (error) @@ -482,16 +513,16 @@ again: (void) b_to_q((char *)cp, cc, &tp->t_canq); #else if (cc) { - bcopy(cp, tp->t_can.rb_tl, cc); - tp->t_can.rb_tl = - RB_ROLLOVER(&tp->t_can, tp->t_can.rb_tl+cc); + bcopy(cp, tp->t_can->rb_tl, cc); + tp->t_can->rb_tl = + RB_ROLLOVER(tp->t_can, tp->t_can->rb_tl+cc); } #endif cc = 0; } - (void) putc(0, &tp->t_can); + (void) putc(0, tp->t_can); ttwakeup(tp); - wakeup((caddr_t)&tp->t_can); + wakeup((caddr_t)tp->t_can); return (0); } while (uio->uio_resid > 0) { @@ -506,9 +537,9 @@ again: return (EIO); } while (cc > 0) { - if ((RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can)) >= TTYHOG - 2 && - (RB_LEN(&tp->t_can) > 0 || !(tp->t_iflag&ICANON))) { - wakeup((caddr_t)&tp->t_raw); + if ((RB_LEN(tp->t_raw) + RB_LEN(tp->t_can)) >= TTYHOG - 2 && + (RB_LEN(tp->t_can) > 0 || !(tp->t_iflag&ICANON))) { + wakeup(TSA_HUP_OR_INPUT(tp)); goto block; } (*linesw[tp->t_line].l_rint)(*cp++, tp); @@ -532,8 +563,8 @@ block: return (EWOULDBLOCK); return (0); } - if (error = tsleep((caddr_t)&tp->t_raw.rb_hd, TTOPRI | PCATCH, - ttyout, 0)) { + if (error = tsleep(TSA_PTC_WRITE(tp), TTOPRI | PCATCH, + "ptcout", 0)) { /* adjust for data copied in but not written */ uio->uio_resid += cc; return (error); @@ -542,15 +573,17 @@ block: } /*ARGSUSED*/ +int ptyioctl(dev, cmd, data, flag) caddr_t data; + int cmd; dev_t dev; + int flag; { - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; register struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; register u_char *cc = tp->t_cc; int stop, error; - extern ttyinput(); /* * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG. @@ -624,7 +657,7 @@ ptyioctl(dev, cmd, data, flag) case TIOCSETA: case TIOCSETAW: case TIOCSETAF: - while (getc(&tp->t_out) >= 0) + while (getc(tp->t_out) >= 0) ; break;