Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

I need help with this code, its not working #include #include #include #include #include #define MAX_CMD_LENGTH 1024 #define MAX_ARGS 64 int parse_input(char* input, char** args)

I need help with this code, its not working

#include

#include

#include

#include

#include

#define MAX_CMD_LENGTH 1024

#define MAX_ARGS 64

int parse_input(char* input, char** args) {

int i = 0;

char* token = strtok(input, " \t ");

while (token != NULL) {

args[i++] = token;

token = strtok(NULL, " \t ");

}

args[i] = NULL; // make sure the last argument is NULL

return i; // return the number of arguments

}

int execute_cmd(char** args, char** path, int num_paths) {

pid_t pid = fork();

if (pid == -1) {

perror("fork");

return 1;

} else if (pid == 0) {

// child process

int i;

for (i = 0; i < num_paths; i++) {

char cmd[MAX_CMD_LENGTH];

snprintf(cmd, sizeof(cmd), "%s/%s", path[i], args[0]);

execv(cmd, args);

}

// if we reach here, execv failed

perror(args[0]);

exit(1);

} else {

// parent process

int status;

waitpid(pid, &status, 0);

return WEXITSTATUS(status);

}

}

int main(int argc, char** argv) {

// initialize path with /bin

char* path[2] = {"/bin", NULL};

int num_paths = 1;

// check if we're in batch mode

FILE* input_file = NULL;

if (argc > 2) {

fprintf(stderr, "Usage: %s [batch_file] ", argv[0]);

return 1;

} else if (argc == 2) {

input_file = fopen(argv[1], "r");

if (input_file == NULL) {

perror(argv[1]);

return 1;

}

}

// main loop

char* line = NULL;

size_t line_size = 0;

ssize_t line_len;

while (1) {

// prompt for input

if (input_file == NULL) {

printf("wish> ");

fflush(stdout);

}

// read input

line_len = getline(&line, &line_size, input_file != NULL ? input_file : stdin);

if (line_len == -1) {

// end of file or error

break;

}

else if (line_len == 1)

printf("An error occured ");

}

}

the code should follow these instructions

Part 2a: Shell In this assignment, you will implement a Command Line Interpreter (CLI) or, as it is more commonly known, a Shell. The shell should operate in this basic way: when you type in a command (in response to its prompt), the shell creates a child process that executes the command you entered and then prompts for more user input when it has finished.

2. Program Specifications - Basic Shell Your basic shell, called wish, is basically an interactive loop: it repeatedly prints a prompt wish> (note the space after the greater-than sign), parses the input, executes the command specified on that line of input, and waits for the command to finish. This is repeated until the user types exit. The name of your final executable should be wish. The shell can be invoked with either no arguments or a single argument; anything else is an error. Here is the no-argument way: prompt>./wish wish> At this point, wish is running, and ready to accept commands. Type away! The mode above is called interactive mode, and allows the user to type commands directly. The shell also supports a batch mode, which instead reads input from a batch file and executes commands from therein. Here is how you run the shell with a batch file named batch.txt: prompt> ./wish batch.txt One difference between batch and interactive modes is that, in interactive mode, a prompt is printed (wish> ). In batch mode, no prompt should be printed. You should structure your shell such that it creates a process for each new command (the exception are built-in commands, discussed below). Your basic shell should be able to parse a command and run the program corresponding to the command. For instance, if the user types ls -la /tmp your shell should run the program /bin/ls with the given arguments -la and /tmp (how does the shell know to run/bin/ls Its something called the shell path; more on this in the next section).

3. Structure The shell is very simple (conceptually): it runs in a while loop, repeatedly asking for input to tell it what command to execute. It then executes that command. The loop continues indefinitely, until the user types the built-in command exit, at which point it exits. Thats it! For reading lines of input, you should use getline(). This allows you to obtain arbitrarily long input lines with ease. Generally, the shell will be run in interactive mode, where the user types a command (one at a time) and the shell acts on it. However, your shell will also support batch mode, in which the shell is given an input file of commands; in this case, the shell should not read user input (from stdin) but rather from this file to get the commands to execute. In either mode, if you hit the end-of-file marker (EOF), you should call exit(0) and exit gracefully. To parse the input line into constituent pieces, you might want to use strsep(). Read the man page (carefully) for more details. To execute commands, look into fork(), exec(), and wait()/waitpid(). See the man pages for these functions, and also read the relevant book chapter for a brief overview. You will note that there are a variety of commands in the exec family; for this project, you must use execv. You should not use the system() library function call to run a command. Remember that if execv() is successful, it will not return; if it does return, there was an error (e.g., the command does not exist). The most challenging part is getting the arguments correctly specified. 4. Paths In our example above, the user typed ls but the shell knew to execute the program /bin/ls. How does your shell know this? It turns out that the user must specify a path variable to describe the set of directories to search for executables; the set of directories that comprise the path are sometimes called the search path of the shell. The path variable contains the list of all directories to search, in order, when the user types a command. Important: Note that the shell itself does not implement ls or other commands (except built-ins). All it does is find those executables in one of the directories specified by path and create a new process to run them. To check if a particular file exists in a directory and is executable, consider the access() system call. For example, when the user types ls , and path is set to include both /bin and /usr/bin, try access("/bin/ls", X_OK). If that fails, try /usr/bin/ls. If that fails too, it is an error. Your initial shell path should contain one directory: /bin 5. Built-in Commands Whenever your shell accepts a command, it should check whether the command is a built-in command or not. If it is, it should not be executed like other programs. Instead, your shell will invoke your implementation of the built-in command. For example, to implement the exit built-in command, you simply call exit(0); in your wish source code, which then will exit the shell. In this project, you should implement exit, cd, and path as built-in commands. exit: When the user types exit, your shell should simply call the exit system call with 0 as a parameter. It is an error to pass any arguments to exit.

6. Redirection Many times, a shell user prefers to send the output of a program to a file rather than to the screen. Usually, a shell provides this nice feature with the > character. Formally this is named as redirection of standard output. To make your shell users happy, your shell should also include this feature, but with a slight twist (explained below). For instance, if a user types ls -la /tmp > output, nothing should be printed on the screen. Instead, the standard output of the ls program should be rerouted to the file output. In addition, the standard error output of the program should be rerouted to the file output (the twist is that this is a little different than standard redirection). If the output file exists before you run your program, you should simple overwrite it (after truncating it). The exact format of redirection is a command (and possibly some arguments) followed by the redirection symbol followed by a filename. Multiple redirection operators or multiple files to the right of the redirection sign are errors. Note: dont worry about redirection for built-in commands (e.g., we will not test what happens when you type path /bin > file). 7. Parallel Commands Your shell will also allow the user to launch parallel commands. This is accomplished with the ampersand operator as follows: wish> cmd1 & cmd2 args1 args2 & cmd3 args1 In this case, instead of running cmd1 and then waiting for it to finish, your shell should run cmd1, cmd2, and cmd3 (each with whatever arguments the user has passed to it) in parallel, before waiting for any of them to complete. Then, after starting all such processes, you must make sure to use wait() (or waitpid) to wait for them to complete. After all processes are done, return control to the user as usual (or, if in batch mode, move on to the next line). Note: B Handle parallel commands which are not built-in (not implemented by you) For example, you have to handle ls & ls ls & echo Hello etc. You need not handle when one(or all) of the parallel commands are built-in (implemented by you exit, cd , path). 8. Program Errors The one and only error message. You should print this one and only error message whenever you encounter an error of any type: char error_message[30] = "An error has occurred "; write(STDERR_FILENO, error_message, strlen(error_message)); The error message should be printed to stderr (standard error), as shown above. After any most errors, your shell simply continues processing after printing the one and only error message. However, if the shell is invoked with more than one file, or if the shell is passed a bad batch file, it should exit by calling exit (1).

There is a difference between errors that your shell catches and those that the program catches. Your shell should catch all the syntax errors specified in this project page.

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database Systems For Advanced Applications 27th International Conference Dasfaa 2022 Virtual Event April 11 14 2022 Proceedings Part 2 Lncs 13246

Authors: Arnab Bhattacharya ,Janice Lee Mong Li ,Divyakant Agrawal ,P. Krishna Reddy ,Mukesh Mohania ,Anirban Mondal ,Vikram Goyal ,Rage Uday Kiran

1st Edition

3031001257, 978-3031001253

More Books

Students also viewed these Databases questions

Question

define what is meant by the term human resource management

Answered: 1 week ago