In this lab, you will write a simple shell by your own. In this shell, it takes
ID: 3720925 • Letter: I
Question
In this lab, you will write a simple shell by your own. In this shell, it takes an input command, and then executes it. Your shell should implement the followings:
Take external commands, such as, ls, emacs and so on.
Take internal commands
exit: terminate the shell.
jobs: list all jobs in the format: <pid><command name>, in the order of creation
help: help information of your shell.
Descriptions:
The input to the shell is a sequence of lines. The shell must correctly handle lines of up to 100 characters. If a line containing more than 100 characters is submitted to the shell, it should print some kind of error message and truncate it to 100 characters.
Each line consists of tokens. Tokens are separated by one or more spaces. A line may contain as many tokens as can fit into 100 characters.
Words consist of the characters A–Z, a–z, 0–9, dash, dot, forward slash, and underscore. If a word in a line of input to the shell contains any character not in this set, then the shell should print an error message and then ignore the rest.
Lines of input are divided into token groups. Each token group will result in the shell forking a new process and then executing a program.
Every token group must begin with a word that is called the command. The words immediately following a command are called arguments and each argument belongs to the command it most closely follows. The order of arguments matters, and they are numbered from left to right, starting at one.
System Calls:
fork()
execvp() or execlp()
wait()
exit()
Explanation / Answer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAXLENGTH 20
#define COMMANDLEN 100
struct node
{
char command[COMMANDLEN];
pid_t pid;
struct node *next;
};
struct node* listHead = NULL;
struct node* listTail = NULL;
void read_command(char* command, char* parameter1, char* parameter2, char* parameter3)
{
char str1[COMMANDLEN];
char arraystr[4][MAXLENGTH];
fgets(str1, sizeof(str1), stdin);
struct node *tmp = (struct node*) malloc(sizeof(struct node));
strncpy(tmp->command, str1, COMMANDLEN);
tmp->next = NULL;
if (listHead == NULL)
{
listHead = tmp;
listTail = tmp;
}
else
{
listTail->next = tmp;
listTail = tmp;
}
int i, j = 0, count = 0;
for (i = 0; i <= strlen(str1) && j < MAXLENGTH; i++)
{
if (str1[i] == ' ' || str1[i] == '' || str1[i] == ' ' || j == MAXLENGTH - 1)
{
arraystr[count][j] = '';
count++;
j=0;
}
else
{
arraystr[count][j] = str1[i];
j++;
}
}
strncpy(command, arraystr[0], MAXLENGTH);
strncpy(parameter1, arraystr[1], MAXLENGTH);
strncpy(parameter2, arraystr[2], MAXLENGTH);
strncpy(parameter3, arraystr[3], MAXLENGTH);
return;
}
int main()
{
while(1) {
char command[MAXLENGTH] = {''};
char parameter1[MAXLENGTH] = {''};
char parameter2[MAXLENGTH] = {''};
char parameter3[MAXLENGTH] = {''};
//display prompt on the screen
printf("shell>> ");
//read input from keyboard
read_command( command, parameter1, parameter2, parameter3 );
//delete link list in case of exit
if (strcmp(command, "exit") == 0) {
while(listHead)
{
struct node *tmp = listHead;
listHead = listHead->next;
free(tmp);
}
break;
}
//print jobs list ion vase of jobs command
else if (strcmp(command, "jobs") == 0) {
listTail->pid = getpid();
struct node *tmp = listHead;
printf("Commands executed :- ");
int count = 1;
printf("index pid command ");
while(tmp)
{
printf("(%d) %d %s", count++, tmp->pid, tmp->command);
tmp=tmp->next;
}
}
//execute command
else
{
int status;
if (fork() != 0) { //executing in parent code after fork
listTail->pid = getpid();
//wait for child to exit
waitpid( -1, &status, 0 );
} else { //executing in child code after fork
//execute command
if (parameter1[0] && parameter2[0] && parameter3[0])
execlp( command, command, parameter1, parameter2, parameter3, NULL );
else if (parameter1[0] && parameter2[0])
execlp( command, command, parameter1, parameter2, NULL );
else if (parameter1[0])
execlp( command, command, parameter1, NULL );
else
execlp( command, command, NULL );
return 1; //should never get here (if all goes well)
}
}
}
printf("Bye.. ");
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.