1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-11-13     Shell        init ver.
9  */
10 
11 #include "bsd_porting.h"
12 
13 /*-
14  * SPDX-License-Identifier: BSD-2-Clause
15  *
16  * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
17  * All rights reserved.
18  *
19  * Portions of this software were developed under sponsorship from Snow
20  * B.V., the Netherlands.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41  * SUCH DAMAGE.
42  */
43 
44 #ifndef _SYS_TTYQUEUE_H_
45 #define _SYS_TTYQUEUE_H_
46 
47 #ifndef __LWP_TERMINAL_H__
48 #error "can only be included through <teminal.h>"
49 #endif /* !__LWP_TERMINAL_H__ */
50 
51 struct lwp_tty;
52 struct ttyinq_block;
53 struct ttyoutq_block;
54 struct uio;
55 
56 /* Data input queue. */
57 struct ttyinq
58 {
59     struct ttyinq_block *ti_firstblock;
60     struct ttyinq_block *ti_startblock;
61     struct ttyinq_block *ti_reprintblock;
62     struct ttyinq_block *ti_lastblock;
63     unsigned int ti_begin;
64     unsigned int ti_linestart;
65     unsigned int ti_reprint;
66     unsigned int ti_end;
67     unsigned int ti_nblocks;
68     unsigned int ti_quota;
69 };
70 #define TTYINQ_DATASIZE 128
71 
72 /* Data output queue. */
73 struct ttyoutq
74 {
75     struct ttyoutq_block *to_firstblock;
76     struct ttyoutq_block *to_lastblock;
77     unsigned int to_begin;
78     unsigned int to_end;
79     unsigned int to_nblocks;
80     unsigned int to_quota;
81 };
82 #define TTYOUTQ_DATASIZE (256 - sizeof(struct ttyoutq_block *))
83 
84 /* Input queue handling routines. */
85 int ttyinq_setsize(struct ttyinq *ti, struct lwp_tty *tp, size_t len);
86 void ttyinq_free(struct ttyinq *ti);
87 int ttyinq_read_uio(struct ttyinq *ti, struct lwp_tty *tp, struct uio *uio,
88                     size_t readlen, size_t flushlen);
89 size_t ttyinq_write(struct ttyinq *ti, const void *buf, size_t len, int quote);
90 int ttyinq_write_nofrag(struct ttyinq *ti, const void *buf, size_t len,
91                         int quote);
92 void ttyinq_canonicalize(struct ttyinq *ti);
93 size_t ttyinq_findchar(struct ttyinq *ti, const char *breakc, size_t maxlen,
94                        char *lastc);
95 void ttyinq_flush(struct ttyinq *ti);
96 int ttyinq_peekchar(struct ttyinq *ti, char *c, int *quote);
97 void ttyinq_unputchar(struct ttyinq *ti);
98 void ttyinq_reprintpos_set(struct ttyinq *ti);
99 void ttyinq_reprintpos_reset(struct ttyinq *ti);
100 
ttyinq_getsize(struct ttyinq * ti)101 rt_inline size_t ttyinq_getsize(struct ttyinq *ti)
102 {
103     return (ti->ti_nblocks * TTYINQ_DATASIZE);
104 }
105 
ttyinq_getallocatedsize(struct ttyinq * ti)106 rt_inline size_t ttyinq_getallocatedsize(struct ttyinq *ti)
107 {
108     return (ti->ti_quota * TTYINQ_DATASIZE);
109 }
110 
ttyinq_bytesleft(struct ttyinq * ti)111 rt_inline size_t ttyinq_bytesleft(struct ttyinq *ti)
112 {
113     size_t len;
114 
115     /* Make sure the usage never exceeds the length. */
116     len = ti->ti_nblocks * TTYINQ_DATASIZE;
117     MPASS(len >= ti->ti_end);
118 
119     return (len - ti->ti_end);
120 }
121 
ttyinq_bytescanonicalized(struct ttyinq * ti)122 rt_inline size_t ttyinq_bytescanonicalized(struct ttyinq *ti)
123 {
124     MPASS(ti->ti_begin <= ti->ti_linestart);
125 
126     return (ti->ti_linestart - ti->ti_begin);
127 }
128 
ttyinq_bytesline(struct ttyinq * ti)129 rt_inline size_t ttyinq_bytesline(struct ttyinq *ti)
130 {
131     MPASS(ti->ti_linestart <= ti->ti_end);
132 
133     return (ti->ti_end - ti->ti_linestart);
134 }
135 
136 /* Input buffer iteration. */
137 typedef void ttyinq_line_iterator_t(void *data, char c, int flags);
138 void ttyinq_line_iterate_from_linestart(struct ttyinq *ti,
139                                         ttyinq_line_iterator_t *iterator,
140                                         void *data);
141 void ttyinq_line_iterate_from_reprintpos(struct ttyinq *ti,
142                                          ttyinq_line_iterator_t *iterator,
143                                          void *data);
144 
145 /* Output queue handling routines. */
146 void ttyoutq_flush(struct ttyoutq *to);
147 int ttyoutq_setsize(struct ttyoutq *to, struct lwp_tty *tp, size_t len);
148 void ttyoutq_free(struct ttyoutq *to);
149 size_t ttyoutq_read(struct ttyoutq *to, void *buf, size_t len);
150 int ttyoutq_read_uio(struct ttyoutq *to, struct lwp_tty *tp, struct uio *uio);
151 size_t ttyoutq_write(struct ttyoutq *to, const void *buf, size_t len);
152 int ttyoutq_write_nofrag(struct ttyoutq *to, const void *buf, size_t len);
153 
ttyoutq_getsize(struct ttyoutq * to)154 rt_inline size_t ttyoutq_getsize(struct ttyoutq *to)
155 {
156     return (to->to_nblocks * TTYOUTQ_DATASIZE);
157 }
158 
ttyoutq_getallocatedsize(struct ttyoutq * to)159 rt_inline size_t ttyoutq_getallocatedsize(struct ttyoutq *to)
160 {
161     return (to->to_quota * TTYOUTQ_DATASIZE);
162 }
163 
ttyoutq_bytesleft(struct ttyoutq * to)164 rt_inline size_t ttyoutq_bytesleft(struct ttyoutq *to)
165 {
166     size_t len;
167 
168     /* Make sure the usage never exceeds the length. */
169     len = to->to_nblocks * TTYOUTQ_DATASIZE;
170     MPASS(len >= to->to_end);
171 
172     return (len - to->to_end);
173 }
174 
ttyoutq_bytesused(struct ttyoutq * to)175 rt_inline size_t ttyoutq_bytesused(struct ttyoutq *to)
176 {
177     return (to->to_end - to->to_begin);
178 }
179 
180 #endif /* !_SYS_TTYQUEUE_H_ */
181