Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_SEQ_BUF_H
0003 #define _LINUX_SEQ_BUF_H
0004 
0005 #include <linux/fs.h>
0006 
0007 /*
0008  * Trace sequences are used to allow a function to call several other functions
0009  * to create a string of data to use.
0010  */
0011 
0012 /**
0013  * seq_buf - seq buffer structure
0014  * @buffer: pointer to the buffer
0015  * @size:   size of the buffer
0016  * @len:    the amount of data inside the buffer
0017  * @readpos:    The next position to read in the buffer.
0018  */
0019 struct seq_buf {
0020     char            *buffer;
0021     size_t          size;
0022     size_t          len;
0023     loff_t          readpos;
0024 };
0025 
0026 static inline void seq_buf_clear(struct seq_buf *s)
0027 {
0028     s->len = 0;
0029     s->readpos = 0;
0030 }
0031 
0032 static inline void
0033 seq_buf_init(struct seq_buf *s, char *buf, unsigned int size)
0034 {
0035     s->buffer = buf;
0036     s->size = size;
0037     seq_buf_clear(s);
0038 }
0039 
0040 /*
0041  * seq_buf have a buffer that might overflow. When this happens
0042  * the len and size are set to be equal.
0043  */
0044 static inline bool
0045 seq_buf_has_overflowed(struct seq_buf *s)
0046 {
0047     return s->len > s->size;
0048 }
0049 
0050 static inline void
0051 seq_buf_set_overflow(struct seq_buf *s)
0052 {
0053     s->len = s->size + 1;
0054 }
0055 
0056 /*
0057  * How much buffer is left on the seq_buf?
0058  */
0059 static inline unsigned int
0060 seq_buf_buffer_left(struct seq_buf *s)
0061 {
0062     if (seq_buf_has_overflowed(s))
0063         return 0;
0064 
0065     return s->size - s->len;
0066 }
0067 
0068 /* How much buffer was written? */
0069 static inline unsigned int seq_buf_used(struct seq_buf *s)
0070 {
0071     return min(s->len, s->size);
0072 }
0073 
0074 /**
0075  * seq_buf_terminate - Make sure buffer is nul terminated
0076  * @s: the seq_buf descriptor to terminate.
0077  *
0078  * This makes sure that the buffer in @s is nul terminated and
0079  * safe to read as a string.
0080  *
0081  * Note, if this is called when the buffer has overflowed, then
0082  * the last byte of the buffer is zeroed, and the len will still
0083  * point passed it.
0084  *
0085  * After this function is called, s->buffer is safe to use
0086  * in string operations.
0087  */
0088 static inline void seq_buf_terminate(struct seq_buf *s)
0089 {
0090     if (WARN_ON(s->size == 0))
0091         return;
0092 
0093     if (seq_buf_buffer_left(s))
0094         s->buffer[s->len] = 0;
0095     else
0096         s->buffer[s->size - 1] = 0;
0097 }
0098 
0099 /**
0100  * seq_buf_get_buf - get buffer to write arbitrary data to
0101  * @s: the seq_buf handle
0102  * @bufp: the beginning of the buffer is stored here
0103  *
0104  * Return the number of bytes available in the buffer, or zero if
0105  * there's no space.
0106  */
0107 static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp)
0108 {
0109     WARN_ON(s->len > s->size + 1);
0110 
0111     if (s->len < s->size) {
0112         *bufp = s->buffer + s->len;
0113         return s->size - s->len;
0114     }
0115 
0116     *bufp = NULL;
0117     return 0;
0118 }
0119 
0120 /**
0121  * seq_buf_commit - commit data to the buffer
0122  * @s: the seq_buf handle
0123  * @num: the number of bytes to commit
0124  *
0125  * Commit @num bytes of data written to a buffer previously acquired
0126  * by seq_buf_get.  To signal an error condition, or that the data
0127  * didn't fit in the available space, pass a negative @num value.
0128  */
0129 static inline void seq_buf_commit(struct seq_buf *s, int num)
0130 {
0131     if (num < 0) {
0132         seq_buf_set_overflow(s);
0133     } else {
0134         /* num must be negative on overflow */
0135         BUG_ON(s->len + num > s->size);
0136         s->len += num;
0137     }
0138 }
0139 
0140 extern __printf(2, 3)
0141 int seq_buf_printf(struct seq_buf *s, const char *fmt, ...);
0142 extern __printf(2, 0)
0143 int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
0144 extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s);
0145 extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf,
0146                int cnt);
0147 extern int seq_buf_puts(struct seq_buf *s, const char *str);
0148 extern int seq_buf_putc(struct seq_buf *s, unsigned char c);
0149 extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len);
0150 extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem,
0151                   unsigned int len);
0152 extern int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc);
0153 extern int seq_buf_hex_dump(struct seq_buf *s, const char *prefix_str,
0154                 int prefix_type, int rowsize, int groupsize,
0155                 const void *buf, size_t len, bool ascii);
0156 
0157 #ifdef CONFIG_BINARY_PRINTF
0158 extern int
0159 seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary);
0160 #endif
0161 
0162 #endif /* _LINUX_SEQ_BUF_H */