#include <linux/module.h> #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> MODULE_LICENSE("Dual BSD/GPL"); #define PROCNAME "sample" static char *data_message[] = { "Fedora", "Red Hat", "Debian", "Ubuntu", 0 }; static void *as_start(struct seq_file *m, loff_t *pos) { loff_t n = *pos; char **ptr; int i; seq_printf(m, "%lld (%s)\n", n, __func__); if (n == 0) seq_printf(m, "=== seq_file header ===\n"); ptr = data_message; for (i = 0; ptr[i]; i++) { n--; if (n < 0) { return (void *) (i + 1); } } return 0; } static void *as_next(struct seq_file *m, void *p, loff_t *pos) { int n = (int) p; char **ptr; seq_printf(m, "%u (%s)\n", n, __func__); (*pos)++; ptr = data_message; if (ptr[n]) return (void *) (n + 1); return 0; } static void as_stop(struct seq_file *m, void *p) { int n = (int) p; seq_printf(m, "%u (%s)\n", n, __func__); } static int as_show(struct seq_file *m, void *p) { int n = (int) p - 1; seq_printf(m, "%u (%s)\n", (int) p, __func__); seq_printf(m, "[%d] %s\n", n, data_message[n]); return 0; } /* seq_file handler */ static struct seq_operations sample_seq_op = { .start = as_start, .next = as_next, .stop = as_stop, .show = as_show, }; static int sample_proc_open(struct inode *inode, struct file *file) { return seq_open(file, &sample_seq_op); } /* procfs handler */ static struct file_operations sample_proc_fops = { .open = sample_proc_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, }; static int sample_init(void) { #if 1 struct proc_dir_entry *entry; entry = create_proc_entry(PROCNAME, S_IRUGO | S_IWUGO, NULL); if (entry) entry->proc_fops = &sample_proc_fops; #else proc_create(PROCNAME, 0, NULL, &sample_proc_fops); #endif printk(KERN_INFO "driver loaded\n"); return 0; } static void sample_exit(void) { remove_proc_entry(PROCNAME, NULL); printk(KERN_INFO "driver unloaded\n"); } module_init(sample_init); module_exit(sample_exit);
2018年2月13日 星期二
Linux kernel - 建立/sys文件系统訪問kernel - seq_open
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言