1

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 the exec() system call to replace the process’s memory space with a new program. The exec() system call loads a binary file into memory (destroying the memory image of the program containing the exec() 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 the execlp() system call (execlp() is a version of the exec() 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.

Abhishek Ghosh
  • 597
  • 7
  • 18
  • 1
    There is no requirement that `arg0` be the same as the file. It's just commonly the case. – William Pursell May 13 '21 at 17:56
  • 1
    The `arg` arguments are what becomes the `argv` array in the program. You can put *anything* there really. That `argv[0]` (and your `arg0`) is the name of the program is traditional. – Some programmer dude May 13 '21 at 18:01
  • @Someprogrammerdude @WilliamPursell I changed the arg0 from "ls" to "" and the program works just the same. Only thing is that if I put the arg0 as NULL, the program says `A NULL argv[0] was passed through an exec system call.` I got the point. – Abhishek Ghosh May 13 '21 at 18:05
  • @Someprogrammerdude `The arg arguments are what becomes the argv array in the program.` Thanks for the help. `You can put anything there really. That argv[0] (and your arg0) is the name of the program is traditional.` Explicitly in execlp() we can put anything, but in the Linux terminal, argv[0] is automatically taken to be the name of the file. Is this what happens? Because I guess in the Linux terminal we cannot cause `argv[0]` to be as our wish (I do not know it, I might be wrong). – Abhishek Ghosh May 13 '21 at 18:10

1 Answers1

2

The arg0 parameter is, by convention, the name of the executable being run. However, this is not required to be the case. You can pass any string for this argument.

dbush
  • 205,898
  • 23
  • 218
  • 273