Sunday 20 August 2017

OS example my shell



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define delim " \t"
#define MAX 100
///////////////// Functions to be Used /////////////////
void get_command();
void parse_command();
void chDir();
char check_for_ampersand();
void spawn_new_process(int signal);
void run_in_background();
///////////////// Variables to be Used /////////////////
char str[MAX];
char *token[MAX/2], *token2[MAX/2];
int pid, died, status;

void main()
{
       printf("Initializing New Shell...\n");
       while(1)
       {
              printf("My Shell ~ $ ");
              get_command();
              parse_command();
              if(strcmp(token[0], "exit") == 0)
                     exit(0);
              else if(strcmp(token[0], "cd") == 0)
                     chDir();
              else
                     switch(check_for_ampersand())
                     {
                           case '&':
                                  spawn_new_process(1);
                                  break;
                           default:
                                  spawn_new_process(0);
                                  break;
                     }
       }
}
///////////////// Get Command from User ////////////////
void get_command()
{
       int i = 0;
       while((i < MAX) && ((str[i] = getchar()) != '\n'))
              i++;
//If Input Extends MAX, the Additional Arguments are Cut
       if(i == MAX)
              str[MAX-1] = '\0';
       else
              str[i] = '\0';
}


///////// Parse Command to Get Different Tokens ////////
void parse_command()
{
       int i = 0;
       token[i] = strtok(str, delim);
       while(token[i] != NULL)
       {
              i++;
              token[i] = strtok(NULL, delim);
       }
}
///////// Change the Current Working Directory /////////
void chDir()
{
       int rv;
       if(token[1] != NULL)
              rv = chdir(token[1]);
       if(rv != 0)
              printf("Error in Changing Directory...\n");
       else
              printf("Current Directory %s\n", token[1]);
}
///////// Check If the Input has '&' Sign in it ////////
char check_for_ampersand()
{
       int i;
       for (i = 0; token[i] != '\0'; i++)
       {
           if (strcmp(token[i], "&") == 0)
                     return token[i][0];
       }
       return '\0';
}
//// Create a New Process Using fork() and execvp() ////
void spawn_new_process(int signal)
{
       switch(pid = fork())
       {
              case -1:
                     // Something did not work....
                     printf("Something went wrong. Unable to create child :(\n");
                     exit(-1);
              case 0:
                     // If Input Contains a '&' Sign, then Run the Processes in Parallel
                     if(signal == 1)
                           run_in_background();
                     else if(signal == 0)
                     {
                           execvp(token[0], token);
                           printf("Command %s not found\n", token[0]);
                     exit(0);
                     }
              default:
                     died = wait(&status);
       }
}


//Create a New Process & Run Both Parent & Child in Parallel
void run_in_background()
{
       int i, count = 0;
       for(i = 0; token[i] != NULL; i++)
              if(strcmp(token[i], "&") == 0)
              {
                     token[i] = NULL;
                     while (token[i+1] != NULL)
                     {
                           token2[count] = token[i+1];
                           token[i+1] = NULL;
                           i++;
                           count++;
                     }
              }
       switch(pid = fork())
       {
              case -1:
                     printf("Something went wrong. Unable to create child :(\n");
                     exit(-1);
              case 0:
                     execvp(token[0], token);
                     printf("Command %s not found\n", token[0]);
                     exit(1);
              default:
                     usleep(10000);
                     exit(0);
       }
}

0 comments: