your code should continue to support the commands 'exit',
'help', and 'today' from MSH 1. Please modify the 'help'
command to match the output shown in the example below.
run Linux commands that are entered by the user. You must
do this by using fork() and execvp() as shown in lecture and in
OSTEP Figure 5.3. After a command is executed, the prompt
should be displayed as usual.
It should be obvious, but your msh code must never (this week or
any other) use the 'system' command, or any other command to
execute shell commands. That would defeat the purpose of the
assignment.
In OSTEP Figure 5.3, the code runs only command 'wc'. Your
MSH code should run whatever command is entered on the command
line.
Here is some sample output to help you understand what your
program should do:
$ ./msh
msh> ls
temp.txt
README.txt
msh> help
enter Linux commands, or
‘exit’ to exit
msh> foo 1
msh: foo: No such file or directory
msh> today
01/02/2018
msh> exit
$
Note the error message reported when ‘foo’ was entered.
execvp() will return an error message if it couldn’t run the
command entered by the user. How do you know this?
execvp() will only return if there was a problem running the
command that was passed to it. Here is the code I use to
print an error message if execvp returns:
printf("msh: %s: %s\n", toks[0],
strerror(errno));
Here toks is an array I used to store the “tokens” entered at
the command line. strerror() and errno are defined by
Linux. For more information, look for errno in the man page
for exec, and look at the man page for strerror.
Your code needs to handle options provided on the command
line. For example, you should be able to support the command
ls -l -t
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
/*
* A simple shell
*/
#define MAX_BUF 160
#define MAX_TOKS 100
int main() {
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;
while (1) {
// prompt for input if
input from terminal
if
(isatty(fileno(stdin))) {
printf(prompt);
}
// read input
char *status = fgets(s,
MAX_BUF+2, stdin);
// exit if ^d
entered
if (status == NULL)
{
printf("\n");
break;
}
// input is too long
if last character is not newline
if ((pos = strchr(s,
'\n')) == NULL) {
printf("error: input too long\n");
// clear the input buffer
while ((ch = getchar()) != '\n' && 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 = tok;
i++;
}
if (i == MAX_TOKS)
{
printf("error: too many tokens\n");
continue;
}
toks = 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 'help', 'today', or 'exit' to quit\n");
continue;
}
// print date if
command is 'date'
if (strcmp(toks[0],
"today") == 0) {
time(&rawtime);
timeinfo = localtime(&rawtime);
printf("%02d/%02d/%4d\n", 1 + timeinfo->tm_mon,
timeinfo->tm_mday, 1900 + timeinfo->tm_year);
continue;
}
// otherwise print
all tokens
for (i = 0; toks !=
NULL; i++) {
printf("token: '%s'\n", toks);
}
}
exit(EXIT_SUCCESS);
}
your code should continue to support the commands 'exit', 'help', and 'today' from MSH 1. Please modify the 'help' comm
-
- Site Admin
- Posts: 899603
- Joined: Mon Aug 02, 2021 8:13 am