In: Computer Science
Compile and run the following code then answer the following questions:
a.) Run this command from the shell prompt:
./a.out ls -F
Explain, in your own words, why you see the screen output you do and how that output relates to both the content of the program AND the nature of the shell command used to invoke it. Be sure to comment on the pointer arithmetic done inside the line: execvp(*(argv+1), argv+1);
b.) Run this command from the shell prompt:
./a.out
Explain, in your own words, why you see the screen output you do and how that output relates to both the content of the program AND the nature of the shell command used to invoke it. Be sure to comment on the pointer arithmetic done inside the line: execvp(*(argv+1), argv+1);
c.) run this command from the shell prompt:
./a.out randomname
Explain, in your own words, why you see the screen output you do and how that output relates to both the content of the program AND the nature of the shell command used to invoke it. Of course, I’m assuming there is no executable file anywhere in your path called “randomname”. If you happen to have an executable named “randomname” –then substitute a name that does NOT exist in your command path J
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{ pid_t fork_returned_pid;
fork_returned_pid = fork();
if (fork_returned_pid < 0)
{ printf("The fork() didn't work! Terminate\n");
exit (0); }
if (fork_returned_pid != 0)
{ printf("The parent will now wait\n");
wait(NULL);
printf("The parent is done\n");
}
else
{ printf("The child is about to rewrite itself to run new
code\n");
execvp(*(argv+1), argv+1);
printf("this prints only if the previous call fails\n");
}
}
a.) Run this command from the shell prompt:
./a.out ls -F
Here ls -F is the argument passed to the program. argv is the array of commands given to main programs. args[0] is the name of the program , args[1] is the ls , argv[2] is the -f option .
We get below output
./main ls -F
The parent will now wait
The child is about to rewrite itself to run new code
main* main.cpp
The parent is done
In the given program, fork_returned_pid = fork();
fork is the system call which will create child process of current program(this is called parent process). Variable 'fork_returned_pid' will be zero or more than zero, Both the parent and child process will have same code after fork() system call. But only difference is using if statement we can distinguish between child and process and make the child and parent to execute their respective code. If 'fork_returned_pid' is greater zero than it's parent process.
parent process code has following line
if (fork_returned_pid != 0)
{ printf("The parent will now wait\n");
wait(NULL);
printf("The parent is done\n");
}
Suppose parent process is the first one to get execution time , then it prints the message 'The parent will now wait' and wait as program is using 'wait' system call to wait for it's child process to finish execution first.So control will be given to child process for execution.
In child process we have below code
else
{ printf("The child is about to rewrite itself to run new code\n");
execvp(*(argv+1), argv+1);
printf("this prints only if the previous call fails\n");
}
In above code , we use execvp system call , which will replace current code with the code which is given as command for execvp to execute. Here in this case *(argv+1) gives the name of the given command and argv+1, gives the address from the first element of 2-d array
In out case we have passes argv[1] as ls argv[2] as -F ,, *argv[1] will be ls command to get executed .
Once child finishes execution, parent process starts executing and it prints 'The parent is done' and exits.
==================================
b.) Run this command from the shell prompt:
./a.out
Here we are not passing any argument to the program ,, hence child process which is getting executed won't get any arguments *(args+1) and (args+1) will be NULL values , execvp executes with NULL values ,, Hence no program gets executed .we get output as below
The parent will now wait
The child is about to rewrite itself to run new code
The parent is done
=========================
c.) run this command from the shell prompt:
./a.out randomname
In this program name of the program passed is 'randomname' . let's say it's not present or implemented . Then in child process , execvp tries to search for the program named 'randomname' ,, it won't find one ,so it fails executing the command passed to it. hence code after execvp is gets printed as below
./main randomname
The parent will now wait
The child is about to rewrite itself to run new code
this prints only if the previous call fails
The parent is done
Hope it helps!!