sergiodev
sergiodev

Reputation: 1

How do I get the children PID by a system call?

I compiled and install a new version of the kernel and now I have to make the new kernel support two new primitives, I explain more below

I have this file, mysystemcalls-test.c where I get the process and do forks in a for iteration. This is my test file.

//mysyscalls-test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <mysyscalls.h>

#define NCHILDREN 10

int main()
{

  int pids[NCHILDREN], i;
  int original_parent = getpid();

  printf ("before fork: current number of children: %ld\n", getnchildren(1));

  for (i=0; i<NCHILDREN; i++) {
    pids[i] = fork();

    if (pids[i] == 0) {
    while (getppid() == original_parent);
      exit(0);
    }
  }
printf("after fork: current number of children: %ld\n", getnchildren(1));

for(i=0; i<NCHILDREN; i++)
  printf("pids[%d]:%d\tgetcpid(%d,1):%ld\n" ,i,pids[i],i,getcpid(i,1));

return 0;
}

The real problem is in the second file, mysyscalls.h I can't make the right call for the child process.

//mysyscalls.h

long getnchildren (int debug){
  int children;
  children = pids[i];
  return children;
}


long getcpid (int order, int debug){
  int childrenid;
  childrenid = getpid();
  return childrenid;
}

I don't know how to call these pids in the mysyscalls.h file. I searched and tested some code that I found here but I don't have an exact answer for my problem. I wrote that code but isn't working, it return the same pid.

It's supposed that long getnchildren returns the number of child processes that the calling process has, at the moment the primitive is called.

long getcpid returns the pid of the child of the calling process, at position order in the list of its children.

Upvotes: 0

Views: 1334

Answers (2)

Matthew Farstad
Matthew Farstad

Reputation: 19

This outlines a simple way to do some common functions involving for PIDs. If I were you, I would circumvent trying to do this in C. More trouble than its worth, IMO.

#!/bin/bash

# getting children generally resolves nicely at some point
get_child() {
    echo $(pgrep -laP $1 | awk '{print $1}')
}

# recursively getting parents isn't that useful, 
# so single use function
get_parent() {
    echo $(ps -o ppid= -p 36700)
}

get_children() {
    __RET=$(get_child $1)
    __CHILDREN=
    while [ -n "$__RET" ]; do
        __CHILDREN+="$__RET "
        __RET=$(get_child $__RET)
    done

    __CHILDREN=$(echo "${__CHILDREN}" | xargs | sort)

    echo "${__CHILDREN}"
}

get_children $1

FILE *fp;
char path[1024];
char command[1024];
sprintf(command, "/bin/bash /get_pids.sh %d", getpid());

fp = popen(command, "r");
while (fgets(path, sizeof(path), fp) != NULL) {
    // children are listed here
    printf("%s", path);
}

pclose(fp);

I've been trying to cook up an unholy one-liner for David Schwartz's method, but I think it is a fully cursed solution. Some other bash-abuser can take a crack at it.

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182743

  1. Get your own pid with getpid.
  2. Iterate through all directories in /proc that start with a digit.
  3. For each such directory, open the status file.
  4. Read all the lines until you find the PPid line.
  5. If the PPid matches the value from getpid, add this directory name to your array.

That will get you the IDs of every process whose parent process is this process.

Upvotes: 2

Related Questions