30 #include <sys/cdefs.h>
33 #include <sys/param.h>
34 #include <sys/kernel.h>
36 #include <sys/queue.h>
37 #include <sys/sysctl.h>
38 #include <sys/systm.h>
65 SYSCTL_INT(_kern, OID_AUTO, tty_inq_flush_secure, CTLFLAG_RW,
68 #define TTYINQ_QUOTESIZE (TTYINQ_DATASIZE / BMSIZE)
70 #define GETBIT(tib,boff) \
71 ((tib)->tib_quotes[(boff) / BMSIZE] & (1 << ((boff) % BMSIZE)))
72 #define SETBIT(tib,boff) \
73 ((tib)->tib_quotes[(boff) / BMSIZE] |= (1 << ((boff) % BMSIZE)))
74 #define CLRBIT(tib,boff) \
75 ((tib)->tib_quotes[(boff) / BMSIZE] &= ~(1 << ((boff) % BMSIZE)))
86 #define TTYINQ_INSERT_TAIL(ti, tib) do { \
87 if (ti->ti_end == 0) { \
88 tib->tib_prev = NULL; \
89 tib->tib_next = ti->ti_firstblock; \
90 ti->ti_firstblock = tib; \
92 tib->tib_prev = ti->ti_lastblock; \
93 tib->tib_next = ti->ti_lastblock->tib_next; \
94 ti->ti_lastblock->tib_next = tib; \
96 if (tib->tib_next != NULL) \
97 tib->tib_next->tib_prev = tib; \
101 #define TTYINQ_REMOVE_HEAD(ti) do { \
102 ti->ti_firstblock = ti->ti_firstblock->tib_next; \
103 if (ti->ti_firstblock != NULL) \
104 ti->ti_firstblock->tib_prev = NULL; \
108 #define TTYINQ_RECYCLE(ti, tib) do { \
109 if (ti->ti_quota <= ti->ti_nblocks) \
110 uma_zfree(ttyinq_zone, tib); \
112 TTYINQ_INSERT_TAIL(ti, tib); \
120 ti->ti_quota = howmany(size, TTYINQ_DATASIZE);
122 while (ti->ti_quota > ti->ti_nblocks) {
149 while ((tib = ti->ti_firstblock) != NULL) {
154 MPASS(ti->ti_nblocks == 0);
159 size_t rlen,
size_t flen)
162 MPASS(rlen <= uio->uio_resid);
167 size_t cbegin, cend, clen;
170 if (ti->ti_begin == ti->ti_linestart)
172 tib = ti->ti_firstblock;
182 cbegin = ti->ti_begin;
183 cend = MIN(MIN(ti->ti_linestart, ti->ti_begin + rlen),
185 clen = cend - cbegin;
196 if (cend == TTYINQ_DATASIZE || cend == ti->ti_end) {
208 #define CORRECT_BLOCK(t) do { \
209 if (t <= TTYINQ_DATASIZE) \
212 t -= TTYINQ_DATASIZE; \
232 char ob[TTYINQ_DATASIZE - 1];
237 memcpy(ob, tib->
tib_data + cbegin, clen - flen);
238 ti->ti_begin += clen;
239 MPASS(ti->ti_begin < TTYINQ_DATASIZE);
243 error =
uiomove(ob, clen - flen, uio);
258 size_t length,
int value)
263 for (; length > 0; length--, offset++)
267 for (; length > 0; length--, offset++)
275 const char *cbuf =
buf;
281 boff = ti->ti_end % TTYINQ_DATASIZE;
283 if (ti->ti_end == 0) {
285 MPASS(ti->ti_begin == 0);
286 tib = ti->ti_firstblock;
291 ti->ti_lastblock = tib;
292 }
else if (boff == 0) {
299 ti->ti_lastblock = tib;
301 tib = ti->ti_lastblock;
305 l = MIN(nbytes, TTYINQ_DATASIZE - boff);
307 memcpy(tib->
tib_data + boff, cbuf, l);
317 return (cbuf - (
const char *)buf);
325 if (ttyinq_bytesleft(ti) < nbytes)
330 MPASS(ret == nbytes);
339 ti->ti_linestart = ti->ti_reprint = ti->ti_end;
340 ti->ti_startblock = ti->ti_reprintblock = ti->ti_lastblock;
348 unsigned int boff = ti->ti_begin;
349 unsigned int bend = MIN(MIN(TTYINQ_DATASIZE, ti->ti_linestart),
350 ti->ti_begin + maxlen);
357 while (boff < bend) {
360 return (boff - ti->ti_begin + 1);
366 return (bend - ti->ti_begin);
375 ti->ti_linestart = 0;
381 for (tib = ti->ti_firstblock; tib != NULL; tib = tib->
tib_next)
392 if (ti->ti_linestart == ti->ti_end)
395 MPASS(ti->ti_end > 0);
396 boff = (ti->ti_end - 1) % TTYINQ_DATASIZE;
399 *quote =
GETBIT(tib, boff);
408 MPASS(ti->ti_linestart < ti->ti_end);
410 if (--ti->ti_end % TTYINQ_DATASIZE == 0) {
412 ti->ti_lastblock = ti->ti_lastblock->tib_prev;
417 MPASS((ti->ti_lastblock == NULL) == (ti->ti_end == 0));
425 ti->ti_reprint = ti->ti_end;
426 ti->ti_reprintblock = ti->ti_lastblock;
433 ti->ti_reprint = ti->ti_linestart;
434 ti->ti_reprintblock = ti->ti_startblock;
439 ttyinq_line_iterator_t *iterator,
void *data,
446 tib = ti->ti_firstblock;
449 for (; offset < ti->ti_end; offset++) {
450 boff = offset % TTYINQ_DATASIZE;
457 if (boff == TTYINQ_DATASIZE - 1)
465 ttyinq_line_iterator_t *iterator,
void *data)
469 ti->ti_linestart, ti->ti_startblock);
474 ttyinq_line_iterator_t *iterator,
void *data)
478 ti->ti_reprint, ti->ti_reprintblock);
486 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
static void ttyinq_startup(void *dummy)
void ttyinq_line_iterate_from_reprintpos(struct ttyinq *ti, ttyinq_line_iterator_t *iterator, void *data)
char tib_data[TTYINQ_DATASIZE]
void ttyinq_free(struct ttyinq *ti)
static __inline void ttyinq_set_quotes(struct ttyinq_block *tib, size_t offset, size_t length, int value)
void ttyinq_flush(struct ttyinq *ti)
struct ttyinq_block * tib_prev
int ttyinq_peekchar(struct ttyinq *ti, char *c, int *quote)
void ttyinq_canonicalize(struct ttyinq *ti)
#define GETBIT(tib, boff)
void ttyinq_reprintpos_reset(struct ttyinq *ti)
void ttyinq_unputchar(struct ttyinq *ti)
uint32_t tib_quotes[TTYINQ_QUOTESIZE]
static void ttyinq_line_iterate(struct ttyinq *ti, ttyinq_line_iterator_t *iterator, void *data, unsigned int offset, struct ttyinq_block *tib)
size_t ttyinq_findchar(struct ttyinq *ti, const char *breakc, size_t maxlen, char *lastc)
#define TTYINQ_REMOVE_HEAD(ti)
static uma_zone_t ttyinq_zone
void ttyinq_setsize(struct ttyinq *ti, struct tty *tp, size_t size)
SYSCTL_INT(_kern, OID_AUTO, tty_inq_flush_secure, CTLFLAG_RW,&ttyinq_flush_secure, 0,"Zero buffers while flushing")
void ttyinq_reprintpos_set(struct ttyinq *ti)
int ttyinq_write_nofrag(struct ttyinq *ti, const void *buf, size_t nbytes, int quote)
size_t ttyinq_write(struct ttyinq *ti, const void *buf, size_t nbytes, int quote)
#define CLRBIT(tib, boff)
int uiomove(void *cp, int n, struct uio *uio)
#define TTYINQ_INSERT_TAIL(ti, tib)
int ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio, size_t rlen, size_t flen)
static int ttyinq_flush_secure
SYSINIT(ttyinq, SI_SUB_DRIVERS, SI_ORDER_FIRST, ttyinq_startup, NULL)
#define TTYINQ_RECYCLE(ti, tib)
struct ttyinq_block * tib_next
#define SETBIT(tib, boff)
void ttyinq_line_iterate_from_linestart(struct ttyinq *ti, ttyinq_line_iterator_t *iterator, void *data)