linux内核之遍历文件描述符

该项工作主要分为两部,其一获得特定进程的名字,找到指定进程的task_struct

其二根据task_struct获得文件对象表struct file,其代码如下:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include<linux/sched.h>
#include<linux/dcache.h>
#include<linux/fdtable.h>
#include<linux/string.h>
#include <linux/fcntl.h>//for O_RDONLY
#include <linux/uaccess.h>//for get_fs
#include <linux/limits.h>//for PATH_MAX 
#include <linux/mm.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");


extern char *d_path(const struct path *, char *, int); 
extern char *dentry_path_raw(struct dentry *, char *, int);
static int hello_init(void)
{
	printk(KERN_ALERT "My Kernel Begin\n");
	if(NULL==current)
	{
		printk(KERN_ALERT "get current failed \n");
		return 0;
	}
	printk(KERN_ALERT "get current successfully \n");
	struct task_struct *task; 
	struct list_head *list;
	for(list=(&(current->tasks))->next; list!=¤t->tasks; list=list->next) 
	{
		task=list_entry(list, struct task_struct, tasks); 
		if(strstr(task->comm,"gedit")!=NULL)//获得指定进程的task_struct
		{	
			
			task_lock(task);
			printk(KERN_ALERT "this is process %s\n",task->comm);
			char * tpath= NULL;			
			tpath=(char*)kmalloc(2048,GFP_KERNEL);
			char *tmp=(char*)kmalloc(2048,GFP_KERNEL);
			if(tpath==NULL||tmp==NULL)
				return 0;
			int i=0;
			struct files_struct*files=task->files;
			if(NULL!=files)
			{
				struct fdtable* fdt=files->fdt;				
				while(fdt!=NULL)
				{
					i=0;
					for(;i<NR_OPEN_DEFAULT;i++)//默认打开表是NR_OPEN_DEFAULT
					{
						char* path=NULL;
						struct file* file=fdt->fd[i];
						if(file!=NULL&&file->f_path.dentry!=NULL)
						{	
							char*result=NULL;
							if(file->f_path.dentry->d_name.name!=NULL)
								result==strstr(file->f_path.dentry->d_name.name,".c");//查找制定类型的文件
							if(result!=NULL)
							{
								printk(KERN_ALERT "maybe this is our file\n");
								printk(KERN_ALERT "FILE NAME IS :%s\n",file->f_path.dentry->d_name.name);
								memset(tmp,0,2048);
								if((file->f_path.dentry!=NULL)&&(file->f_path.mnt!=NULL))
									path = d_path(&(file->f_path),tmp,2048);
								if(path!=NULL)
								{
									memset(tpath,0,2048);
									strcpy(tpath,path);
									printk(KERN_ALERT "the file name is %s\n",tpath);
									memset(path,0,2048);
								}
							}
							else
							{
								printk(KERN_ALERT "NOT MY WANT\n");
							}
						}
					}
					fdt=fdt->next;
				}
			}
			task_unlock(task);
			kfree(tpath);
			kfree(tmp);
		}
	}
	return 0;
}
	
	



static void hello_exit(void)
{
      printk(KERN_ALERT "Goodbye,Cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit); 

其makefile如下

obj-m := hello.o
all:
	make -C /lib/modules/`uname -r`/build SUBDIRS=$(PWD) modules  #`uname -r` 指的是linux的版本号  $(PWD)当前目录
clean:
	make -C /lib/modules/`uname -r`/build SUBDIRS=$(PWD) clean    

#就是说首先改变目录到-C选项指定的目录(即内核源代码目录),SUBDIRS=选项让该makefile在构造modules目标返回之前到模块源代码目录。然后,modules目标指向obj-m变量设定的模块。
    # subsystem:

           cd subdir && $(MAKE)

其等价于:

    subsystem:

           $(MAKE) -C subdir
    $(MAKE) -C subdir

定义$(MAKE)宏变量的意思是,也许我们的make需要一些参数,所以定义成一个变量比较利于维护。这两个例子的意思都是先进入“subdir”目录,然后执行make命令。

我们把这个Makefile叫做“总控Makefile”,总控Makefile的变量可以传递到下级的Makefile中(如果你显示的声明),但是不会覆盖下层的Makefile中所定义的变量,除非指定了“-e”

使用make编译连接之后,sudo insmod ./hello.ko即可

使用

tail -100 /var/log/syslog

查看输出信息


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世纪殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值