From John Dyson - fix for bug in kern_physio where buffers would be
[unix-history] / sys / kern / tty_ring.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1989, 1990, 1991, 1992 William F. Jolitz, TeleMuse
3 * 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
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This software is a component of "386BSD" developed by
16 * William F. Jolitz, TeleMuse.
17 * 4. Neither the name of the developer nor the name "386BSD"
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ
22 * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS
23 * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
24 * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
25 * NOT MAKE USE OF THIS WORK.
26 *
27 * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED
28 * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN
29 * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES
30 * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING
31 * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND
32 * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE
33 * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS
34 * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 *
fde1aeb2 48 * $Id: tty_ring.c,v 1.3 1993/11/25 01:33:30 wollman Exp $
15637ed4 49 */
15637ed4
RG
50
51#include "param.h"
52#include "systm.h"
53#include "buf.h"
54#include "ioctl.h"
55#include "tty.h"
56
4c45483e
GW
57int
58putc(c, rbp)
59 int c;
60 struct ringb *rbp;
15637ed4
RG
61{
62 char *nxtp;
63
64 /* ring buffer full? */
65 if ( (nxtp = RB_SUCC(rbp, rbp->rb_tl)) == rbp->rb_hd) return (-1);
66
67 /* stuff character */
68 *rbp->rb_tl = c;
69 rbp->rb_tl = nxtp;
70 return(0);
71}
72
4c45483e
GW
73int
74getc(rbp)
75 struct ringb *rbp;
15637ed4
RG
76{
77 u_char c;
78
79 /* ring buffer empty? */
80 if (rbp->rb_hd == rbp->rb_tl) return(-1);
81
82 /* fetch character, locate next character */
83 c = *(u_char *) rbp->rb_hd;
84 rbp->rb_hd = RB_SUCC(rbp, rbp->rb_hd);
85 return (c);
86}
87
4c45483e
GW
88int
89nextc(cpp, rbp)
90 char **cpp;
91 struct ringb *rbp;
92{
15637ed4
RG
93
94 if (*cpp == rbp->rb_tl) return (0);
95 else { char *cp;
96 cp = *cpp;
97 *cpp = RB_SUCC(rbp, cp);
98 return(*cp);
99 }
100}
101
4c45483e
GW
102int
103ungetc(c, rbp)
104 int c;
105 struct ringb *rbp;
15637ed4
RG
106{
107 char *backp;
108
109 /* ring buffer full? */
110 if ( (backp = RB_PRED(rbp, rbp->rb_hd)) == rbp->rb_tl) return (-1);
111 rbp->rb_hd = backp;
112
113 /* stuff character */
114 *rbp->rb_hd = c;
115 return(0);
116}
117
4c45483e
GW
118int
119unputc(rbp)
120 struct ringb *rbp;
15637ed4
RG
121{
122 char *backp;
123 int c;
124
125 /* ring buffer empty? */
126 if (rbp->rb_hd == rbp->rb_tl) return(-1);
127
128 /* backup buffer and dig out previous character */
129 backp = RB_PRED(rbp, rbp->rb_tl);
130 c = *(u_char *)backp;
131 rbp->rb_tl = backp;
132
133 return(c);
134}
135
136#define peekc(rbp) (*(rbp)->rb_hd)
137
4c45483e
GW
138void
139initrb(rbp)
140 struct ringb *rbp;
141{
15637ed4
RG
142 rbp->rb_hd = rbp->rb_tl = rbp->rb_buf;
143}
144
145/*
146 * Example code for contiguous operations:
147 ...
148 nc = RB_CONTIGPUT(&rb);
149 if (nc) {
150 if (nc > 9) nc = 9;
151 bcopy("ABCDEFGHI", rb.rb_tl, nc);
152 rb.rb_tl += nc;
153 rb.rb_tl = RB_ROLLOVER(&rb, rb.rb_tl);
154 }
155 ...
156 ...
157 nc = RB_CONTIGGET(&rb);
158 if (nc) {
159 if (nc > 79) nc = 79;
160 bcopy(rb.rb_hd, stringbuf, nc);
161 rb.rb_hd += nc;
162 rb.rb_hd = RB_ROLLOVER(&rb, rb.rb_hd);
163 stringbuf[nc] = 0;
164 printf("%s|", stringbuf);
165 }
166 ...
167 */
168
169/*
170 * Concatenate ring buffers.
171 */
4c45483e 172void
15637ed4
RG
173catb(from, to)
174 struct ringb *from, *to;
175{
176 size_t nfromleft;
177 size_t nfromright;
178
179 nfromright = RB_CONTIGGET(from);
180 rb_write(to, from->rb_hd, nfromright);
181 from->rb_hd += nfromright;
182 from->rb_hd = RB_ROLLOVER(from, from->rb_hd);
183 nfromleft = RB_CONTIGGET(from);
184 rb_write(to, from->rb_hd, nfromleft);
185 from->rb_hd += nfromleft;
186}
187
188/*
189 * Copy ordinary buffer to ring buffer, return count of what fitted.
190 */
191size_t rb_write(to, buf, nfrom)
192 struct ringb *to;
193 char *buf;
194 size_t nfrom;
195{
196 char *toleft;
197 size_t ntoleft;
198 size_t ntoright;
199
200 ntoright = RB_CONTIGPUT(to);
201 if (nfrom < ntoright) {
202 bcopy(buf, to->rb_tl, nfrom);
203 to->rb_tl += nfrom;
204 return (nfrom);
205 }
206 bcopy(buf, to->rb_tl, ntoright);
207 nfrom -= ntoright;
208 toleft = to->rb_buf; /* fast RB_ROLLOVER */
209 ntoleft = to->rb_hd - toleft; /* fast RB_CONTIGPUT */
210 if (nfrom > ntoleft)
211 nfrom = ntoleft;
212 bcopy(buf + ntoright, toleft, nfrom);
213 to->rb_tl = toleft + nfrom;
214 return (ntoright + nfrom);
215}