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

Main menu dropdown parent item clickable in Drupal 8 using Bootstrap 4

 Edit menu--main.html.twig template file {# /**  * @file  * Bootstrap Barrio's override to display a menu.  *  * Available variables:  * - menu_name: The machine name of the menu.  * - items: A nested list of menu items. Each menu item contains:  *   - attributes: HTML attributes for the menu item.  *   - below: The menu item child items.  *   - title: The menu link title.  *   - url: The menu link url, instance of \Drupal\Core\Url  *   - localized_options: Menu link localized options.  *   - is_expanded: TRUE if the link has visible children within the current  *     menu tree.  *   - is_collapsed: TRUE if the link has children within the current menu tree  *     that are not currently visible.  *   - in_active_trail: TRUE if the link is in the active trail.  */ #} {% import _self as menus...

Add JS to the bottom of the page in Drupal 7

How to add JS at bottom of a particular page in Drupal 7 Step 1: Get the page id. In case of front page "is_front"  Step 2: In template.php file of your theme add the below code : function illume_preprocess_page(&$variables) { if ($variables['is_front']) { drupal_add_js(path_to_theme().'/js/util.js', array('type' => 'file', 'scope' => 'footer')); drupal_add_js(path_to_theme().'/js/main.js', array('type' => 'file', 'scope' => 'footer')); drupal_add_js(path_to_theme().'/js/slideimage.js', array('type' => 'file', 'scope' => 'footer')); $variables['bottom_scripts'] = drupal_get_js(); } } This way you can add JS file using drupal_add_js() and define scope as footer. Step 3: Now you can use bottom_script variable to the page tpl file where you want to add JS print $bottom_scripts;

Use Case Diagram for Online Book Store