筆記一下建立/proc的方式:

#include <linux/proc_fs.h>

struct proc_dir_entry *p;

int write_tf_monitor(struct file *file, const char *buffer, int length, void *data)

{

/proc/net/tf_monitorecho 的時候要做的事情。

}

int read_tf_monitor(char *page, char **start, off_t off,int count, int *eof, void *data)

{

/porc/net/tf_monitorcat的時候要輸出的資訊。

}

static int __init init(void)

{

p = create_proc_entry("tf_monitor", 0666, init_net.proc_net);

if(p)

{

p->write_proc = write_tf_monitor;

p->read_proc = read_tf_monitor;

}

}

原先使用上述方法建立,但因為輸出的資料是像表格的樣子,若用上述的寫法,會造成上層C Code在分析資料時,
無法正確斷行,一行一行取得資料,因此改用seq_printf的方式輸出資料,所以整個建立/proc的方式,也要改變。

#include <linux/proc_fs.h>

#include <linux/seq_file.h>

static void* tfm_seq_start(struct seq_file *s, loff_t *pos);

static void* tfm_seq_next(struct seq_file *s, void *v, loff_t *pos);

static int tfm_seq_show(struct seq_file *s, void *v);

static void tfm_seq_stop (struct seq_file *s, void *v);

static int tfm_open(struct inode *inode, struct file *file);

static ssize_t tfm_write(struct file *file, const char __user *buffer, size_t length, loff_t *ppos);

static struct seq_operations tfm_seq_ops = {

.start = tfm_seq_start,

.next = tfm_seq_next,

.stop = tfm_seq_stop,

.show = tfm_seq_show

};

static struct file_operations tfm_file_ops = {

.owner = THIS_MODULE,

.open = tfm_open,

.read = seq_read,

.write = tfm_write,

.llseek = seq_lseek,

.release = seq_release

};

static int tfm_open(struct inode *inode, struct file *file)

{

return seq_open(file, &tfm_seq_ops);

}

static ssize_t tfm_write(struct file *file, const char __user *buffer, size_t length, loff_t *ppos)

{

/proc/net/tf_monitorecho的時候,要做的事情。

char s[32] = {0};

int int_s = 0;

if (length > 0)

{

memcpy(s, buffer, length);

int_s = simple_strtoul(s, NULL, 16);

printk(" s = %d\n", int_s);

}

return length;

}

/*關於seq_operations 此寫法使得能正確將資料如行輸出*/

http://cs.brynmawr.edu/Courses/cs355/spring2014/lkmpg/x861.htm (The Linux Kernel Module Programming Guide, Chapter 5. the /proc file system)

static void* tfm_seq_start(struct seq_file *s, loff_t *pos)

{

static unsigned long counter = 0;

/* beginning a new sequence ? */

if ( *pos == 0 )

{

/* yes => return a non null value to begin the sequence */

return &counter;

}

else

{

/* no => it's the end of the sequence, return end to stop reading */

*pos = 0;

return NULL;

}

}

static void* tfm_seq_next(struct seq_file *s, void *v, loff_t *pos)

{

unsigned long *tmp_v = (unsigned long *)v;

(*tmp_v)++;

(*pos)++;

return NULL;

}

static void tfm_seq_stop (struct seq_file *s, void *v)

{

}

static int tfm_seq_show(struct seq_file *s, void *v)

{

/porc/net/tf_monitorcat的時候要輸出的資訊。

loff_t *spos = (loff_t *) v;

seq_printf(s, "hash\tDEV\tIP Address\tMAC Address\t\tTX_bytes\t\tTX_pkts\t\tRX_bytes\t\tRX_pkts\t\tInit_time\t\tCur_time\n");

return 0;

}

static int __init init(void)

{

struct proc_dir_entry *p;

p = create_proc_entry("tf_monitor", 0666, init_net.proc_net);

if(p) {

p->proc_fops = &tfm_file_ops;

}

}

參考網址1:http://kartaforfun.blogspot.tw/2009/03/fileoperationsfileinode-fileoperations.html (Karta Language 重要的資料結構file_operations, file, inode)

參考網址2:http://daydreamer.idv.tw/rewrite.php/read-50.html (愛做夢的蘆薈 seq_file讀取proc資料的新選擇)

參考網址3: http://cs.brynmawr.edu/Courses/cs355/spring2014/lkmpg/x861.htm (The Linux Kernel Module Programming Guide, Chapter 5. the /proc file system)

參考網址4: http://tuxthink.blogspot.tw/2011/02/creating-readwrite-proc-entry.html

參考網址5: http://nano-chicken.blogspot.tw/2009/12/linux-modulesiv-seqfile.html (Nano 雞排 Linux Kernel-seq_file)

參考網址6: http://lwn.net/Articles/22355/ (Driver porting: The seq_file interface.)

arrow
arrow

    Yisin 發表在 痞客邦 留言(0) 人氣()