Skip to main content

UNIX Shell & History Feature

Operating System Project

Implementation of UNIX Shell & History Feature in C language


Note: - Implement this code on Linux platform
How to Compile?
      cc -o exec_name source_name.c 


Source Code: -

/* press ctrl-c to show history & press ctrl-d to exit from command prompt */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
#define BUFFER_SIZE 50
#define buffer "\n\nCommand History:\n"

char history[10][BUFFER_SIZE];
int count = 0;
int caught = 0;

void printHistory()
{
int i;
int j = 0;
int hcount = count;
for (i = 0; i<10;i++)
{
printf("%d.  ", hcount);
while (history[i][j] != '\n' && history[i][j] != '\0')
{
printf("%c", history[i][j]);
j++;
}
printf("\n");
j = 0;
hcount--;
if (hcount ==  0)
break;
}


printf("\n");
printf("COMMAND->\n");
}

/* the signal handler function */
void handle_SIGINT()
{
write(STDOUT_FILENO,buffer,sizeof(buffer));
printHistory();
caught = 1;
}


/*
  setup() reads in the next command line, separating it into distinct tokens
using whitespace as delimiters. setup() sets the args parameter as a
 null-terminated string.
 */


void setup(char inputBuffer[], char *args[],int *background)
{
int length, /* # of characters in the command line */
        i,     /* loop index for accessing inputBuffer array */
        start,  /* index where beginning of next command parameter is */
        ct;     /* index of where to place the next parameter into args[] */
    ct = 0;

    /* read what the user enters on the command line */
length = read(STDIN_FILENO, inputBuffer, MAX_LINE);

if (caught == 1)
{
length = read(STDIN_FILENO, inputBuffer, MAX_LINE);
caught = 0;
}
for (i = 9;i>0; i--)
strcpy(history[i], history[i-1]);

strcpy(history[0],inputBuffer);
count++;
start = -1;
    if (length == 0)
exit(0);            /* ^d was entered, end of user command stream */
     if (length < 0)
{
         perror("error reading the command\n");
exit(-1);           /* terminate with error code of -1 */
}

/* examine every character in the inputBuffer */
for (i=0;i<length;i++)
{
switch (inputBuffer[i])
{
case ' ':
  case '\t' :               /* argument separators */
if(start != -1)
{
args[ct] = &inputBuffer[start];    /* set up pointer */
ct++;
}
        inputBuffer[i] = '\0'; /* add a null char; make a C string */
start = -1;
break;
   
case '\n':                 /* should be the final char examined */
if (start != -1)
{
        args[ct] = &inputBuffer[start];
ct++;
}
        inputBuffer[i] = '\0';
        args[ct] = NULL; /* no more arguments to this command */
break;

default :             /* some other character */
if (start == -1)
start = i;
            if (inputBuffer[i] == '&')
{
*background  = 1;
              inputBuffer[i] = '\0';
}
}
    }
 
 args[ct] = NULL; /* just in case the input line was > 80 */
}

int main(void)
{
    char inputBuffer[MAX_LINE]; /* buffer to hold the command entered */
    int background;             /* equals 1 if a command is followed by '&' */
    char *args[MAX_LINE/+1];/* command line (of 80) has max of 40 arguments */

    pid_t pid;
    int i;


    /* set up the signal handler */
    struct sigaction handler;
   handler.sa_handler = handle_SIGINT;
    sigaction(SIGINT, &handler, NULL);

    while (1)
    {            /* Program terminates normally inside setup */
background = 0;
printf(" COMMAND->\n");
      setup(inputBuffer,args,&background);       /* get next command */
/* the steps are:
                (1) fork a child process using fork()*/
pid = fork();
if (pid < 0)
                {

printf("Fork failed.\n");
exit (1);
                }

                // (2) the child process will invoke execvp()
else if (pid == 0)
                {
if (execvp (args[0], args) == -1)
printf("Error executing command\n");
}

                // (3) if background == 0, the parent will wait,
               // otherwise returns to the setup() function.
else
                {
if (background == 0)
wait(NULL);
}
}
}

Comments

Popular posts from this blog

Use Case Diagram for Online Book Store

Linear search & Binary search using Template

Write a program to search an element from a list. Give user the option to perform Linear or Binary search. Use Template functions. #include<iostream> using namespace std; template <class T> void Lsearch(T *a, T item, int n) { int z=0; for(int i=0;i<n;i++) { if(a[i]== item) { z=1; cout<<"\n Item found at position = "<<i+1<<"\n\n"; } else if(z!=1) { z=0; } } if(z==0) cout<<"\n Item not found in the list\n\n"; } template <class T> void Bsearch(T *a, T item, int n) { int beg=0,end=n-1; int mid=beg+end/2; while((a[mid]!=item) && (n>0)) { if(item>a[mid]) beg=mid; else end=mid; mid=(beg+end)/2; n--; } if(a[mid]==item) cout<<"\n Item found at position = "<<mid+1<<"\n\n"; else cout<<"\n Item not found in the list\n\n"; } void main() { int iarr[10] = {2,42,56,86,87,99,323,546,767,886};...

Occurrences of each letter of alphabet in the text

Program to print a table indicating the no. of occurrences of each letter of alphabet in the text entered as command line arguments. #include<iostream> #include<string> using namespace std; int main(int argc, char *argv[]) { string str=""; static int alphabet[26]; int x; cout<<"\n\n Command-Line Argument\n"; for(int i=0;i<argc;i++) { cout<<"\n "<<argv[i]; str+=argv[i]; } for(int i=0;i<str.length();i++) { if(str[i]>='A' && str[i]<='Z') { x=((int)str[i])-65; alphabet[x]++; } else if(str[i]>='a' && str[i]<='z') { x=((int)str[i])-97; alphabet[x]++; } } //Displaying No. of occurrences of each alphabets in the command line argument cout<<"\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n Alphabet No. of Occurrences\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; for(int i=0;i<26;i++)...