In: Computer Science
Write the simple shell in C language. Please show some outputs.
Write the simple shell in C language. Please show some outputs.
Linux Shell in C
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<readline/readline.h>
#include<readline/history.h>
#define MAXCOM 1000 // max number of letters to be
supported
#define MAXLIST 100 // max number of commands to be
supported
// Clearing the shell using escape sequences
#define clear() printf("\033[H\033[J")
// Greeting shell during startup
void init_shell()
{
    clear();
    printf("\n\n\n\n******************"
        "************************");
    printf("\n\n\n\t****MY
SHELL****");
    printf("\n\n\t-USE
AT YOUR OWN RISK-");
    printf("\n\n\n\n*******************"
        "***********************");
    char*
username =
getenv("USER");
    printf("\n\n\nUSER
is: @%s", username);
    printf("\n");
    sleep(1);
    clear();
}
// Function to take input
int takeInput(char*
str)
{
    char*
buf;
    buf =
readline("\n>>> ");
    if
(strlen(buf) != 0) {
        add_history(buf);
        strcpy(str,
buf);
        return
0;
    }
else {
        return
1;
    }
}
// Function to print Current Directory.
void printDir()
{
    char
cwd[1024];
    getcwd(cwd,
sizeof(cwd));
    printf("\nDir:
%s", cwd);
}
// Function where the system command is
executed
void
execArgs(char** parsed)
{
    // Forking a
child
    pid_t pid =
fork();
    if (pid
== -1) {
        printf("\nFailed
forking child..");
        return;
    }
else if (pid == 0) {
        if
(execvp(parsed[0], parsed) < 0) {
            printf("\nCould
not execute command..");
        }
        exit(0);
    }
else {
        //
waiting for child to terminate
        wait(NULL);
        return;
    }
}
// Function where the piped system commands is
executed
void
execArgsPiped(char** parsed,
char** parsedpipe)
{
    // 0 is read end, 1
is write end
    int
pipefd[2];
    pid_t p1,
p2;
    if
(pipe(pipefd) < 0) {
        printf("\nPipe
could not be initialized");
        return;
    }
    p1 =
fork();
    if (p1
< 0) {
        printf("\nCould
not fork");
        return;
    }
    if (p1
== 0) {
        //
Child 1 executing..
        //
It only needs to write at the write end
        close(pipefd[0]);
        dup2(pipefd[1],
STDOUT_FILENO);
        close(pipefd[1]);
        if
(execvp(parsed[0], parsed) < 0) {
            printf("\nCould
not execute command 1..");
            exit(0);
        }
    }
else {
        //
Parent executing
        p2
= fork();
        if
(p2 < 0) {
            printf("\nCould
not fork");
            return;
        }
        //
Child 2 executing..
        //
It only needs to read at the read end
        if
(p2 == 0) {
            close(pipefd[1]);
            dup2(pipefd[0],
STDIN_FILENO);
            close(pipefd[0]);
            if
(execvp(parsedpipe[0], parsedpipe) < 0) {
                printf("\nCould
not execute command 2..");
                exit(0);
            }
        }
else {
            //
parent executing, waiting for two children
            wait(NULL);
            wait(NULL);
        }
    }
}
// Help command builtin
void openHelp()
{
    puts("\n***WELCOME
TO MY SHELL HELP***"
        "\nCopyright
@ Suprotik Dey"
        "\n-Use
the shell at your own risk..."
        "\nList
of Commands supported:"
        "\n>cd"
        "\n>ls"
        "\n>exit"
        "\n>all
other general commands available in UNIX shell"
        "\n>pipe
handling"
        "\n>improper
space handling");
    return;
}
// Function to execute builtin commands
int
ownCmdHandler(char**
parsed)
{
    int
NoOfOwnCmds = 4, i, switchOwnArg = 0;
    char*
ListOfOwnCmds[NoOfOwnCmds];
    char*
username;
    ListOfOwnCmds[0]
= "exit";
    ListOfOwnCmds[1]
= "cd";
    ListOfOwnCmds[2]
= "help";
    ListOfOwnCmds[3]
= "hello";
    for (i =
0; i < NoOfOwnCmds; i++) {
        if
(strcmp(parsed[0],
ListOfOwnCmds[i]) == 0) {
            switchOwnArg
= i + 1;
            break;
        }
    }
    switch
(switchOwnArg) {
    case
1:
        printf("\nGoodbye\n");
        exit(0);
    case
2:
        chdir(parsed[1]);
        return
1;
    case
3:
        openHelp();
        return
1;
    case
4:
        username
=
getenv("USER");
        printf("\nHello
%s.\nMind that this is "
            "not
a place to play around."
            "\nUse
help to know more..\n",
            username);
        return
1;
    default:
        break;
    }
    return
0;
}
// function for finding pipe
int parsePipe(char*
str, char** strpiped)
{
    int
i;
    for (i =
0; i < 2; i++) {
        strpiped[i]
= strsep(&str, "|");
        if
(strpiped[i] == NULL)
            break;
    }
    if
(strpiped[1] == NULL)
        return
0; // returns zero if no pipe is
found.
    else
{
        return
1;
    }
}
// function for parsing command words
void
parseSpace(char* str,
char** parsed)
{
    int
i;
    for (i =
0; i < MAXLIST; i++) {
        parsed[i]
= strsep(&str, " ");
        if
(parsed[i] == NULL)
            break;
        if
(strlen(parsed[i]) == 0)
            i--;
    }
}
int
processString(char* str,
char** parsed, char**
parsedpipe)
{
    char*
strpiped[2];
    int
piped = 0;
    piped =
parsePipe(str, strpiped);
    if
(piped) {
        parseSpace(strpiped[0],
parsed);
        parseSpace(strpiped[1],
parsedpipe);
    }
else {
        parseSpace(str,
parsed);
    }
    if
(ownCmdHandler(parsed))
        return
0;
    else
        return
1 + piped;
}
int main()
{
    char
inputString[MAXCOM], *parsedArgs[MAXLIST];
    char*
parsedArgsPiped[MAXLIST];
    int
execFlag = 0;
    init_shell();
    while
(1) {
        //
print shell line
        printDir();
        //
take input
        if
(takeInput(inputString))
            continue;
        //
process
        execFlag
= processString(inputString,
        parsedArgs,
parsedArgsPiped);
        //
execflag returns zero if there is no command
        //
or it is a builtin command,
        //
1 if it is a simple command
        //
2 if it is including a pipe.
        //
execute
        if
(execFlag == 1)
            execArgs(parsedArgs);
        if
(execFlag == 2)
            execArgsPiped(parsedArgs,
parsedArgsPiped);
    }
    return
0;
}
To Run the code –
gcc shell.c -lreadline ./a.out
OUT PUT
*********************************************************
**** MY SHELL****
-USE AT YOUR OWN RISK-
*********************************************************
USER is @supde
supdefbubuntw/medla/supde/FILES/Documents/Interships/2ndyriaernshIps/geeksforgeeks
Dirymedia/supdegnEs/Documents/interships/2nd yr internships/yeeksforgeeks/Codes a.out shells
Dir: /media/supde/FILES/Documents/interships/Znd yr internships/geeksforgeeks/Godes xxx mkdir gfg
Dir: /media/supde/FILES/Documents/interships/Znd yr internships/geeksforgeeks/Godes xxx Is a.out gfg shells
Dir:/media/supde/FILES/Documents/interships/Znd yr internships/geeksforgeeks/Godes xxx hello
Hello supde. Mind that this is not a place to play around. Use help to know more..
Dir: /media/supde/FILES/Documents/interships/Znd yr internships/geeksforgeeks/Godes xxx exit
Goodbye