如何使用C从PID获取进程名称

时间:2015-04-04 22:09:00

标签: c kernel pid

我想从task_struct获取进程名称,但是 我得到一个错误,取消引用指向不完整类型的指针(task-> comm)。 我必须使用pid_task函数。 我不知道为什么它不起作用。

ssize_t simple_read(struct file *filp, char __user *user_buf, size_t count, loff_t *f_pos) {

    int len=0;
    pid_struct = find_get_pid(pid);
    task = pid_task(pid_struct,PIDTYPE_PID);

    len = sprintf(user_buf,"\nname %s\n ",task->comm);
    return len;
}

1 个答案:

答案 0 :(得分:2)

要查找进程的task_struct,我们可以使用kernel / pid.c中定义的函数pid_task。

struct task_struct *pid_task(struct pid *pid, enum pid_type type)

参数:

pid : Pointer to the struct pid of the process. 
pid_type:  PIDTYPE_PID,
       PIDTYPE_PGID,
          PIDTYPE_SID,
          PIDTYPE_MAX

要找到pid结构,如果我们有一个进程的pid,我们可以使用functionfind_get_pid,它也在kernel / pid.c中定义。

struct pid *find_get_pid(pid_t nr)

在下面的模块中,我们创建一个名为task_by_pid的读/写proc条目。我们想要找到使用其pid的task_struct的哪个进程,我们可以将数字写入proc条目。

当我们读取proc条目时,它将显示与我们写入其中的pid相对应的进程的名称。

proc_task_pid:

#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/fs.h> 
#include <linux/cdev.h>
#include <linux/proc_fs.h>
#include <linux/pid.h>

#include <linux/pid_namespace.h>
int p_id;
struct pid *pid_struct;
struct task_struct *task;
static struct proc_dir_entry *proc_write_entry;
char *proc_name="task_by_pid";

int read_proc(char *buf,char **start,off_t offset,int count,int *eof,void *data )
{
int len=0;
pid_struct = find_get_pid(p_id);
task = pid_task(pid_struct,PIDTYPE_PID);

 len = sprintf(buf,"\nname %s\n ",task->comm);

return len;
}

int write_proc(struct file *file,const char *buf,int count,void *data )
{
int ret;
char *id;
id = (char *)kmalloc(1000*sizeof(char),GFP_KERNEL);
printk(KERN_INFO "buf passed %s",buf);
if(copy_from_user(id,buf,count))
    return -EFAULT;
printk(KERN_INFO "id passed %s",id);
p_id = simple_strtoul(id,NULL,0);
printk(KERN_INFO "pid %d ret %d",p_id,ret);
return sizeof(buf);
}

void create_new_proc_entry()
{
proc_write_entry = create_proc_entry(proc_name,0666,NULL);
if(!proc_write_entry)
      {
    printk(KERN_INFO "Error creating proc entry");
    return -ENOMEM;
    }
proc_write_entry->read_proc = read_proc ;
proc_write_entry->write_proc = write_proc;
printk(KERN_INFO "proc initialized");

}



int proc_init (void) {
    create_new_proc_entry();
    return 0;
}

void proc_cleanup(void) {
    printk(KERN_INFO " Inside cleanup_module\n");
    remove_proc_entry(proc_name,NULL);
}
MODULE_LICENSE("GPL");   
module_init(proc_init);
module_exit(proc_cleanup);

使用以下make文件进行编译:

ifneq ($(KERNELRELEASE),) 
   obj-m := proc_task_pid.o
else 

KERNELDIR ?= /lib/modules/$(shell uname -r)/build 

PWD := $(shell pwd)

default: 
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif 
clean:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) clean

Compile it using 

$make 

将其插入内核:

$ insmod proc_task_pid.ko 

现在让我们尝试使用pid“1”找到进程的名称,它始终是init。

$ printf "1" > /proc/task_by_pid 
$ cat /proc/task_by_pid
name init

正如预期的那样,输出是“init”。因此,我们可以使用其pid找到任何进程的task_struct。

来自here的源代码。