views:

55

answers:

4
int main()
{
    ...
    if(!fork())
        {
            execvp(cmdName,cmdParam);
        }
    printf("In main()...");
return(0);
}
  1. Assuming I have correctly passed the cmdName & cmdParam arguments, how do I wait for the process created by execvp to finish, before resuming the execution of main()?
  2. Does the execvp() create a process which is a child of the newly fork()ed process?
+3  A: 
  1. In the parent process, fork returns the PID of the child process, so you can store that in a variable, and then use waitpid to wait for the child process to terminate.

  2. Not really - the new child process created by fork is a duplicate of the parent, and execvp then replaces its process image with a new image. Effectively you initially have two 'copies' of the parent, one of which then 'becomes' the new program.

Richard Fearn
so is the "new program" a child of the parent or does it have some other process as parent?
Kedar Soparkar
@crypto: from http://www.opengroup.org/onlinepubs/000095399/functions/fork.html: "The child process shall have a different parent process ID, which shall be the process ID of the calling process." Then `execvp` replaces the process image, but doesn't change the process's metadata.
Steve Jessop
@crypto: The former. If you do this on process 1000, one of the resulting forks will still be process 1000 with the original parent, and one will be another process, maybe 1001, with 1000 as the parent. Other than that, and what `fork` returns, the processes are the same. The `execvp` then changes what process 1001 is doing.
David Thornley
+1  A: 

You need to store the return value of fork(), which returns a different value to each executable (0 if you are the child PID if you are the parent), and then you need to do a waitpid

Seamus
+3  A: 

For your first question:

Use waitpid(2) like this:

int pid = fork();
if (!pid)
  {
    execvp(cmdName, cmdParam);
  }
waitpid(pid, NULL, 0);
printf("Resuming main()...\n");

For the second part: all exec function calls take the process over (none of them return)

terminus
+2  A: 

As noted you need to save the value of the fork call. You should really use more than an if on the fork. There are three cases:

  1. 0: you're the child process
  2. > 0: you're the parent and got a child PID back
  3. -1: something horrible happened and fork failed

You really want to know about case 3, it'll ruin your whole day. (also the exec call)

int main() {
  int pid = fork();
  if(-1 == pid) {
     fprintf(stderr, "Big problems forking %s\n", strerror(errno);
     exit(-1);//or whatever
  }
  else if (0 == pid) {
    if (-1 == execvp(cmdName,cmdParam)) {
      //like above, get some output about what happened
    }
  }
  //no need to else here, execvp  shouldn't return 
  // if it does you've taken care of it above
  waitpid(pid, NULL, 0);
  printf("Resuming main()...");
}

return(0); }

Paul Rubel
should'nt the child process in the (pid==0) part have an exit()? I don't want the child to print "Resuming main()...".
Kedar Soparkar
If the execvp worked that code that would print resuming main will be gone, replaced by cmdName. If there is a failure you'll handle it in some reasonable way.
Paul Rubel