Wednesday, February 8, 2012

Shell alternate implementation in C

Introduction

This is the code in which a alternate shell is implemented.


This version of shell is implemented at the very basic level and  does not have the following features.
  • cd command
  • " " when accessing files and folder 
These features will be implemented in future versions.

Important to remember when operating :
  • To set environmental path variable type 'PATH' which will then ask you to type in the path separately. This will not replace the $PATH variable contents but append to its content.
  • To exit mosh type 'exit'

The Algorithm

First this will read the user command character by character. When the user inputs a command, the last letter or rather the last character will be a enter character (\n). So first this character will be replaced by a null character.This will be helpful especially when searching for the end of the command.

Then it will check for any sign of a pipe command. A character by character search is done and if '|' is found inside the command then it will be split into two arrays from that point onwards. This is to make sure that two different arrays can be passed into the child and parent processes.

Then the characters in the array or arrays will be tokenized using the space ( this will break the characters into words) and store the tokenized characters (separate words) into an array. Then simply depending on if its a pipe command or not it will be passed to the relevant execution methods.

The Code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>

char cmd[50];
char cmd2[50];
char *retrn[10];
char *retrn2[10];
int control=1;


//---------------------------------------------------------------------
main()
{
    printf("\n\n\n ------------ ");
    printf(" My Own SHell ");
    printf(" ------------ \n\n\n");
    readInput();
}
//-----------------------------------------------------------------------
keep(){
    if (control==1 || control ==0){
        if(fork()){
            wait();
            readInput();
        }else{
            if (control==1)
                command();
            else if(control==0)
                pipe_command();
        }
    }else{    
        if(control==4){
            set_path();
        }
        else     if (control ==3)
                printf("MOSH will now exit. \n\n");   
            else
                readInput();
    }
   
}

//-----------------------------------------------------------------------

readInput(){
    memset(&cmd[0], 0, sizeof(cmd));
    memset(&cmd2[0], 0, sizeof(cmd2));
    control = 1;
    printf("\n[ MOSH ] $ ");
    if ( fgets(cmd, sizeof cmd, stdin) != NULL ){
        //remove the newline after each line
        char *newline = strchr(cmd, '\n');
        if ( newline != NULL ){
            *newline = '\0';
        }
        //serach for | and determine pipe commands
       
        char *pipe = strchr(cmd, '|');
        if( pipe != NULL){
            control=0;
            // split array and store commands after | into second array
            *pipe= '\0';
            pipe=pipe+1;
            strcpy(cmd2,pipe);
        }
    }

   
       
        int count=0;
        char delims[] = " ";
        char *result = NULL;
        result = strtok( cmd, delims );
        // look for command exit
        if(strcmp(cmd,"exit") == 0)
            control=3;
        //look for path setting command
        if(strcmp(cmd,"PATH") == 0)
            control=4;
        while( result != NULL ) {
             retrn[count]=result;
                result = strtok( NULL, delims );
            count+=1;
        }
        count=0;
        result = strtok( cmd2, delims );
        while( result != NULL ) {
             retrn2[count]=result;
                result = strtok( NULL, delims );
            count+=1;
    }
    keep();
}

//-----------------------------------------------------------------------

command(){       
    execvp(retrn[0],retrn);
}

//-----------------------------------------------------------------------

pipe_command(){
    //execute pipe command
    int pfds[2];
    pipe(pfds);
    if (!fork()) {
        close(1);      
        dup(pfds[1]);  
        close(pfds[0]);
        execvp(retrn[0],retrn);
    } else {
        close(0);     
        dup(pfds[0]);  
        close(pfds[1]);
        execvp(retrn2[0],retrn2);
    }   
}

//-----------------------------------------------------------------------
set_path(){
    char* pathvar=getenv("PATH");;
    printf("          Enter Path variable : ");
    fgets(cmd, sizeof cmd, stdin);
    char* path=malloc(sizeof(char)* (strlen(pathvar)+strlen(cmd)+2));
    path=strcat(path,pathvar);
    path=strcat(path,":");
    path=strcat(path,cmd);
    path=strcat(path, "\0");
       setenv("PATH",path,1);
    free(path);
    readInput();
}

Hope you enjoy !!!! :D :D

No comments:

Post a Comment