Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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;
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote