netdev
[Top] [All Lists]

[PATCH] convert /proc/net/unix to seq_file

To: "David S. Miller" <davem@xxxxxxxxxx>
Subject: [PATCH] convert /proc/net/unix to seq_file
From: Stephen Hemminger <shemminger@xxxxxxxx>
Date: Thu, 4 Sep 2003 11:49:22 -0700
Cc: netdev@xxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx
Organization: Open Source Development Lab
Sender: netdev-bounce@xxxxxxxxxxx
Applies against 2.6.0-test4.


diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c        Thu Sep  4 10:35:58 2003
+++ b/net/unix/af_unix.c        Thu Sep  4 10:35:58 2003
@@ -111,6 +111,7 @@
 #include <linux/tcp.h>
 #include <net/af_unix.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <net/scm.h>
 #include <linux/init.h>
 #include <linux/poll.h>
@@ -1805,25 +1806,52 @@
 
 
 #ifdef CONFIG_PROC_FS
-static int unix_read_proc(char *buffer, char **start, off_t offset,
-                         int length, int *eof, void *data)
+static struct sock *unix_seq_idx(int *iter, loff_t pos)
 {
-       off_t pos=0;
-       off_t begin=0;
-       int len=0;
-       int i;
+       loff_t off = 0;
        struct sock *s;
-       
-       len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St "
-           "Inode Path\n");
 
+       for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) {
+               if (off == pos) 
+                       return s;
+               ++off;
+       }
+       return NULL;
+}
+
+
+static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
+{
        read_lock(&unix_table_lock);
-       forall_unix_sockets (i,s)
-       {
+       return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
+}
+
+static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       ++*pos;
+
+       if (v == (void *)1) 
+               return first_unix_socket(seq->private);
+       return next_unix_socket(seq->private, v);
+}
+
+static void unix_seq_stop(struct seq_file *seq, void *v)
+{
+       read_unlock(&unix_table_lock);
+}
+
+static int unix_seq_show(struct seq_file *seq, void *v)
+{
+       
+       if (v == (void *)1)
+               seq_puts(seq, "Num       RefCount Protocol Flags    Type St "
+                        "Inode Path\n");
+       else {
+               struct sock *s = v;
                struct unix_sock *u = unix_sk(s);
                unix_state_rlock(s);
 
-               len+=sprintf(buffer+len,"%p: %08X %08X %08X %04X %02X %5lu",
+               seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
                        s,
                        atomic_read(&s->sk_refcnt),
                        0,
@@ -1835,39 +1863,61 @@
                        sock_i_ino(s));
 
                if (u->addr) {
-                       buffer[len++] = ' ';
-                       memcpy(buffer+len, u->addr->name->sun_path,
-                              u->addr->len-sizeof(short));
-                       if (!UNIX_ABSTRACT(s))
-                               len--;
-                       else
-                               buffer[len] = '@';
-                       len += u->addr->len - sizeof(short);
-               }
-               unix_state_runlock(s);
+                       int i;
+                       seq_putc(seq, ' ');
+                       
+                       for (i = 0; i < u->addr->len-sizeof(short); i++)
+                               seq_putc(seq, u->addr->name->sun_path[i]);
 
-               buffer[len++]='\n';
-               
-               pos = begin + len;
-               if(pos<offset)
-               {
-                       len=0;
-                       begin=pos;
+                       if (UNIX_ABSTRACT(s))
+                               seq_putc(seq, '@');
                }
-               if(pos>offset+length)
-                       goto done;
+               unix_state_runlock(s);
+               seq_putc(seq, '\n');
        }
-       *eof = 1;
-done:
-       read_unlock(&unix_table_lock);
-       *start=buffer+(offset-begin);
-       len-=(offset-begin);
-       if(len>length)
-               len=length;
-       if (len < 0)
-               len = 0;
-       return len;
+
+       return 0;
+}
+
+struct seq_operations unix_seq_ops = {
+       .start  = unix_seq_start,
+       .next   = unix_seq_next,
+       .stop   = unix_seq_stop,
+       .show   = unix_seq_show,
+};
+
+
+static int unix_seq_open(struct inode *inode, struct file *file)
+{
+       struct seq_file *seq;
+       int rc = -ENOMEM;
+       int *iter = kmalloc(sizeof(int), GFP_KERNEL);
+
+       if (!iter)
+               goto out;
+
+       rc = seq_open(file, &unix_seq_ops);
+       if (rc)
+               goto out_kfree;
+
+       seq          = file->private_data;
+       seq->private = iter;
+       *iter = 0;
+out:
+       return rc;
+out_kfree:
+       kfree(iter);
+       goto out;
 }
+
+static struct file_operations unix_seq_fops = {
+       .owner          = THIS_MODULE,
+       .open           = unix_seq_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release_private,
+};
+
 #endif
 
 struct proto_ops unix_stream_ops = {
@@ -1947,7 +1997,7 @@
 
        sock_register(&unix_family_ops);
 #ifdef CONFIG_PROC_FS
-       create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL);
+       proc_net_fops_create("unix", 0, &unix_seq_fops);
 #endif
        unix_sysctl_register();
        return 0;
@@ -1957,7 +2007,7 @@
 {
        sock_unregister(PF_UNIX);
        unix_sysctl_unregister();
-       remove_proc_entry("net/unix", 0);
+       proc_net_remove("unix");
        kmem_cache_destroy(unix_sk_cachep);
 }
 

<Prev in Thread] Current Thread [Next in Thread>