Home > Software design >  How can I save the value of pid in a data structure and access it later with fork()?
How can I save the value of pid in a data structure and access it later with fork()?

Time:11-03

I have a program where I am creating several different child processes to simulate a shell script. What I am doing if the process should be ran in the background is creating a child process, then storing it's process id in a database so that next time I run a command, I can do a quick check with waitpid(pid,status,WNOHANG).

Where I am running into issues is with storing the value of child process ids and later trying to access them.

Here is the code where I create new child processes and insert them into a DLL that accepts a void * as a "node":

typedef void*Data;

extern void execCommand(Command command, Pipeline pipeline, Jobs jobs,
                             int *jobbed, int *eof, int fg) {
  CommandRep r=command;
  if (fg && builtin(r,eof,jobs))
    return;

  int pid=fork();
  if (pid==-1)
    ERROR("fork() failed");
  if (pid==0){
    // do some work as the child
  } else if(fg && pid > 0) {
    // if you're a parent and this is a foreground process
    // wait for the most recent process that started running
    // then try to wait for existing children if they exist
    int c_stat = -999;
    waitpid(pid,&c_stat,0);
    attemptWait();
  } else if (fg==0 && pid > 0) {
    // if you're a parent and this is a background process
    // add this childs process id to the list, and then
    // attempt to wait for all processes to finish
    dll_put(running_processes,(Data)&pid);
    attemptWait();
  }
}
void attemptWait() {
  int j=-999;
  for(int i=0;i<dll_len(running_processes);i  ) {
    j=waitpid(*(int *)dll_ith(running_processes, i),&j,WNOHANG);
    printf("child pid: %d\n",*(int *)dll_ith(running_processes, i));
    if((j)==(*(int *)dll_ith(running_processes, i))) {
      printf("[%d]  Done", i);
    } else if (j == -1) {
      printf("there was an error closing the %d-th process\n", i);
    }
  }
}

Now, what's happening is that when I store the pid of the newly created child process, I am passing it the address of pid to store in the data structure, however the next time execCommand is called, pid is updated, so all of my pids in the DLL are getting overwritten and I am trying to close the same process everytime I enter a command.

How do I get just the integer value stored in DLL so that I can use it without worrying that it's going to be overwritten?

CodePudding user response:

I don't know the dll_..() functions you're using but obviously you're always storing an address of a local variable which is out of scope when execFunction() returns. So you should try allocating a buffer to store that pid:

pid_t *pid_ptr = malloc( sizeof *pid_ptr );
*pid_ptr = pid;
dll_put(running_processes, pid_ptr);

And don't forget to call free() when you don't need that pid anymore (which should be after the child terminated)

  • Related