#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h> //proc_fs
#include <linux/seq_file.h> //seq_file
#include <linux/fs.h> //struct file,struct inode
#include <linux/sched.h> //next_task()
MODULE_AUTHOR("xunil@bmy");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("a test module utilise the seq_file mechanism");
static void *ps_seq_start(struct seq_file *s,loff_t *pos){
struct task_struct *task;
seq_printf(s,"%s\t%s\t%s\t%s\t%s\n","pid","ppid","uid","gid","comm");
if(*pos>0)
return NULL;
else{
task=next_task(current);
return task;
}
}
static void *ps_seq_next(struct seq_file *s,void *v,loff_t *pos){
struct task_struct *task=(struct task_struct *)v;
++*pos;
if(task->pid== current->pid){
return NULL;
}else{
task=next_task(task);
return task;
}
}
static void ps_seq_stop(struct seq_file *s,void *v){}
static int ps_seq_show(struct seq_file *s,void *v){
rwlock_t lock = RW_LOCK_UNLOCKED;
struct task_struct *task=(struct task_struct *)v;
read_lock(&lock);
seq_printf(s,"%d\t%d\t%d\t%d\t%s\n",task->pid,task->parent->pid,task->uid,task->gid,task->comm);
read_unlock(&lock);
return 0;
}
static struct seq_operations ps_seq_ops = {
.start = ps_seq_start,
.next = ps_seq_next,
.stop = ps_seq_stop,
.show = ps_seq_show
};
static int ps_open(struct inode *inode,struct file *file){
return seq_open(file,&ps_seq_ops);
}
static struct file_operations ps_file_ops = {
.owner = THIS_MODULE,
.open = ps_open,
.read = seq_read,
.llseek = seq_lseek,
.release= seq_release
};
static int __init ps_init(void){
struct proc_dir_entry *entry;
entry = create_proc_entry("myps",0,NULL);
if(entry)
entry->proc_fops = &ps_file_ops;
return 0;
}
static void __exit ps_exit(void){
remove_proc_entry("myps",NULL);
}
module_init(ps_init);
module_exit(ps_exit);