Question

This project consists of designing a C program to serve as a shell interface that accepts...

This project consists of designing a C program to serve as a shell interface that accepts user commands and then executes each command in a separate process.

A shell interface gives the user a prompt, after which the next command is entered. The example below illustrates the prompt cse222> and the user’s next command: cat prog.c.

cse222> cat prog.c

One technique for implementing a shell interface is to have the parent process first read what the user enters on the command line (in this case, cat prog.c), and then create a separate child process that performs the command. Unless otherwise specified, the parent process waits for the child to exit before continuing. However, UNIX shells typically also allow the child process to run in the background, or concurrently. To accomplish this, we add an ampersand (&) at the end of the command. Thus, if we rewrite the above command as

cse222> cat prog.c &

the parent and child process will run concurrently.

The separate child process is created using the fork() system call, and the user’s command is executed using one of the system calls in the exec() family.

A C program that provides the general operations of a command-line shell is supplied below. The main() function presents the prompt cse22> and outlines the steps to be taken after input from the user has been read. The main() function continually loops as long as should_run equals 1; when the user enters exit at the prompt, you program should set should_run to 0 and terminate.

#include <stdio.h>

#include <unistd.h>

#define MAX_LINE 80 /* The maximum length command */ int main(void)

{

char *args[MAX_LINE/2 + 1]; /* command line arguments */

int should_run = 1; /* flag to determine when to exit */

while(should_run){

printf(“cse222>”);

fflush(stdout);

/**

*After reading user input, the steps are:

*(1) fork a child process using fork()

*(2) the child process will invoke execvp()

*(3) if command include &, parent will invoke wait()

*/

}

return 0;

}

You need to modify the main() function so that a child process is forked and executes the command specified by the user. This will require parsing what the user has entered into separate tokens and storing the tokens in an array of character strings (args). For example, if the user enters the command ps –ael at the cse222> prompt, the values stored in the args array are:

arg[0] = “ps”

arg[1] = “-ael” args[2] = NULL

The args arrary will be passed to the execvp() function, which has the following prototype:

execvp(char *command, char *params[]);

where command represents the command to be performed and params stores the parameters to this command. For this project, the execvp() function should be invoked as execvp(args[0], args). You should check whether the user includes an & to determine whether or not the parent process is to wait for the child to exit.

0 0
Add a comment Improve this question Transcribed image text
Answer #1

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

#define MAX_LINE 80 /* The maximum length command */

void invoke_error(char *a) {
   printf("rsh: %s (~.~)! \n", a);
}

int fetch_input(char *a) {
   char p;
   int num = 0;

   while (((p = getchar()) != '\n') && (num < MAX_LINE)) {
       a[num++] = p;
   }

   if (num == MAX_LINE && p != '\n') {
       invoke_error("Command exceeds maximum command length");
       num = -1;
   } else {
       a[num] = 0;
   }
   while (p != '\n') p = getchar();
   return num;
}

void print_history(char history[][MAX_LINE + 1], int history_count) {
   if (history_count == 0) {
       invoke_error("No history yet");
       return;
   }

   int i, j = 10;
   for (i = history_count; i > 0 && j > 0; i --, j--) {
       printf("%4d\t%s\n", i, history[i % 10]);
   }
}

int parse(char *buffer, int length, char* args[]) {
   int args_num = 0, last = -1, i;
   args[0] = NULL;
   for (i = 0; i <= length; ++i) {
       /* The last one must be zero so use <=*/
       if (buffer[i] != ' ' && buffer[i] != '\t' && buffer[i]) {
           continue;
       } else {
           if (last != i-1) {
               //store the parse result of [last+1, i-1]
               args[args_num] = (char*)malloc(i-last);
               if (args[args_num] == NULL) {
                   invoke_error("Unable to allocate memory");
                   return 1;
               }
               //malloc size+1
               memcpy(args[args_num], &buffer[last+1], i-last-1);
               //
               args[args_num][i-last] = 0;
               //set the last char zero
                   args[++args_num] = NULL;
           }
           last = i;
       }
   }
   return args_num;
}

int to_number(char *a) {
   int length = strlen(a), i, answer = 0;
   for (i = 0; i < length; i++) {
       if (a[i] > '9' || a[i] < '0') return -1;
       answer = answer * 10 + a[i] - '0';
   }
   return answer;
}

int main(void) {

  

   char *args[MAX_LINE/2 + 1]; /* command line arguments */
   int should_run = 1; /* flag to determine when to exit program */

   char history[10][MAX_LINE + 1];
   int history_count = 0;

   char buffer[MAX_LINE + 1];
   memset(buffer, 0, sizeof(buffer));
   int length, args_num;

   while (should_run) {
       printf("rsh>");
       fflush(stdout);

       /**
       * After reading user input, the steps are:
       * (1) fork a child process using fork()
       * (2) the child process will invoke execvp()
       * (3) if command included &, parent will invoke wait()
       */

       length = fetch_input(buffer);
       if (length == -1) continue;

       if (strcmp(buffer, "!!") == 0) {
           if (history_count > 0) {
               memcpy(buffer, history[history_count % 10], MAX_LINE + 1);
               length = strlen(buffer);
           } else {
               invoke_error("No commands in history");
               continue;
           }
       }

       args_num = parse(buffer, length, args);

       if (args_num == 0) continue;
       //No input message

       if (strcmp(args[0], "!") == 0) {
           int temp = to_number(args[1]);
           if (temp <= 0 || temp < history_count - 9 || temp > history_count) {
               invoke_error("No such command in history");
               continue;
           } else {
               memcpy(buffer, history[temp % 10], MAX_LINE + 1);
               length = strlen(buffer);
               args_num = parse(buffer, length, args);
           }
       }

       if (strcmp(args[0], "exit") == 0) {
           should_run = 0;
           continue;
       }

       if (strcmp(args[0], "history") == 0) {
           print_history(history, history_count);
           continue;
       }

       history_count ++;
       memcpy(history[history_count% 10], buffer, MAX_LINE + 1);

       //printf("%s\n", args[0]);
       //here to implement the new order

       int background = 0;
       if (strcmp(args[args_num-1], "&") == 0) {
           background = 1;
           args[--args_num] = NULL;
       }

       pid_t pid = fork();
       if (pid < 0) {
           invoke_error("Fork process error");
           return 1;
       }

       int status;

       if (pid == 0) {
           status = execvp(args[0], args);
           if (status == -1) {
               invoke_error("Failed to execute the command");
           }
           return 0;
       } else {
           if (background) {
               printf("pid #%d running in background %s\n", pid, buffer);
           } else {
               wait(&status);
           }
       }

   }

   return 0;
}

Add a comment
Know the answer?
Add Answer to:
This project consists of designing a C program to serve as a shell interface that accepts...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Creating a Shell Interface Using Java This project consists of modifying a Java program so that...

    Creating a Shell Interface Using Java This project consists of modifying a Java program so that it serves as a shell interface that accepts user commands and then executes each command in a separate process external to the Java virtual machine. Overview A shell interface provides the user with a prompt, after which the user enters the next command. The example below illustrates the prompt jsh> and the user’s next command: cat Prog.java. This command displays the file Prog.java on...

  • The original code using the gets() function is written below. You need to do (a) change...

    The original code using the gets() function is written below. You need to do (a) change the provided code so that you now use fgets() function to obtain input from the user instead of gets(), (b) make any other necessary changes in the code because of using fgets() function, and (c) fill in the code for the execute() function so that the whole program works as expected (a simple shell program). Note: part c is already done, and the execute...

  • C LANGUAGE PROGRAM: You have the program that creates a parent and child. They communicate via...

    C LANGUAGE PROGRAM: You have the program that creates a parent and child. They communicate via the pipe. The parent writes into the pipe and child reads the data from the pipe. All you got to is replace FILL_IN_THE_BLANK with appropriate values or function names and just type the values of each TASKS, I don't need the c program. TASK_1 = TASK_2 = TASK_3 = TASK_4 = 4 of them [ 5 points each ] -------------------------------------------------------------------------------------------- When you run the...

  • Write a C program for Linux called pipes.c that does the following: In the main() function,...

    Write a C program for Linux called pipes.c that does the following: In the main() function, it creates a pipe using the pipe() function, then creates two child processes with fork(). Child 1 redirects stdout to the write end of the pipe and then executes with execlp() the "ps -aux" command. Child 2 redirects its input from stdin to the read end of the pipe, then it executes the "sort -r -n -k 5" command. After creating both children, the...

  • Project 1: Implementing a Shell 1 Overview In this individual project you will have to design...

    Project 1: Implementing a Shell 1 Overview In this individual project you will have to design and implement a simple shell command interpreter called mysh. The basic function of a shell is to accept lines of text as input and execute programs in response. The shell must be able to execute built-in commands in a process different from the one executing mysh. 2 Requirements When first started, your shell should initialize any necessary data structures and then enter a loop...

  • Edit the code (shell.c) given to do the tasks asked! will rate for correct answer! Also,...

    Edit the code (shell.c) given to do the tasks asked! will rate for correct answer! Also, include a screen shot of the output and terminal window of each command you used. Read carefully to do this task please. shell.c code given below. #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> #include <string.h> int main() { int PID; char lineGot[256]; char *cmd; while (1){ printf("cmd: "); fgets(lineGot, 256, stdin); // Get a string from user (includes \n) cmd = strtok(lineGot, "\n");...

  • Overview Writing in the C language, implement a very basic shell, called smash. In this project,...

    Overview Writing in the C language, implement a very basic shell, called smash. In this project, we will work on processing strings and using the appropriate system calls. Build System setup Before we can start writing code we need to get our build system all setup. This will involve writing a very simple makefile. You should leverage your Makefile project for this part of the assignment! Write a Makefile that provides the three targets listed below all - The default...

  • *Write a parallel program pie.c in C or C++ (pie.cc) for Linux that computes an approximation of the number π using a se...

    *Write a parallel program pie.c in C or C++ (pie.cc) for Linux that computes an approximation of the number π using a series with N+1 terms.* --The series sum is partitioned in T non-overlapping partial sums, each computed by T separate child processes created with the fork() library function.* --This program demonstrates data parallelism and interprocess communication using pipes. Each child process could perform a (potentially) long computation on a separate CPU (or core). Depending on the computer architecture, the...

  • Hello, how can i compile this C code using option -std=c99 or -std=gnu99 #include <stdio.h> #include...

    Hello, how can i compile this C code using option -std=c99 or -std=gnu99 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/stat.h> #include <fcntl.h> static char* args[512]; pid_t pid; int command_pipe[2]; static void waiting(int n); static int command(int input, int first, int last) { int fd[2]; int flag=0; pipe( fd );   pid = fork(); if (pid == 0) { for(int i=0;args[i]!=0;i++) { if(args[i][0]=='>') { fd[1]=open(args[i+1], O_CREAT|O_TRUNC|O_WRONLY, 0644); flag=1; } if(args[i]=='>>' ) { fd[1]=open(args[i+1],...

  • Update the program in the bottom using C++ to fit the requirements specified in the assignment....

    Update the program in the bottom using C++ to fit the requirements specified in the assignment. Description For this assignment, you will be writing a single program that enters a loop in which each iteration prompts the user for two, single-line inputs. If the text of either one of the inputs is “quit”, the program should immediately exit. If “quit” is not found, each of these lines of input will be treated as a command line to be executed. These...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT