Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Re-architect vsh of Problem 2 to replace system() with system calls to Linux to

ID: 3914826 • Letter: R

Question

Re-architect vsh of Problem 2 to replace system() with system calls to Linux to spawn a child using fork() and execute a command using execl() which invokes the loader. After reading user input from vsh's prompt, if the input is determined not to be one of the shell commands of Problem 2, then a call to fork() is made to create a child process that calls execl() to run the requested command. To use execl() include the header file <unistd.h>. As an example, to execute the binary ls from within the binary vsh, the child process calls

     execl("/bin/ls","/bin/ls",NULL);

which invokes the Linux loader to load the "/bin/ls" binary into main memory and creates a new process that executes /bin/ls. Before calling execl() with the user provided binary as the first and second arguments to execl(), print to standard output using fprintf() a message

"forked child process: <name-of-binary> <pid>"

where <name-of-binary> is the full pathname of the binary entered by the user, and <pid> is the process ID (PID) of the child. Use the system call getpid() (perform man to determine its usage) to get the PID of the current (i.e., calling) process. For simplicity, assume arguments to binaries are not allowed (i.e., "/bin/ls" is fine but "/bin/ls -l" is not). Shell commands (e.g., nprompt, secure) should be executed out by the parent as in Problem 2 without forking a child process. Thus shell commands are entire separate features from binary commands (i.e., legacy app binaries such as /bin/sh) that a shell is requested to execute. Code, compile, and test the modified shell, call it vish. Use Makefile to manage your code.

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define SECRET "purduepete" // using C preprocess command #define to set secret key

int main()

{

char prompt[100] = ">>"; // string for prompt

char input[100]; // string for user input

while (1) // infinite loop

{

printf("%s ",prompt); // display prompt

char c;

int i = 0;

while ((c = getchar()) != ' ') // read characters using getchar() until ' ' is encountered

{

input[i++] = c; // append read character into input

}

input[i] = 0; // terminate input string

if (strncmp(input, "nprompt ", 8)==0) // check if first word of input is "nprompt", first feature

{

int j = 0;

for (int i = 8; i < strlen(input); i++) // iterate over the rest of the input after "nprompt "

prompt[j++] = input[i]; // copy the characters from the input to prompt

prompt[j] = 0; // terminate prompt string

}

else if(strlen(input)==0) // check is input string is empty, second feature

{

printf("What do you want? "); // display the required statement

}

else if(strcmp(input,"q")==0||strcmp(input,"Q")==0) // check if input string is "q" or "Q", third feature

{

printf("Thank you for using vsh! "); // display exit message

break; // break infinite loop to exit

}

else if(strcmp(input,"secure")==0) // check if input string is "secure", fourth feature

{

int attempts = 0; // keeps track of incorrect attempts

char secret[100]; // string for secret key entered by user

while (attempts < 3)

{

int i = 0;

printf("secret key: "); // display

while((c=getchar())!=' ') // read characters using getchar() until ' ' is encountered

secret[i++] = c; // append read character to secret

secret[i] = 0; // terminate secret string

if(strcmp(secret,SECRET)==0) // if secret string matches with SECRET

break; // successfully unlock

else

attempts++; // incorrect secret key, add 1 to attempts

}

if(attempts==3) // if key is incorrectly entered for 3 times

{

printf("You failed to enter the secret key in 3 attempts! Exiting. "); // print appropriate exit message

break; // break infinite loop to exit

}

}

else

system(input); // execute input string by using the system() command

}

return 0;

}

Explanation / Answer

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#include<sys/types.h>
#define SECRET "purduepete" // using C preprocess command #define to set secret key
int main()
{
int i;
pid_t id,wpid;
char prompt[100] = ">>"; // string for prompt
char input[100]; // string for user input
while (1) // infinite loop
{
printf("%s ",prompt); // display prompt
char c;
int i = 0;
while ((c = getchar()) != ' ') // read characters using getchar() until ' ' is encountered
{
input[i++] = c; // append read character into input
}
input[i] = 0; // terminate input string
if (strncmp(input, "nprompt ", 8)==0) // check if first word of input is "nprompt", first feature
{
int j = 0;
for (i = 8; i < strlen(input); i++) // iterate over the rest of the input after "nprompt "
prompt[j++] = input[i]; // copy the characters from the input to prompt
prompt[j] = 0; // terminate prompt string
}
else if(strlen(input)==0) // check is input string is empty, second feature
{
printf("What do you want? "); // display the required statement
}
else if(strcmp(input,"q")==0||strcmp(input,"Q")==0) // check if input string is "q" or "Q", third feature
{
printf("Thank you for using vsh! "); // display exit message
break; // break infinite loop to exit
}
else if(strcmp(input,"secure")==0) // check if input string is "secure", fourth feature
{
int attempts = 0; // keeps track of incorrect attempts
char secret[100]; // string for secret key entered by user
while (attempts < 3)
{
int i = 0;
printf("secret key: "); // display
while((c=getchar())!=' ') // read characters using getchar() until ' ' is encountered
secret[i++] = c; // append read character to secret
secret[i] = 0; // terminate secret string
if(strcmp(secret,SECRET)==0) // if secret string matches with SECRET
break; // successfully unlock
else
attempts++; // incorrect secret key, add 1 to attempts
}
if(attempts==3) // if key is incorrectly entered for 3 times
{
printf("You failed to enter the secret key in 3 attempts! Exiting. "); // print appropriate exit message
break; // break infinite loop to exit
}
}
else{
    //system(input); // execute input string by using the system() command
    id = fork();
    if (id == 0){
      
       char cmd[100] = "/bin/";
       strcat(cmd,input);
       printf("%s ",cmd);
       execl(cmd,input,NULL);
       exit(0);
       
    }
    else {
       printf("Forked a child process: %s %d ",input,id);
    }
}
}
return 0;
}