How to get process name from PID using C

我的梦境 提交于 2020-05-12 08:00:39

问题


I want to get the process name from task_struct, but I get an error dereferencing pointer to incomplete type (task->comm). I have to use pid_task function. I have no idea why it does not work.

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:


To find the task_struct of a process we can make use of the function pid_task defined in kernel/pid.c .

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

Arguments:

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

To find the pid structure if we have the pid of a process we can use the functionfind_get_pid which is also defined in kernel/pid.c

struct pid *find_get_pid(pid_t nr)

In the below module we create a read/write proc entry named task_by_pid. Which ever process we want to find the task_struct of using its pid we can write to number into the proc entry.

When we read the proc entry, it will display the name of the process corresponding to the pid we wrote into it.

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

Use the following make file to compile it:

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 

Insert it into the kernel:

$ insmod proc_task_pid.ko 

Now let us try to find the name of the process with pid "1", which is always init.

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

As expected the output is "init". Thus we can find the task_struct of any process using its pid.

Source code from here.



来源:https://stackoverflow.com/questions/29451920/how-to-get-process-name-from-pid-using-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!