Find the answer to your Linux question:
Results 1 to 4 of 4
Getting task_struct of current process is easy that is: Code: struct task_struct *cur_task; cur_task = get_current(); But I want to get task_struct of a process specified by its pid. e.g ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Oct 2009
    Posts
    3

    Getting task_struct of a process using its pid ?


    Getting task_struct of current process is easy that is:

    Code:
    struct task_struct *cur_task;
    cur_task = get_current();
    But I want to get task_struct of a process specified by its pid.

    e.g I want to get task_struct of a process whose pid = 1234

  2. #2
    Just Joined! probe's Avatar
    Join Date
    Oct 2009
    Location
    Belgrade, Serbia
    Posts
    29
    Here are two programs who gives you some info about process
    based on pid, but they do not return task_struct. But if they
    provide enough info you can populate task_struct yourself.

    1. Print the Argument List of a Running Process

    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    /* Prints the argument list, one argument to a line, of the process
    given by PID. */
    void print_process_arg_list (pid_t pid)
    {
    int fd;
    char filename[24];
    char arg_list[1024];
    size_t length;
    char* next_arg;
    /* Generate the name of the cmdline file for the process. */
    snprintf (filename, sizeof (filename), “/proc/%d/cmdline”, (int) pid);
    /* Read the contents of the file. */
    fd = open (filename, O_RDONLY);
    length = read (fd, arg_list, sizeof (arg_list));
    close (fd);
    /* read does not NUL-terminate the buffer, so do it here. */
    arg_list[length] = ‘\0’;
    /* Loop over arguments. Arguments are separated by NULs. */
    next_arg = arg_list;
    while (next_arg < arg_list + length) {
    /* Print the argument. Each is NUL-terminated, so just treat it
    like an ordinary string. */
    printf (“%s\n”, next_arg);
    /* Advance to the next argument. Since each argument is
    NUL-terminated, strlen counts the length of the next argument,
    not the entire argument list. */
    next_arg += strlen (next_arg) + 1;
    }
    }
    int main (int argc, char* argv[])
    {
    pid_t pid = (pid_t) atoi (argv[1]);
    print_process_arg_list (pid);
    return 0;
    }

    2. Display the Environment of a Process

    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    /* Prints the environment, one environment variable to a line, of the
    process given by PID. */
    void print_process_environment (pid_t pid)
    {
    int fd;
    char filename[24];
    char environment[8192];
    size_t length;
    char* next_var;
    /* Generate the name of the environ file for the process. */
    snprintf (filename, sizeof (filename), “/proc/%d/environ”, (int) pid);
    /* Read the contents of the file. */
    fd = open (filename, O_RDONLY);
    length = read (fd, environment, sizeof (environment));
    close (fd);
    /* read does not NUL-terminate the buffer, so do it here. */
    environment[length] = ‘\0’;
    /* Loop over variables. Variables are separated by NULs. */
    next_var = environment;
    while (next_var < environment + length) {
    /* Print the variable. Each is NUL-terminated, so just treat it
    like an ordinary string. */
    printf (“%s\n”, next_var);
    /* Advance to the next variable. Since each variable is
    NUL-terminated, strlen counts the length of the next variable,
    not the entire variable list. */
    next_var += strlen (next_var) + 1;
    }
    }
    int main (int argc, char* argv[])
    {
    pid_t pid = (pid_t) atoi (argv[1]);
    print_process_environment (pid);
    return 0;
    }

    ------------

    Regards !

  3. #3
    Just Joined!
    Join Date
    Oct 2009
    Posts
    3
    Thanks for the reply.

    The code you have written works at user level. I am trying to make it a system call that is at kernel level.

    I have written all the code to get the info of current process.

    One solution I have in mind is that to traverse the processes' link list in which each process is a "task_struct" structure and check each of these and get all the info from desired process. but it will become a spaghetti.

    I was thinking if there is any function to get the "task_struct" of a specific process at kernel level. like getting "task_ struct" of current process using "get_current" method.

    Regards,
    Shujaat

  4. #4
    Just Joined! probe's Avatar
    Join Date
    Oct 2009
    Location
    Belgrade, Serbia
    Posts
    29
    Ok,

    I found it, but unfortunately it is working for Linux kernel 2.4, but I am sure it can gives us insight to find it in kernel 2.6

    Here is text for 2.4 :
    -----------------------------------------------------------------------------------
    The set of processes on the Linux system is represented as a collection of struct task_struct structures which are linked in two ways:

    1. as a hashtable, hashed by pid, and
    2. as a circular, doubly-linked list using p->next_task and p->prev_task pointers.

    The hashtable is called pidhash[] and is defined in include/linux/sched.h:

    /* PID hashing. (shouldnt this be dynamic?) */
    #define PIDHASH_SZ (4096 >> 2)
    extern struct task_struct *pidhash[PIDHASH_SZ];

    #define pid_hashfn(x) ((((x) >> ^ (x)) & (PIDHASH_SZ - 1))

    The tasks are hashed by their pid value and the above hashing function is supposed to distribute the elements uniformly in their domain (0 to PID_MAX-1). The hashtable is used to quickly find a task by given pid, using find_task_pid() inline from include/linux/sched.h:

    static inline struct task_struct *find_task_by_pid(int pid)
    {
    struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];

    for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
    ;

    return p;
    }
    -----------------------------------------------------------------------------------

    So, I looked code for include/linux/sched.h on Linux online code site [lxr]
    There is no more hashtable called pidhash[] there, but there is

    extern struct task_struct *find_task_by_pid_ns(pid_t nr,
    struct pid_namespace *ns);

    Try to use this and let me know what happens. I will try it myself but at the moment I am little busy,

    regards !

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •