Change tty code to use clist interface, but with ring buffer implementation.
Also, fix a couple of bugs in tty.c and pccons.c, and some gross kluginess in the hp300 stuff.
This commit is contained in:
parent
bfc1b68bb5
commit
41b03a4a6e
|
@ -31,7 +31,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)tty_pty.c 7.21 (Berkeley) 5/30/91
|
||||
* $Id: tty_pty.c,v 1.7 1993/06/27 06:06:47 andrew Exp $
|
||||
* $Id: tty_pty.c,v 1.8 1993/07/12 11:33:54 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -48,7 +48,6 @@
|
|||
#include "tty.h"
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "malloc.h"
|
||||
#include "proc.h"
|
||||
#include "uio.h"
|
||||
#include "kernel.h"
|
||||
|
@ -74,8 +73,8 @@ struct pt_ioctl {
|
|||
} pt_ioctl[NPTY];
|
||||
int npty = NPTY; /* for pstat -t */
|
||||
|
||||
#define PF_RCOLL 0x01
|
||||
#define PF_WCOLL 0x02
|
||||
#define PF_COPEN 0x01 /* master open */
|
||||
#define PF_SOPEN 0x02 /* slave open */
|
||||
#define PF_PKT 0x08 /* packet mode */
|
||||
#define PF_STOPPED 0x10 /* user told stopped */
|
||||
#define PF_REMOTE 0x20 /* remote and flow controlled input */
|
||||
|
@ -100,9 +99,7 @@ ptsopen(dev, flag, devtype, p)
|
|||
if (minor(dev) >= NPTY)
|
||||
return (ENXIO);
|
||||
if(!pt_tty[minor(dev)]) {
|
||||
MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
|
||||
bzero(tp, sizeof(struct tty));
|
||||
pt_tty[minor(dev)] = tp;
|
||||
tp = pt_tty[minor(dev)] = ttymalloc();
|
||||
} else
|
||||
tp = pt_tty[minor(dev)];
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
|
@ -122,13 +119,15 @@ ptsopen(dev, flag, devtype, p)
|
|||
tp->t_state |= TS_WOPEN;
|
||||
if (flag&FNONBLOCK)
|
||||
break;
|
||||
if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH,
|
||||
if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
|
||||
ttopen, 0))
|
||||
return (error);
|
||||
}
|
||||
error = (*linesw[tp->t_line].l_open)(dev, tp);
|
||||
ptcwakeup(tp, FREAD|FWRITE);
|
||||
if (error = (*linesw[tp->t_line].l_open)(dev, tp))
|
||||
return (error);
|
||||
pt_ioctl[minor(dev)].pt_flags |= PF_SOPEN;
|
||||
ptcwakeup(tp, FREAD|FWRITE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -143,6 +142,11 @@ ptsclose(dev, flag, mode, p)
|
|||
(*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);
|
||||
pt_tty[minor(dev)] = (struct tty *)NULL;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -170,22 +174,22 @@ again:
|
|||
TTIPRI | PCATCH, ttybg, 0))
|
||||
return (error);
|
||||
}
|
||||
if (RB_LEN(&tp->t_can) == 0) {
|
||||
if (tp->t_canq.c_cc == 0) {
|
||||
if (flag & IO_NDELAY)
|
||||
return (EWOULDBLOCK);
|
||||
if (error = ttysleep(tp, (caddr_t)&tp->t_can,
|
||||
if (error = ttysleep(tp, (caddr_t)&tp->t_canq,
|
||||
TTIPRI | PCATCH, ttyin, 0))
|
||||
return (error);
|
||||
goto again;
|
||||
}
|
||||
while (RB_LEN(&tp->t_can) > 1 && uio->uio_resid > 0)
|
||||
if (ureadc(rbgetc(&tp->t_can), uio) < 0) {
|
||||
while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
|
||||
if (ureadc(getc(&tp->t_canq), uio) < 0) {
|
||||
error = EFAULT;
|
||||
break;
|
||||
}
|
||||
if (RB_LEN(&tp->t_can) == 1)
|
||||
(void) rbgetc(&tp->t_can);
|
||||
if (RB_LEN(&tp->t_can))
|
||||
if (tp->t_canq.c_cc == 1)
|
||||
(void) getc(&tp->t_canq);
|
||||
if (tp->t_canq.c_cc)
|
||||
return (error);
|
||||
} else
|
||||
if (tp->t_oproc)
|
||||
|
@ -230,7 +234,6 @@ ptsstart(tp)
|
|||
pti->pt_send = TIOCPKT_START;
|
||||
}
|
||||
ptcwakeup(tp, FREAD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -243,11 +246,11 @@ ptcwakeup(tp, flag)
|
|||
|
||||
if (flag & FREAD) {
|
||||
selwakeup(&pti->pt_selr);
|
||||
wakeup((caddr_t)&tp->t_out.rb_tl);
|
||||
wakeup((caddr_t)&tp->t_outq.c_cl);
|
||||
}
|
||||
if (flag & FWRITE) {
|
||||
selwakeup(&pti->pt_selw);
|
||||
wakeup((caddr_t)&tp->t_raw.rb_hd);
|
||||
wakeup((caddr_t)&tp->t_rawq.c_cf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,9 +272,7 @@ ptcopen(dev, flag, devtype, p)
|
|||
if (minor(dev) >= NPTY)
|
||||
return (ENXIO);
|
||||
if(!pt_tty[minor(dev)]) {
|
||||
MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
|
||||
bzero(tp, sizeof(struct tty));
|
||||
pt_tty[minor(dev)] = tp;
|
||||
tp = pt_tty[minor(dev)] = ttymalloc();
|
||||
} else
|
||||
tp = pt_tty[minor(dev)];
|
||||
if (tp->t_oproc)
|
||||
|
@ -280,7 +281,8 @@ ptcopen(dev, flag, devtype, p)
|
|||
(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);
|
||||
|
@ -304,17 +306,11 @@ ptcclose(dev)
|
|||
if (constty==tp)
|
||||
constty = 0;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* currently, we do not free the pty structures once they have
|
||||
* been allocated. Two reasons: cheap to keep them around, and
|
||||
* I don't want to spend my time finding the exact variables that
|
||||
* will tell me if the slave/master are closed and if I can free
|
||||
* them. <deraadt@fsa.ca>
|
||||
*/
|
||||
FREE(tp, M_TTYS);
|
||||
pt_ioctl[minor(dev)].pt_flags &= ~PF_COPEN;
|
||||
if ((pt_ioctl[minor(dev)].pt_flags & PF_SOPEN) == 0) {
|
||||
ttyfree(tp);
|
||||
pt_tty[minor(dev)] = (struct tty *)NULL;
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -326,7 +322,7 @@ ptcread(dev, uio, flag)
|
|||
{
|
||||
register struct tty *tp = pt_tty[minor(dev)];
|
||||
struct pt_ioctl *pti = &pt_ioctl[minor(dev)];
|
||||
char buf[BUFSIZ];
|
||||
u_char buf[BUFSIZ];
|
||||
int error = 0, cc;
|
||||
|
||||
/*
|
||||
|
@ -357,38 +353,29 @@ ptcread(dev, uio, flag)
|
|||
pti->pt_ucntl = 0;
|
||||
return (0);
|
||||
}
|
||||
if (RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0)
|
||||
if (tp->t_outq.c_cc && (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,
|
||||
if (error = tsleep((caddr_t)&tp->t_outq.c_cl, TTIPRI | PCATCH,
|
||||
ttyin, 0))
|
||||
return (error);
|
||||
}
|
||||
if (pti->pt_flags & (PF_PKT|PF_UCNTL))
|
||||
error = ureadc(0, uio);
|
||||
while (uio->uio_resid > 0 && error == 0) {
|
||||
#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));
|
||||
if (cc) {
|
||||
rbunpack(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_outq.c_cc <= tp->t_lowat) {
|
||||
if (tp->t_state&TS_ASLEEP) {
|
||||
tp->t_state &= ~TS_ASLEEP;
|
||||
wakeup((caddr_t)&tp->t_out);
|
||||
wakeup((caddr_t)&tp->t_outq);
|
||||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
}
|
||||
|
@ -439,7 +426,7 @@ ptcselect(dev, rw, p)
|
|||
*/
|
||||
s = spltty();
|
||||
if ((tp->t_state&TS_ISOPEN) &&
|
||||
RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) {
|
||||
tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
|
||||
splx(s);
|
||||
return (1);
|
||||
}
|
||||
|
@ -458,12 +445,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 (tp->t_canq.c_cc == 0)
|
||||
return (1);
|
||||
} else {
|
||||
if (RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can) < TTYHOG-2)
|
||||
if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2)
|
||||
return (1);
|
||||
if (RB_LEN(&tp->t_can) == 0 && (tp->t_iflag&ICANON))
|
||||
if (tp->t_canq.c_cc == 0 && (tp->t_iflag&ICANON))
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
@ -492,12 +479,12 @@ again:
|
|||
if ((tp->t_state&TS_ISOPEN) == 0)
|
||||
goto block;
|
||||
if (pti->pt_flags & PF_REMOTE) {
|
||||
if (RB_LEN(&tp->t_can))
|
||||
if (tp->t_canq.c_cc)
|
||||
goto block;
|
||||
while (uio->uio_resid > 0 && RB_LEN(&tp->t_can) < TTYHOG - 1) {
|
||||
while (uio->uio_resid > 0 && tp->t_canq.c_cc < TTYHOG - 1) {
|
||||
if (cc == 0) {
|
||||
cc = min(uio->uio_resid, BUFSIZ);
|
||||
cc = min(cc, TTYHOG - 1 - RB_CONTIGPUT(&tp->t_can));
|
||||
cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
|
||||
cp = locbuf;
|
||||
error = uiomove((caddr_t)cp, cc, uio);
|
||||
if (error)
|
||||
|
@ -506,21 +493,13 @@ again:
|
|||
if ((tp->t_state&TS_ISOPEN) == 0)
|
||||
return (EIO);
|
||||
}
|
||||
#ifdef was
|
||||
if (cc)
|
||||
(void) b_to_q((char *)cp, cc, &tp->t_canq);
|
||||
#else
|
||||
if (cc) {
|
||||
rbpack(cp, tp->t_can.rb_tl, cc);
|
||||
tp->t_can.rb_tl =
|
||||
RB_ROLLOVER(&tp->t_can, tp->t_can.rb_tl+cc);
|
||||
}
|
||||
#endif
|
||||
(void) b_to_q(cp, cc, &tp->t_canq);
|
||||
cc = 0;
|
||||
}
|
||||
(void) putc(0, &tp->t_can);
|
||||
(void) putc(0, &tp->t_canq);
|
||||
ttwakeup(tp);
|
||||
wakeup((caddr_t)&tp->t_can);
|
||||
wakeup((caddr_t)&tp->t_canq);
|
||||
return (0);
|
||||
}
|
||||
while (uio->uio_resid > 0) {
|
||||
|
@ -535,9 +514,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 ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
|
||||
(tp->t_canq.c_cc > 0 || !(tp->t_iflag&ICANON))) {
|
||||
wakeup((caddr_t)&tp->t_rawq);
|
||||
goto block;
|
||||
}
|
||||
(*linesw[tp->t_line].l_rint)(*cp++, tp);
|
||||
|
@ -561,7 +540,7 @@ block:
|
|||
return (EWOULDBLOCK);
|
||||
return (0);
|
||||
}
|
||||
if (error = tsleep((caddr_t)&tp->t_raw.rb_hd, TTOPRI | PCATCH,
|
||||
if (error = tsleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI | PCATCH,
|
||||
ttyout, 0)) {
|
||||
/* adjust for data copied in but not written */
|
||||
uio->uio_resid += cc;
|
||||
|
@ -654,7 +633,7 @@ ptyioctl(dev, cmd, data, flag)
|
|||
case TIOCSETA:
|
||||
case TIOCSETAW:
|
||||
case TIOCSETAF:
|
||||
while (rbgetc(&tp->t_out) >= 0)
|
||||
while (getc(&tp->t_outq) >= 0)
|
||||
;
|
||||
break;
|
||||
|
||||
|
|
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Theo de Raadt
|
||||
* All rights reserved.
|
||||
*
|
||||
* Per Lindqvist <pgd@compuram.bbt.se> supplied an almost fully working
|
||||
* set of true clist functions that this is very loosely based on.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Theo de Raadt.
|
||||
* 4. The name of Theo de Raadt may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* $Id: tty_subr.c,v 1.1 1993/07/12 11:35:18 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include "param.h"
|
||||
#include "systm.h"
|
||||
#include "buf.h"
|
||||
#include "ioctl.h"
|
||||
#include "tty.h"
|
||||
#include "clist.h"
|
||||
#include "malloc.h"
|
||||
|
||||
/*
|
||||
* At compile time, choose:
|
||||
* There are two ways the TTY_QUOTE bit can be stored. If QBITS is
|
||||
* defined we allocate an array of bits -- 1/8th as much memory but
|
||||
* setbit(), clrbit(), and isset() take more cpu. If QBITS is
|
||||
* undefined, we just use an array of bytes.
|
||||
*
|
||||
* If TTY_QUOTE functionality isn't required by a line discipline,
|
||||
* it can free c_cq and set it to NULL. This speeds things up,
|
||||
* and also does not use any extra memory. This is useful for (say)
|
||||
* a SLIP line discipline that wants a 32K ring buffer for data
|
||||
* but doesn't need quoting.
|
||||
*/
|
||||
#define QBITS
|
||||
|
||||
#ifdef QBITS
|
||||
#define QMEM(n) ((((n)-1)/NBBY)+1)
|
||||
#else
|
||||
#define QMEM(n) (n)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize clists.
|
||||
*/
|
||||
void
|
||||
cinit()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a particular clist. Ok, they are really ring buffers,
|
||||
* of the specified length, with/without quoting support.
|
||||
*/
|
||||
int
|
||||
clalloc(clp, size, quot)
|
||||
struct clist *clp;
|
||||
int size;
|
||||
int quot;
|
||||
{
|
||||
|
||||
MALLOC(clp->c_cs, u_char *, size, M_TTYS, M_WAITOK);
|
||||
if (!clp->c_cs)
|
||||
return (-1);
|
||||
bzero(clp->c_cs, size);
|
||||
|
||||
if(quot) {
|
||||
MALLOC(clp->c_cq, u_char *, QMEM(size), M_TTYS, M_WAITOK);
|
||||
if (!clp->c_cq) {
|
||||
FREE(clp->c_cs, M_TTYS);
|
||||
return (-1);
|
||||
}
|
||||
bzero(clp->c_cs, QMEM(size));
|
||||
} else
|
||||
clp->c_cq = (u_char *)0;
|
||||
|
||||
clp->c_cf = clp->c_cl = (u_char *)0;
|
||||
clp->c_ce = clp->c_cs + size;
|
||||
clp->c_cn = size;
|
||||
clp->c_cc = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
clfree(clp)
|
||||
struct clist *clp;
|
||||
{
|
||||
if(clp->c_cs)
|
||||
FREE(clp->c_cs, M_TTYS);
|
||||
if(clp->c_cq)
|
||||
FREE(clp->c_cq, M_TTYS);
|
||||
clp->c_cs = clp->c_cq = (u_char *)0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get a character from a clist.
|
||||
*/
|
||||
int
|
||||
getc(clp)
|
||||
struct clist *clp;
|
||||
{
|
||||
register int c = -1;
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
if (clp->c_cc == 0)
|
||||
goto out;
|
||||
|
||||
c = *clp->c_cf & 0xff;
|
||||
if (clp->c_cq) {
|
||||
#ifdef QBITS
|
||||
if (isset(clp->c_cq, clp->c_cf - clp->c_cs) )
|
||||
c |= TTY_QUOTE;
|
||||
#else
|
||||
if (*(clp->c_cf - clp->c_cs + clp->c_cq))
|
||||
c |= TTY_QUOTE;
|
||||
#endif
|
||||
}
|
||||
if (++clp->c_cf == clp->c_ce)
|
||||
clp->c_cf = clp->c_cs;
|
||||
if (--clp->c_cc == 0)
|
||||
clp->c_cf = clp->c_cl = (u_char *)0;
|
||||
out:
|
||||
splx(s);
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy clist to buffer.
|
||||
* Return number of bytes moved.
|
||||
*/
|
||||
int
|
||||
q_to_b(clp, cp, count)
|
||||
struct clist *clp;
|
||||
u_char *cp;
|
||||
int count;
|
||||
{
|
||||
register int cc;
|
||||
u_char *p = cp;
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
/* optimize this while loop */
|
||||
while (count > 0 && clp->c_cc > 0) {
|
||||
cc = clp->c_cl - clp->c_cf;
|
||||
if (clp->c_cf >= clp->c_cl)
|
||||
cc = clp->c_ce - clp->c_cf;
|
||||
if (cc > count)
|
||||
cc = count;
|
||||
bcopy(clp->c_cf, p, cc);
|
||||
count -= cc;
|
||||
p += cc;
|
||||
clp->c_cc -= cc;
|
||||
clp->c_cf += cc;
|
||||
if (clp->c_cf == clp->c_ce)
|
||||
clp->c_cf = clp->c_cs;
|
||||
}
|
||||
if (clp->c_cc == 0)
|
||||
clp->c_cf = clp->c_cl = (u_char *)0;
|
||||
splx(s);
|
||||
return p - cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return count of contiguous characters in clist.
|
||||
* Stop counting if flag&character is non-null.
|
||||
*/
|
||||
ndqb(clp, flag)
|
||||
struct clist *clp;
|
||||
int flag;
|
||||
{
|
||||
int count = 0;
|
||||
register int i;
|
||||
register int cc;
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
if ((cc = clp->c_cc) == 0 || flag == 0)
|
||||
goto out;
|
||||
|
||||
i = clp->c_cf - clp->c_cs;
|
||||
while (cc-- > 0 && (clp->c_cs[i++] & flag) == 0) {
|
||||
count++;
|
||||
if (i == clp->c_cn)
|
||||
break;
|
||||
}
|
||||
out:
|
||||
splx(s);
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush count bytes from clist.
|
||||
*/
|
||||
void
|
||||
ndflush(clp, count)
|
||||
struct clist *clp;
|
||||
int count;
|
||||
{
|
||||
register int cc;
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
if (count == clp->c_cc) {
|
||||
clp->c_cc = 0;
|
||||
clp->c_cf = clp->c_cl = (u_char *)0;
|
||||
goto out;
|
||||
}
|
||||
/* optimize this while loop */
|
||||
while (count > 0 && clp->c_cc > 0) {
|
||||
cc = clp->c_cl - clp->c_cf;
|
||||
if (clp->c_cf >= clp->c_cl)
|
||||
cc = clp->c_ce - clp->c_cf;
|
||||
if (cc > count)
|
||||
cc = count;
|
||||
count -= cc;
|
||||
clp->c_cc -= cc;
|
||||
clp->c_cf += cc;
|
||||
if (clp->c_cf == clp->c_ce)
|
||||
clp->c_cf = clp->c_cs;
|
||||
}
|
||||
if (clp->c_cc == 0)
|
||||
clp->c_cf = clp->c_cl = (u_char *)0;
|
||||
out:
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a character into the output queue.
|
||||
*/
|
||||
int
|
||||
putc(c, clp)
|
||||
int c;
|
||||
struct clist *clp;
|
||||
{
|
||||
register u_char *q;
|
||||
register int i;
|
||||
int r = -1;
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
if (clp->c_cc == clp->c_cn)
|
||||
goto out;
|
||||
|
||||
if (clp->c_cc == 0) {
|
||||
if (!clp->c_cs) {
|
||||
#if defined(DIAGNOSTIC) || 1
|
||||
printf("b_to_q: required clalloc\n");
|
||||
#endif
|
||||
if(clalloc(clp, 1024, 1)) {
|
||||
out:
|
||||
splx(s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
clp->c_cf = clp->c_cl = clp->c_cs;
|
||||
}
|
||||
|
||||
*clp->c_cl = c & 0xff;
|
||||
i = clp->c_cl - clp->c_cs;
|
||||
if (clp->c_cq) {
|
||||
#ifdef QBITS
|
||||
if (c & TTY_QUOTE)
|
||||
setbit(clp->c_cq, i);
|
||||
else
|
||||
clrbit(clp->c_cq, i);
|
||||
#else
|
||||
q = clp->c_cq + i;
|
||||
*q = (c & TTY_QUOTE) ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
clp->c_cc++;
|
||||
clp->c_cl++;
|
||||
if (clp->c_cl == clp->c_ce)
|
||||
clp->c_cl = clp->c_cs;
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef QBITS
|
||||
/*
|
||||
* optimized version of
|
||||
*
|
||||
* for (i = 0; i < len; i++)
|
||||
* clrbit(cp, off + len);
|
||||
*/
|
||||
void
|
||||
clrbits(cp, off, len)
|
||||
u_char *cp;
|
||||
int off;
|
||||
int len;
|
||||
{
|
||||
int sby, sbi, eby, ebi;
|
||||
register int i;
|
||||
u_char mask;
|
||||
|
||||
if(len==1) {
|
||||
clrbit(cp, off);
|
||||
return;
|
||||
}
|
||||
|
||||
sby = off / NBBY;
|
||||
sbi = off % NBBY;
|
||||
eby = (off+len) / NBBY;
|
||||
ebi = (off+len) % NBBY;
|
||||
if (sby == eby) {
|
||||
mask = ((1 << (ebi - sbi)) - 1) << sbi;
|
||||
cp[sby] &= ~mask;
|
||||
} else {
|
||||
mask = (1<<sbi) - 1;
|
||||
cp[sby++] &= mask;
|
||||
|
||||
mask = (1<<ebi) - 1;
|
||||
cp[eby] &= ~mask;
|
||||
|
||||
for (i = sby; i < eby; i++)
|
||||
cp[i] = 0x00;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy buffer to clist.
|
||||
* Return number of bytes not transfered.
|
||||
*/
|
||||
int
|
||||
b_to_q(cp, count, clp)
|
||||
u_char *cp;
|
||||
int count;
|
||||
struct clist *clp;
|
||||
{
|
||||
register int i, cc;
|
||||
register u_char *p = cp;
|
||||
int off, s;
|
||||
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
s = spltty();
|
||||
if (clp->c_cc == clp->c_cn)
|
||||
goto out;
|
||||
|
||||
if (clp->c_cc == 0) {
|
||||
if (!clp->c_cs) {
|
||||
#if defined(DIAGNOSTIC) || 1
|
||||
printf("b_to_q: required clalloc\n");
|
||||
#endif
|
||||
if(clalloc(clp, 1024, 1))
|
||||
goto out;
|
||||
}
|
||||
clp->c_cf = clp->c_cl = clp->c_cs;
|
||||
}
|
||||
|
||||
/* optimize this while loop */
|
||||
while (count > 0 && clp->c_cc < clp->c_cn) {
|
||||
cc = clp->c_ce - clp->c_cl;
|
||||
if (clp->c_cf > clp->c_cl)
|
||||
cc = clp->c_cf - clp->c_cl;
|
||||
if (cc > count)
|
||||
cc = count;
|
||||
bcopy(p, clp->c_cl, cc);
|
||||
if (clp->c_cq) {
|
||||
#ifdef QBITS
|
||||
clrbits(clp->c_cq, clp->c_cl - clp->c_cs, cc);
|
||||
#else
|
||||
bzero(clp->c_cl - clp->c_cs + clp->c_cq, cc);
|
||||
#endif
|
||||
}
|
||||
p += cc;
|
||||
count -= cc;
|
||||
clp->c_cc += cc;
|
||||
clp->c_cl += cc;
|
||||
if (clp->c_cl == clp->c_ce)
|
||||
clp->c_cl = clp->c_cs;
|
||||
}
|
||||
out:
|
||||
splx(s);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int cc;
|
||||
|
||||
/*
|
||||
* Given a non-NULL pointer into the clist return the pointer
|
||||
* to the next character in the list or return NULL if no more chars.
|
||||
*
|
||||
* Callers must not allow getc's to happen between firstc's and getc's
|
||||
* so that the pointer becomes invalid. Note that interrupts are NOT
|
||||
* masked.
|
||||
*/
|
||||
u_char *
|
||||
nextc(clp, cp, c)
|
||||
struct clist *clp;
|
||||
register u_char *cp;
|
||||
int *c;
|
||||
{
|
||||
|
||||
if (clp->c_cf == cp) {
|
||||
/*
|
||||
* First time initialization.
|
||||
*/
|
||||
cc = clp->c_cc;
|
||||
}
|
||||
if (cc == 0 || cp == NULL)
|
||||
return NULL;
|
||||
if (--cc == 0)
|
||||
return NULL;
|
||||
if (++cp == clp->c_ce)
|
||||
cp = clp->c_cs;
|
||||
*c = *cp & 0xff;
|
||||
if (clp->c_cq) {
|
||||
#ifdef QBITS
|
||||
if (isset(clp->c_cq, cp - clp->c_cs))
|
||||
*c |= TTY_QUOTE;
|
||||
#else
|
||||
if (*(clp->c_cf - clp->c_cs + clp->c_cq))
|
||||
*c |= TTY_QUOTE;
|
||||
#endif
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a non-NULL pointer into the clist return the pointer
|
||||
* to the first character in the list or return NULL if no more chars.
|
||||
*
|
||||
* Callers must not allow getc's to happen between firstc's and getc's
|
||||
* so that the pointer becomes invalid. Note that interrupts are NOT
|
||||
* masked.
|
||||
*
|
||||
* *c is set to the NEXT character
|
||||
*/
|
||||
u_char *
|
||||
firstc(clp, c)
|
||||
struct clist *clp;
|
||||
int *c;
|
||||
{
|
||||
int empty = 0;
|
||||
register u_char *cp;
|
||||
register int i;
|
||||
|
||||
cc = clp->c_cc;
|
||||
if (cc == 0)
|
||||
return NULL;
|
||||
cp = clp->c_cf;
|
||||
*c = *cp & 0xff;
|
||||
if(clp->c_cq) {
|
||||
#ifdef QBITS
|
||||
if (isset(clp->c_cq, cp - clp->c_cs))
|
||||
*c |= TTY_QUOTE;
|
||||
#else
|
||||
if (*(cp - clp->c_cs + clp->c_cq))
|
||||
*c |= TTY_QUOTE;
|
||||
#endif
|
||||
}
|
||||
return clp->c_cf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the last character in the clist and return it.
|
||||
*/
|
||||
int
|
||||
unputc(clp)
|
||||
struct clist *clp;
|
||||
{
|
||||
unsigned int c = -1;
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
if (clp->c_cc == 0)
|
||||
goto out;
|
||||
|
||||
if (clp->c_cl == clp->c_cs)
|
||||
clp->c_cl = clp->c_ce - 1;
|
||||
else
|
||||
--clp->c_cl;
|
||||
clp->c_cc--;
|
||||
|
||||
c = *clp->c_cl & 0xff;
|
||||
if (clp->c_cq) {
|
||||
#ifdef QBITS
|
||||
if (isset(clp->c_cq, clp->c_cl - clp->c_cs))
|
||||
c |= TTY_QUOTE;
|
||||
#else
|
||||
if (*(clp->c_cf - clp->c_cs + clp->c_cq))
|
||||
c | TTY_QUOTE;
|
||||
#endif
|
||||
}
|
||||
if (clp->c_cc == 0)
|
||||
clp->c_cf = clp->c_cl = (u_char *)0;
|
||||
out:
|
||||
splx(s);
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the chars in the from queue on the end of the to queue.
|
||||
*/
|
||||
void
|
||||
catq(from, to)
|
||||
struct clist *from, *to;
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = getc(from)) != -1)
|
||||
putc(c, to);
|
||||
}
|
Loading…
Reference in New Issue