In: Computer Science
Question) The following simple shell program/code using gets()
function to obtain input from user. Using the gets() function is
potentially dangerous and it allows buffer to overflow.
You need to do following modification in the code;
(a) change the provided code so that you now use fgets() function
instead of fget() to obtain input from the user,
(b) make any other necessary changes in the code because of using
fgets() function, and
(c) fill in the code for the exectute() function so that the whole
program works as expected (a simple shell program).
******************************** C O D E
**********************************
/* The program asks for UNIX commands to be typed and inputted to a string*/ /* The string is then "parsed" by locating blanks etc. */ /* Each command and corresponding arguments are put in a args array */ /* execvp is called to execute these commands in child process */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> void parse(char *buf, char **args); void execute(char **args); char *gets(char *s); int main(int argc, char *argv[]) { char buf[1024]; char *args[64]; for (;;) { /* * Prompt for and read a command. */ printf("Command: "); if (gets(buf) == NULL) { printf("\n"); exit(0); } /* * Split the string into arguments. */ parse(buf, args); /* * Execute the command. */ execute(args); } } /* * parse--split the command in buf into * individual arguments. */ void parse(char *buf, char **args) { while (*buf != '\0') { /* * Strip whitespace. Use nulls, so * that the previous argument is terminated * automatically. */ while ((*buf == ' ') || (*buf == '\t')) *buf++ = '\0'; /* * Save the argument. */ *args++ = buf; /* * Skip over the argument. */ while ((*buf != '\0') && (*buf != ' ') && (*buf != '\t')) buf++; } *args = NULL; } /* * execute--spawn a child process and execute * the program. */ void execute(char **args) { //fill in your code here }
The solution to the above question is given below with screenshot of output.
=====================================================
I kept the logic simple and i have tested all outputs.
I Have added comments in program so that it can be easily
understood.
If there is anything else do let me know in comments.
=====================================================
============ CODE TO COPY ===============================
main.c
/* The program asks for UNIX commands to be typed and inputted to a string*/ /* The string is then "parsed" by locating blanks etc. */ /* Each command and corresponding arguments are put in a args array */ /* execvp is called to execute these commands in child process */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> void parse(char *buf, char **args); void execute(char **args); char *gets(char *s); int main(int argc, char *argv[]) { char buf[1024]; char *args[64]; for (;;) { /* * Prompt for and read a command. */ printf("Command: "); // Updated gets() to fgets() if (fgets(buf,1024,stdin) == NULL) { printf("\n"); exit(0); } /* * Split the string into arguments. */ parse(buf, args); /* * Execute the command. */ execute(args); } } /* * parse--split the command in buf into * individual arguments. */ void parse(char *buf, char **args) { while (*buf != '\0') { /* * Strip whitespace. Use nulls, so * that the previous argument is terminated * automatically. */ while ((*buf == ' ') || (*buf == '\t')) *buf++ = '\0'; /* * */ int length = strlen(buf); if( buf[length-1] == '\n' ) buf[length-1] = 0; /* * Save the argument. */ *args++ = buf; /* * Skip over the argument. */ while ((*buf != '\0') && (*buf != ' ') && (*buf != '\t')) buf++; } *args = NULL; } /* * execute--spawn a child process and execute * the program. */ void execute(char **args) { int pid = fork(); if(pid < 0) { printf("Error Creating child process"); return; } else if(pid == 0) { // Child process execvp(args[0], args); } else { // Parent process wait(0); } }
=====================================================
Output :