I was going through the Dinosaur book by Galvin et. al. where I came across the following illustration of the fork()
system call.
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t pid;
/* fork a child process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0) { /* child process */
execlp("/bin/ls","ls",NULL);
}
else { /* parent process */
/* parent will wait for the child to complete */
wait(NULL);
printf("Child Complete");
}
return 0;
}
The text says:
After a
fork()
system call, one of the two processes typically uses theexec()
system call to replace the process’s memory space with a new program. Theexec()
system call loads a binary file into memory (destroying the memory image of the program containing theexec()
system call) and starts its execution.
So in this example above :
The child process then overlays its address space with the UNIX command
/bin/ls
(used to get a directory listing) using theexeclp()
system call (execlp()
is a version of theexec()
system call).
Here it is said that :
#include <unistd.h>
int execlp( const char * file,
const char * arg0,
const char * arg1,
…
const char * argn,
NULL );
file: Used to construct a pathname that identifies the new process image file. If the file argument contains a slash character, the file argument is used as the pathname for the file. Otherwise, the path prefix for this file is obtained by a search of the directories passed as the environment variable PATH.
arg0, …, argn : Pointers to NULL-terminated character strings. These strings constitute the argument list available to the new process image. You must terminate the list with a NULL pointer. The arg0 argument must point to a filename that's associated with the process being started and cannot be NULL.
Could anyone please explain what are the 3 arguments to the execlp() doing ? More specifically, why the arg0
must have the same name as the process being started ? The web search said me that the first argument is a file name (or path name) and the rest can be considered as pointers to null terminated strings which act as arguments to the file.
What I do not understand is why we are passing ls
as an argument to the ls
program present in the binary folder? While working on Linux terminal with
$
in the prompt. Just typing
$ ls
and hitting the enter key does the work... I mean we do not give.
$ ls ls
Is it similar to the way a C program accepts command line arguments ?
int main(int argc,char* argv){
...
}
Running the binary corresponding to the above program as:
$ ./a.out xyz pqr
has argv[0]="./a.out"
and argv[1]="xyz"
and argv[2]="pqr"
. Is ./a.out
an argument to the binary file a.out
? But using ./a.out
we are actually guiding the Linux system to run the binary.
I went here and here but none of them seem to answer my question directly.