summaryrefslogtreecommitdiff
path: root/fs/seq_file.c
diff options
context:
space:
mode:
authorAlexander Viro <viro@parcelfarce.linux.theplanet.co.uk>2003-05-20 06:58:17 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-05-20 06:58:17 -0700
commit32ccd2b61dfd05401528b27770ab3cd22b143641 (patch)
tree01cd62e23876962215deb49c4ff7105a65bdddfd /fs/seq_file.c
parentecdb306381de9308a484c29b28c03e2686aa00ae (diff)
[PATCH] seq_path(), /proc/mounts and /proc/swaps
This adds a new seq_...() helper: seq_path(seq_file, mnt, dentry, escape) It spits the pathname into seq_file, does octal escapes for given set of characters, returns the number of characters it'd produced or -1 in case of error. Long names are handled gracefully - you don't need anything to do, generic seq_file logics will do the right thing. /proc/mounts and /proc/swaps are converted to use of seq_path(), some junk removed. /proc/pid/maps will be converted next.
Diffstat (limited to 'fs/seq_file.c')
-rw-r--r--fs/seq_file.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 98d7a01c14a4..7a9bcab37d49 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -297,6 +297,37 @@ int seq_printf(struct seq_file *m, const char *f, ...)
return -1;
}
+int seq_path(struct seq_file *m,
+ struct vfsmount *mnt, struct dentry *dentry,
+ char *esc)
+{
+ if (m->count < m->size) {
+ char *s = m->buf + m->count;
+ char *p = d_path(dentry, mnt, s, m->size - m->count);
+ if (!IS_ERR(p)) {
+ while (s <= p) {
+ char c = *p++;
+ if (!c) {
+ p = m->buf + m->count;
+ m->count = s - m->buf;
+ return s - p;
+ } else if (!strchr(esc, c)) {
+ *s++ = c;
+ } else if (s + 4 > p) {
+ break;
+ } else {
+ *s++ = '\\';
+ *s++ = '0' + ((c & 0300) >> 6);
+ *s++ = '0' + ((c & 070) >> 3);
+ *s++ = '0' + (c & 07);
+ }
+ }
+ }
+ }
+ m->count = m->size;
+ return -1;
+}
+
static void *single_start(struct seq_file *p, loff_t *pos)
{
return NULL + (*pos == 0);