Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- #include <linux/kernel.h>
- #include "process_ancestors.h"
- #include <linux/slab.h>
- #include <asm/uaccess.h>
- #include <linux/sched.h>
- asmlinkage long sys_process_ancestors(struct process_info info_array[], long size, long *num_filled)
- {
- struct task_struct* tmp=current;
- long i;
- int err=0;
- for(i=0;i<size;i++) {
- struct process_info inf;
- memset(&inf,0,sizeof(inf));
- //copy fields
- inf.pid=(long)tmp->pid;
- memcpy(inf.name,tmp->comm,ANCESTOR_NAME_LEN);
- inf.state=tmp->state;
- inf.uid=tmp->cred->uid.val;
- inf.nvcsw=tmp->nvcsw;
- inf.nivcsw=tmp->nivcsw;
- if((err=copy_to_user(info_array+i,&inf,sizeof(inf)))!=0) goto out;
- if(tmp->parent==NULL || tmp->parent==tmp) break;
- tmp=tmp->parent;
- }
- i++;
- err=copy_to_user(num_filled,&i,sizeof(i));
- out:
- return err;
- }
- */
- #include "process_ancestors.h"
- #include <linux/kernel.h>
- #include <linux/sched.h>
- #include <linux/string.h>
- #include <linux/cred.h>
- #include <linux/list.h>
- #include <linux/uaccess.h>
- asmlinkage long sys_process_ancestors(struct process_info info_array[],
- long size, long *num_filled) {
- struct task_struct *curr_task, *prev_task;
- long num_filled_kernel = 0;
- struct list_head *curr_node;
- if (size < 1) {
- printk("size too small\n");
- return -EINVAL;
- }
- //`current` is a pointer to a task_struct that gives us info about the process
- //that is currently executing
- curr_task = current;
- //get info associated with process in curr_task
- do {
- struct process_info inf;
- memset(&inf,0,sizeof(inf));
- //pid
- //printk("pid: %d\n", curr_task->pid);
- inf.pid = (long)curr_task->pid;
- //name
- //printk("name: %s\n", curr_task->comm);
- strcpy(inf.name, curr_task->comm);
- //state: -1 unrunnable, 0 runnable, >0 stopped
- //printk("state: %ld\n", curr_task->state);
- inf.state = curr_task->state;
- //uid
- //printk("uid: %ld\n", curr_task->cred->uid.val);
- inf.uid = curr_task->cred->uid.val;
- //nvcsw
- //printk("nvcsw: %ld\n", curr_task->nvcsw);
- inf.nvcsw = curr_task->nvcsw;
- //nivcsw
- //printk("nivcsw: %ld\n", curr_task->nivcsw);
- inf.nivcsw = curr_task->nivcsw;
- //num_children
- //`list_for_each` macro from <linux/list.h> takes a node of a circularly linked list
- //and allows us to iterate through each node of the list it is a part of
- list_for_each(curr_node, &(curr_task->children)) {
- inf.num_children++;
- }
- //printk("num_children: %ld\n", inf.num_children);
- //num_siblings
- list_for_each(curr_node, &(curr_task->sibling)) {
- inf.num_siblings++;
- }
- //printk("num_siblings: %ld\n", inf.num_siblings);
- //copy filled process_info struct to user
- if(copy_to_user(&info_array[num_filled_kernel], &inf, sizeof(inf))) {
- return -EFAULT;
- }
- //ascend one level in process hierarchy
- prev_task = curr_task;
- curr_task = curr_task->parent;
- num_filled_kernel++;
- } while (prev_task->pid != 0 && num_filled_kernel < size);
- //copy number_filled to user
- if(copy_to_user(num_filled, &num_filled_kernel, sizeof(long))) {
- return -EFAULT;
- }
- //successful
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement