2015-04-04 124 views
0

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

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; 
} 
+0

你的意思是进程名称? – MCHAppy 2015-04-04 22:21:06

+0

我的意思是进程名称。 – mariusz2108 2015-04-04 22:28:36

+0

可能的重复[完整进程名称从任务\ _struct](http://stackoverflow.com/questions/18658295/full-process-name-from-task-struct) – b4hand 2015-04-04 22:38:45

回答

1

要找到一个过程中,我们可以利用在内核/ pid.c定义的函数pid_task的task_struct中。

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 pid.c

struct pid *find_get_pid(pid_t nr) 

在下面的模块中,我们创建一个名为task_by_pid的读/写过程条目。我们希望通过哪个过程来查找使用其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); 

使用下列使文件编译:

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

+0

我必须使用'pid_task'函数 – mariusz2108 2015-04-04 22:41:45