Question
Instructions: In this assignment we will add only one feature: redirection. To direct a commands output to a file, the syntax > outfile is used.
Instructions: In this assignment we will add only one feature: redirection. To direct a commands output to a file, the syntax > outfile is used. To read a commands input from a file, the syntax < infile is used.
Your extended version of msh should extend the previous version of msh to handle commands like these:
$ ./msh
msh> ls -l > temp.txt
msh> sort < temp.txt > temp-sorted.txt
The result of these commands should be that the sorted output of ls -l is in file temp-sorted.txt.
Your shell builtins (like cd and help) do not have to handle redirection. Only one new Linux command is needed: dup2. You will use dup2 for both input and output redirection. The idea is that if you see redirection on the command line, you open the file or files, and then use dup2.
C CODE(do no change the code, only add what is needed) :
#include
/* * A simple shell */
#define MAX_BUF 160 #define MAX_TOKS 100
int main(int argc, char *argv[]) { int ch; int i; char *pos; char *tok; char s[MAX_BUF+2]; // 2 extra for the newline and ending '\0' static const char prompt[] = "msh> "; char *toks[MAX_TOKS]; time_t rawtime; struct tm *timeinfo; char *path; FILE *infile;
// process command-line arguments if (argc > 2) { fprintf(stderr, "msh: usage: msh [file] "); exit(EXIT_FAILURE); } if (argc == 2) { // read from script supplied on the command line infile = fopen(argv[1], "r"); if (infile == NULL) { fprintf(stderr, "msh: cannot open script '%s'. ", argv[1]); exit(EXIT_FAILURE); } } else { infile = stdin; }
while (1) { // prompt for input if input from terminal if (isatty(fileno(infile))) { printf(prompt); }
// read input char *status = fgets(s, MAX_BUF+2, infile);
// exit if ^d entered if (status == NULL) { printf(" "); break; }
// input is too long if last character is not newline if ((pos = strchr(s, ' ')) == NULL) { printf("error: input too long "); // clear the input buffer while ((ch = getchar()) != ' ' && ch != EOF) ; continue; }
// remove trailing newline *pos = '\0';
// break input into tokens i = 0; char *rest = s; while ((tok = strtok_r(rest, " ", &rest)) != NULL && i < MAX_TOKS) { toks[i] = tok; i++; } if (i == MAX_TOKS) { printf("error: too many tokens "); continue; } toks[i] = NULL;
// if no tokens do nothing if (toks[0] == NULL) { continue; }
// exit if command is 'exit' if (strcmp(toks[0], "exit") == 0) { break; }
// print help info if command is 'help' if (strcmp(toks[0], "help") == 0) { printf("enter a Linux command, or 'exit' to quit "); continue; }
// print date if command is 'date' if (strcmp(toks[0], "today") == 0) { time(&rawtime); timeinfo = localtime(&rawtime); printf("%02d/%02d/%4d ", 1 + timeinfo->tm_mon, timeinfo->tm_mday, 1900 + timeinfo->tm_year); continue; }
// cd command if (strcmp(toks[0], "cd") == 0) { // cd if (toks[1] == NULL) { path = getenv("HOME"); } else { path = toks[1]; } int cd_status = chdir(path); if (cd_status != 0) { printf("msh: %s: %s: %s ", toks[0], path, strerror(errno)); } continue; }
// otherwise fork a process to run the command int rc = fork(); if (rc < 0) { fprintf(stderr, "fork failed "); exit(1); } if (rc == 0) { // child process: run the command indicated by toks[0] execvp(toks[0], toks); // if execvp returns than an error occurred printf("msh: %s: %s ", toks[0], strerror(errno)); exit(1); } else { // wait for command to finish running wait(NULL); } } exit(EXIT_SUCCESS); }
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started