Question

I would like to know - if possible - how to get the pid of a process' grandparent (or further).

To be more specific, I want for a process to print its depth in a process tree. For example, when starting with the following:

int main() {
    int creator_id = (int) getpid();
    pid_t pid1 = fork();
    pid_t pid2 = fork();
    pid_t pid3 = fork();        

    //print depth in process tree of each process

    return 0;
}

According to my theory, the tree will look like this:

               0
              /|\ 
             / | \
            /  |  \
           0   0   0
          / \  |            
         0   0 0  
        /            
       0

So my first idea was to somehow see how often I have to go up until I find the creator's pid.

As a little sidenote: I also wondered if it was possible to make the printing from bottom up, meaning that all processes in the deepest level would print first.

No correct solution

OTHER TIPS

how to get the pid of a process' grandparent (or further).

This depends on which operating system you are using, since you use fork() to create new process in your example, I suppose you are using some Unix-like system.

If you are using Linux and know the pid of a process, you could get its parent process' pid from /proc/[pid]/stat, the fourth field in that file. Through this parent-child chain, you could find a process' all ancestors.

Following @Lee Duhem's hint, I made the following function that returns the nth ancestor of the current process (the 2nd ancestor is the grandparent).

/* Get the process ID of the calling process's nth ancestor. */
pid_t getapid(int n) {
  pid_t pid = getpid();

  while(n>0 && pid){ // process with pid 0 has no parent

    // strlen("/proc/") == 6
    // max [pid] for 64 bits is 4194304 then strlen("[pid]") < 7
    // strlen("/stat") == 5
    // then strlen("/proc/[pid]/stat") < 6 + 7 + 5
    char proc_stat_path[6+7+5+1];
    sprintf(proc_stat_path, "/proc/%d/stat", pid);

    // open "/proc/<pid>/stat"
    FILE *fh = fopen(proc_stat_path, "r");
    if (fh == NULL) {
      fprintf(stderr, "Failed opening %s: ", proc_stat_path);
      perror("");
      exit(1);
    }

    // seek to the last ')'
    int c;
    long pos = 0;
    while ((c = fgetc(fh)) != EOF) {
      if (c == ')')
        pos = ftell(fh);
    }
    fseek(fh, pos, SEEK_SET);

    // get parent 
    fscanf(fh, " %*c %d", &pid);

    // close "/proc/<pid>/stat"
    fclose(fh);

    // decrement n
    n--;
  }

  if(n>0)
    return -1;
  else
    return pid;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top