On Fri, Jul 28, 2000 at 02:47:31PM -0700, H. Peter Anvin wrote:
> Andries Brouwer wrote:
> > On Fri, Jul 28, 2000 at 01:19:55PM -0700, H. Peter Anvin wrote:
> >
> > > Also, /proc/mounts is impossible to parse cleanly -- if you
> > > have mount points with spaces or \n
> >
> > Probably confusion is minimized if the kernel follows what
> > mount already does.
> >
> > # mount /dev/hde5 /mnt/"my dir"
> > # mount | tail -1
> > /dev/hde5 on /mnt/my dir type ext2 (rw)
> > # tail -1 /etc/mtab
> > /dev/hde5 /mnt/my\040dir ext2 rw 0 0
>
> That's perfectly fine with me, and would make a lot of sense. This
> isn't the only place in /proc where a standard escape sequence system is
> needed.
OK. Patch below.
Andries
--- ../../../linux-2.4.0test5/linux/fs/super.c Sat Jul 29 02:59:10 2000
+++ super.c Sat Jul 29 15:39:39 2000
@@ -428,6 +428,33 @@
kfree(mnt);
}
+
+/* Use octal escapes, like mount does, for embedded spaces etc. */
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static int
+mangle(const unsigned char *s, char *buf, int len) {
+ char *sp;
+ int n;
+
+ sp = buf;
+ while(*s && sp-buf < len-3) {
+ for (n = 0; n < sizeof(need_escaping); n++) {
+ if (*s == need_escaping[n]) {
+ *sp++ = '\\';
+ *sp++ = '0' + ((*s & 0300) >> 6);
+ *sp++ = '0' + ((*s & 070) >> 3);
+ *sp++ = '0' + (*s & 07);
+ goto next;
+ }
+ }
+ *sp++ = *s;
+ next:
+ s++;
+ }
+ return sp - buf; /* no trailing NUL */
+}
+
static struct proc_fs_info {
int flag;
char *str;
@@ -466,27 +493,32 @@
struct proc_fs_info *fs_infop;
struct proc_nfs_info *nfs_infop;
struct nfs_server *nfss;
- int len = 0;
- char *path,*buffer = (char *) __get_free_page(GFP_KERNEL);
+ int len, prevlen;
+ char *path, *buffer = (char *) __get_free_page(GFP_KERNEL);
if (!buffer) return 0;
- for (p = vfsmntlist.next; p!=&vfsmntlist && len < PAGE_SIZE - 160;
- p = p->next) {
+ len = prevlen = 0;
+
+#define FREEROOM ((int)PAGE_SIZE-200-len)
+#define MANGLE(s) len += mangle((s), buf+len, FREEROOM);
+
+ for (p = vfsmntlist.next; p != &vfsmntlist; p = p->next) {
struct vfsmount *tmp = list_entry(p, struct vfsmount, mnt_list);
if (!(tmp->mnt_flags & MNT_VISIBLE))
continue;
path = d_path(tmp->mnt_root, tmp, buffer, PAGE_SIZE);
if (!path)
continue;
- len += sprintf( buf + len, "%s %s %s %s",
- tmp->mnt_devname ? tmp->mnt_devname : "none", path,
- tmp->mnt_sb->s_type->name,
- tmp->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw" );
+ MANGLE(tmp->mnt_devname ? tmp->mnt_devname : "none");
+ buf[len++] = ' ';
+ MANGLE(path);
+ buf[len++] = ' ';
+ MANGLE(tmp->mnt_sb->s_type->name);
+ len += sprintf(buf+len, " %s",
+ tmp->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
- if (tmp->mnt_sb->s_flags & fs_infop->flag) {
- strcpy(buf + len, fs_infop->str);
- len += strlen(fs_infop->str);
- }
+ if (tmp->mnt_sb->s_flags & fs_infop->flag)
+ MANGLE(fs_infop->str);
}
if (!strcmp("nfs", tmp->mnt_sb->s_type->name)) {
nfss = &tmp->mnt_sb->u.nfs_sb.s_server;
@@ -527,17 +559,24 @@
str = nfs_infop->str;
else
str = nfs_infop->nostr;
- strcpy(buf + len, str);
- len += strlen(str);
+ MANGLE(str);
}
- len += sprintf(buf+len, ",addr=%s",
- nfss->hostname);
+ len += sprintf(buf+len, ",addr=");
+ MANGLE(nfss->hostname);
+ }
+ len += sprintf(buf + len, " 0 0\n");
+ if (FREEROOM <= 3) {
+ len = prevlen;
+ len += sprintf(buf+len, "# truncated\n");
+ break;
}
- len += sprintf( buf + len, " 0 0\n" );
+ prevlen = len;
}
free_page((unsigned long) buffer);
return len;
+#undef MANGLE
+#undef FREEROOM
}
/**
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Mon Jul 31 2000 - 21:00:30 EST