seq_file.h 6.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
#ifndef _LINUX_SEQ_FILE_H
#define _LINUX_SEQ_FILE_H

#include <linux/types.h>
#include <linux/string.h>
6
#include <linux/bug.h>
I
Ingo Molnar 已提交
7
#include <linux/mutex.h>
8 9
#include <linux/cpumask.h>
#include <linux/nodemask.h>
L
Linus Torvalds 已提交
10 11 12

struct seq_operations;
struct file;
13
struct path;
L
Linus Torvalds 已提交
14
struct inode;
15
struct dentry;
16
struct user_namespace;
L
Linus Torvalds 已提交
17 18 19 20 21 22

struct seq_file {
	char *buf;
	size_t size;
	size_t from;
	size_t count;
23
	size_t pad_until;
L
Linus Torvalds 已提交
24
	loff_t index;
25
	loff_t read_pos;
26
	u64 version;
I
Ingo Molnar 已提交
27
	struct mutex lock;
28
	const struct seq_operations *op;
29
	int poll_event;
30 31 32
#ifdef CONFIG_USER_NS
	struct user_namespace *user_ns;
#endif
L
Linus Torvalds 已提交
33 34 35 36 37 38 39 40 41 42
	void *private;
};

struct seq_operations {
	void * (*start) (struct seq_file *m, loff_t *pos);
	void (*stop) (struct seq_file *m, void *v);
	void * (*next) (struct seq_file *m, void *v, loff_t *pos);
	int (*show) (struct seq_file *m, void *v);
};

43 44
#define SEQ_SKIP 1

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
/**
 * seq_has_overflowed - check if the buffer has overflowed
 * @m: the seq_file handle
 *
 * seq_files have a buffer which may overflow. When this happens a larger
 * buffer is reallocated and all the data will be printed again.
 * The overflow state is true when m->count == m->size.
 *
 * Returns true if the buffer received more than it can hold.
 */
static inline bool seq_has_overflowed(struct seq_file *m)
{
	return m->count == m->size;
}

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
/**
 * seq_get_buf - get buffer to write arbitrary data to
 * @m: the seq_file handle
 * @bufp: the beginning of the buffer is stored here
 *
 * Return the number of bytes available in the buffer, or zero if
 * there's no space.
 */
static inline size_t seq_get_buf(struct seq_file *m, char **bufp)
{
	BUG_ON(m->count > m->size);
	if (m->count < m->size)
		*bufp = m->buf + m->count;
	else
		*bufp = NULL;

	return m->size - m->count;
}

/**
 * seq_commit - commit data to the buffer
 * @m: the seq_file handle
 * @num: the number of bytes to commit
 *
 * Commit @num bytes of data written to a buffer previously acquired
 * by seq_buf_get.  To signal an error condition, or that the data
 * didn't fit in the available space, pass a negative @num value.
 */
static inline void seq_commit(struct seq_file *m, int num)
{
	if (num < 0) {
		m->count = m->size;
	} else {
		BUG_ON(m->count + num > m->size);
		m->count += num;
	}
}

98 99 100 101 102 103 104 105 106 107 108 109 110 111
/**
 * seq_setwidth - set padding width
 * @m: the seq_file handle
 * @size: the max number of bytes to pad.
 *
 * Call seq_setwidth() for setting max width, then call seq_printf() etc. and
 * finally call seq_pad() to pad the remaining bytes.
 */
static inline void seq_setwidth(struct seq_file *m, size_t size)
{
	m->pad_until = m->count + size;
}
void seq_pad(struct seq_file *m, char c);

A
Al Viro 已提交
112
char *mangle_path(char *s, const char *p, const char *esc);
113
int seq_open(struct file *, const struct seq_operations *);
L
Linus Torvalds 已提交
114 115 116 117 118 119
ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
loff_t seq_lseek(struct file *, loff_t, int);
int seq_release(struct inode *, struct file *);
int seq_escape(struct seq_file *, const char *, const char *);
int seq_putc(struct seq_file *m, char c);
int seq_puts(struct seq_file *m, const char *s);
120
int seq_write(struct seq_file *seq, const void *data, size_t len);
L
Linus Torvalds 已提交
121

