This post shows how to create a child process using fork() function. execvp replace the calling program with other executable binary. We’ll demonstrate the following:

  1. Create a child process and let the parent wait till completion of child.
  2. The parent will take command line argument containing name of an executable program and arguments.
  3. The child process will execute the program whose name is given in command line.
  4. The parent will pass any command line argument to the child.

 

Consider the following program. Lets’s save it as child-parent.c.

 

#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
	pid_t pid = fork();
	if(pid)
		wait(NULL);
	else{
	    execvp(argv[1], &argv[1]);
	}
	return 0;
}

Compile the program using gcc.

 

gcc child-parent.c
./a.out ls
./a.out ls -lah
./a.out ls /home

 

fork() returns pid = 0 to child and pid = of child to parent. So, parent will execute the if (pid) block and child will execute else block only. The wait() function blocks the execution of calling process till completion of child’s execution. Child  process may get it’s own PID and it parent’s PID using getpid() and getppid() function respectively.

 

execvp system call replaces the calling program with a new executable binary. The system call doesn’t return anything on success. In case of failure, it returns a negative integer. execvp take two arguments. 1st argument is a string (char * or character array, ‘\0’ terminated) containing the name or path of the executable. 2nd argument is a NULL terminated array of pointers to a string (i.e. NULL terminated char **) which is passed as argument to the executable.

 

In Linux system char ** argv contains the name of actual program as argv[0] and command line arguments starts from argv[1]. So the parent will get it’s own name as argv[0], child’s name as argv[1] and starting from argv[2] its arguments for the child process. To follow the same convention we’ve passed &argv[1] as arguments. Actual arguments for child process starts from argv[2]. But if we pass &argv[2] as 2nd argument of execvp() the child process will ignore the argument present in argv[2] as if it’s the process’s name. NOTE: It’s a bad idea to use NULL in place of &argv[1] even in case we don’t need to pass arguments. For more read this.

 

execvp search for an executable binary in the shell path when a program name like ls, top etc is given as 1st argument. To find your current path variable type echo $PATH in terminal. However, if an executable file name is given in argv[1] (starting with / or ./ e.g. /usr/bin/ls or ./a.out then that file is used.

 

For more details of fork(), execvp()and wait()please read man 3 corresponding to each function e.g. man 3 fork, man 3 exec etc.

 

For any suggestions please comment below. Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *