Write a custom shell program as described in the textbook: Programming Project 1, Part 1 (page 157). Do not do Part 2 (history feature) unless you wish to do so for fun. You are not required to detect & for background processes unless you wish to do so for fun. The minimum requirements are: Use the basic design provided in simple-shell.c that was provided in class and appears in Fig. 3.36. Parse the user input appropriately. You may use the approach provided in execvp_demo.c that was provided in class, or you may use a different approach that is more robust. Fork a new process for every command (except exit) in order to provide separate process control. Use wait() for the parent process. Below is an example of how your output might look (user input is in bold): EECS> echo This is my own shell! This is my own shell! EECS> ls shell.c -all -rwxr-xr-x 1 chrisf None 1146 Sep 14 22:25 shell.c EECS338> ./sleep Sleeping EECS> exit
Page 157
simple-shell.c
Execvp
#include #include
#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 program */ while (should_run) printf ("osh>"); fflush (stdout); kok *After reading user input, the steps are: *(1) fork a child process using forkO *(2) the child process will invoke execvp() * (3) if command included &, parent will invoke wait) return 0 Figure 3.36 Outline of simple shell. Part I-Creating a Child Process The first task is to modify the main) function in Figure 3.36 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 in Figure 3.36). For example, if the user enters the command ps -ael at the osh> prompt, the values stored in the args array are: "ps" "-ael" args [0] = args [1] args [2] = NULL This args array will be passed to the execvp) function, which has the following prototype: execvp (char *command, char *params []); Here, 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). Be sure to check whether the user included an & to determine whether or not the parent process is to wait for the child to exit. #include #include #define MAX LINE 80 80 chars per line, per command / int main(void) char *args [MAXLINE/2 + j; /* command line (of 80) has max of 40 arguments */ - int should run -1: int i, upper while (should run) ( printf ("osh>") fflush (stdout) After reading user input, the steps are: (1) fork a child process (2) the child process will invoke execvp (3) if command included &,parent will invoke wait ) x/ return0 #include // Required for execvp #include // Required for 1/0 #include // Required for string operations #define MAX LINE 80 // 80 chars per line, per command int main) char text [MAX LINE] II For user input text char *args [MAX LINE/2 + 1]; // Choose max # of command line arguments printf ("Enter text: ") fgets (text, MAX LINE, stdin) I/ Get user input text [strlen (text) -1] 0'; // Remove the from fgets args [O] strtok(text, " "). // Get text before 1st space int = 0; // Iterator for "arguments" after 1st space while (args[i]!NULL) // Loop until a null args [++1] = strtok(NULL, " "); Returns if (!strp (args[0], "Is")) // difference in lexicographical order (0 means equal) printf ("Ah, I see that you used the '1s' command. Excellent!n" ", printf ("Text before the 1st space: '%s'. Now calling execvp() execvp (args [0], args): I/ Execute the command args[0])