Question
INSTRUCTIONS Add only one feature: redirection. To direct a commands output to a file, the syntax > outfile is used. To read a commands input
INSTRUCTIONS
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 basic idea is that if you see redirection on the command line, you open the file or files, and then use dup2. Think: do you want to do this in the child process that gets forked, or by the parent process?
Make sure you understand dup2. Please check out this dup2 slide deck I created that explains dup2 and gives some hints on the homework.
Also, you need to handle the ">" and "<" characters that appear on the command line. Think about whether or not you put them into an array of tokens.
CODE
#include
#include
#include
#include
#include
#include
#include
#include
#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];
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