122
__printf(2, 3) int seq_printf(struct seq_file *, const char *, ...);
123
__printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args);
L
Linus Torvalds 已提交
124

A
Al Viro 已提交
125
int seq_path(struct seq_file *, const struct path *, const char *);
M
Miklos Szeredi 已提交
126
int seq_file_path(struct seq_file *, struct file *, const char *);
A
Al Viro 已提交
127 128 129
int seq_dentry(struct seq_file *, struct dentry *, const char *);
int seq_path_root(struct seq_file *m, const struct path *path,
		  const struct path *root, const char *esc);
130

L
Linus Torvalds 已提交
131
int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
A
Al Viro 已提交
132
int single_open_size(struct file *, int (*)(struct seq_file *, void *), void *, size_t);
L
Linus Torvalds 已提交
133
int single_release(struct inode *, struct file *);
134 135
void *__seq_open_private(struct file *, const struct seq_operations *, int);
int seq_open_private(struct file *, const struct seq_operations *, int);
L
Linus Torvalds 已提交
136
int seq_release_private(struct inode *, struct file *);
137 138
int seq_put_decimal_ull(struct seq_file *m, char delimiter,
			unsigned long long num);
139 140
int seq_put_decimal_ll(struct seq_file *m, char delimiter,
			long long num);
L
Linus Torvalds 已提交
141

142 143 144 145 146 147 148 149 150 151
static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
{
#ifdef CONFIG_USER_NS
	return seq->user_ns;
#else
	extern struct user_namespace init_user_ns;
	return &init_user_ns;
#endif
}

152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
/**
 * seq_show_options - display mount options with appropriate escapes.
 * @m: the seq_file handle
 * @name: the mount option name
 * @value: the mount option name's value, can be NULL
 */
static inline void seq_show_option(struct seq_file *m, const char *name,
				   const char *value)
{
	seq_putc(m, ',');
	seq_escape(m, name, ",= \t\n\\");
	if (value) {
		seq_putc(m, '=');
		seq_escape(m, value, ", \t\n\\");
	}
}

/**
 * seq_show_option_n - display mount options with appropriate escapes
 *		       where @value must be a specific length.
 * @m: the seq_file handle
 * @name: the mount option name
 * @value: the mount option name's value, cannot be NULL
 * @length: the length of @value to display
 *
 * This is a macro since this uses "length" to define the size of the
 * stack buffer.
 */
#define seq_show_option_n(m, name, value, length) {	\
	char val_buf[length + 1];			\
	strncpy(val_buf, value, length);		\
	val_buf[length] = '\0';				\
	seq_show_option(m, name, val_buf);		\
}

L
Linus Torvalds 已提交
187
#define SEQ_START_TOKEN ((void *)1)
188 189 190 191 192 193 194 195 196 197 198
/*
 * Helpers for iteration over list_head-s in seq_files
 */

extern struct list_head *seq_list_start(struct list_head *head,
		loff_t pos);
extern struct list_head *seq_list_start_head(struct list_head *head,
		loff_t pos);
extern struct list_head *seq_list_next(void *v, struct list_head *head,
		loff_t *ppos);

199 200 201 202 203
/*
 * Helpers for iteration over hlist_head-s in seq_files
 */

extern struct hlist_node *seq_hlist_start(struct hlist_head *head,
204
					  loff_t pos);
205
extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head,
206
					       loff_t pos);
207
extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
208 209 210 211 212 213 214 215 216
					 loff_t *ppos);

extern struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
					      loff_t pos);
extern struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
						   loff_t pos);
extern struct hlist_node *seq_hlist_next_rcu(void *v,
						   struct hlist_head *head,
						   loff_t *ppos);
217 218 219 220 221 222

/* Helpers for iterating over per-cpu hlist_head-s in seq_files */
extern struct hlist_node *seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos);

extern struct hlist_node *seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head, int *cpu, loff_t *pos);

L
Linus Torvalds 已提交
223
#endif