Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

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

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_2

Step: 3

blur-text-image_3

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

Introductory Relational Database Design For Business With Microsoft Access

Authors: Jonathan Eckstein, Bonnie R. Schultz

1st Edition

1119329418, 978-1119329411

More Books

Students also viewed these Databases questions