内核模块遍历进程--内核PS

4115阅读 0评论2009-12-30 ubuntuer
分类:LINUX

  让我们先来看看一个重要的结构体吧...struct task_struct 自己用sourceinsight看下在linux\sched.h里...  pid parent->pid comm就是我们要的pid ppid cmd
   注意当你添加了linux\sched.h后就有个current给你使用了,也是struct task_struct的...可以打印自身的pid cmd等
 
pid.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/sched.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("kenthy@163.com");

static int ps_read(char *page, char **start, off_t offset,int count, int *eof, void *data)
{
    static char buf[1024*8]={0};
    char tmp[128];
    struct task_struct *p;
   

    if(offset >0)
        return 0;
    memset(buf,0,sizeof(buf));
    read_lock(&tasklist_lock);
    for_each_process(p)
    {
        sprintf(tmp,"%d\t\t%d\t\t\t%s\n",p->pid,p->parent->pid,p->comm);
        strcat(buf,tmp);
        memset(tmp,0,sizeof(tmp));
    }
    read_unlock(&tasklist_lock);
    *start=buf;
    return strlen(buf);
}

static __init int ps_init(void)
{
    struct proc_dir_entry *entry;

    entry = create_proc_entry("_ps", 0444, &proc_root);
    if(entry == 0)
    {
        printk(KERN_ERR "create_proc_entry failed!\n");
        return -1;
    }
    entry->mode = S_IFREG | 0444;
    entry->size = 0;
    entry->read_proc = ps_read;

    printk("%d, %d, %s\n", current->pid, current->parent->pid, current->comm);
    return 0;
}

static __exit void ps_cleanup(void)
{
    remove_proc_entry("_ps", &proc_root);
}

module_init(ps_init);
module_exit(ps_cleanup);

 


 user.c

#include <stdio.h>
#include <error.h>

int main()
{
    FILE *fp;
    char buf[1024];

    fp=fopen("/proc/_ps","r");
    if(fp==NULL)
    {
        perror("fopen");
        return -1;
    }
    printf("pid\t\tppid\t\t\tcommand\n");
    while(!feof(fp))
    {
        if(fgets(buf,sizeof(buf),fp)!=NULL)
            printf("%s",buf);
    }
    fclose(fp);
    return 0;
}

 

Makefile:

obj-m := pid.o

KDIR := /lib/modules/$(shell uname -r)/build/
PWD := $(shell pwd)

all:module

module:
    $(MAKE) -C $(KDIR) M=$(PWD) modules


clean:
    rm -rf *.ko *.mod.c *.o Module.* modules.* .*.cmd .tmp_versions

 

可以对ps_read做如下改进

static int ps_read(char *page, char **start, off_t off,int count, int *eof, void *data)
{
            int len = 0;
            struct task_struct *p;
          
           read_lock(&tasklist_lock);
            for_each_process(p)
                     len += sprintf(page+len,"%d\t\t%d\t\t\t%s\n",p->pid,p->parent->pid,p->comm);
            read_unlock(&tasklist_lock);

            if (len <= off+count) *eof = 1;
            *start = page + off;
            len -= off;
            if (len>count) len = count;
            if (len<0) len = 0;
            return len;
}

 

 for_each_process(p)遍历每一个进程

 
还可以用seq写个
 

#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);


上一篇:inotify实例
下一篇:GNU Linux核心命令和工具的源代码路径