Problems with Implementing History in a Simple UNIX Shell
I'm trying to implement a history feature for a simple shell. The history should hold the last 10 commands executed. I placed my code below, but I am running into some problems.

First, when I enter one (or two) commands and type in `history`to display the history, nothing is displayed. But, when I enter a few more commands, the entire history is displayed (like it should), but a string of zero's is displayed next to each history index. 

What am I doing wrong, and how can I fix this? 

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
    
    char *history[10][MAX_LINE];
    int placePointer;
    /**
     * Additional code added by: Matthew Bear
     */
    
    
    /**
     * 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);  
    
        start = -1;
        if (length == 0)
            exit(0);            /* ^d was entered, end of user command stream */
        if (length < 0){
            perror("error reading the command");
    		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;
    
            case '&':
                *background = 1;
                inputBuffer[i] = '\0';
                break;
                
            default :             /* some other character */
                if (start == -1)
                    start = i;
    		} 
        }    
        args[ct] = NULL; /* just in case the input line was > 80 */
    } 
    
    void displayHistory(){
    	printf("Display History:\n");
    	int i = placePointer;
    	int j;
    	int counter;
    	while(counter < 10) {
    		printf("%d: ",counter);
    		for (j = 0; j < MAX_LINE; j++) {
    		  printf("%d",history[i][j]);
    		}
    		printf("\n");
    		i = (i + 1) % 10;
    		counter++;
    	}
    }
    /*
    void runHistoryAt(int index){
    	printf("Run History At:\n");
    	char *arg1 = &history[placePointer + index][0];
    	char *argLine[MAX_LINE/2+1];
    	int j;
    	for (j = 0; j < MAX_LINE/2+1; j++) {
    	  *argLine[j] = history[placePointer + index][j];
    	}
    	execvp(arg1,argLine);
    }*/
    
    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/2+1];/* command line (of 80) has max of 40 arguments */
        
    
        while (1){            /* Program terminates normally inside setup */
    		background = 0;
    		printf("COMMAND->");
    			fflush(0);
    			setup(inputBuffer, args, &background);       /* get next command */
    
    		/* the steps are:
    		 (1) fork a child process using fork()
    		 (2) the child process will invoke execvp()
    		 (3) if background == 0, the parent will wait, 
    			otherwise returns to the setup() function. */
    		
    		pid_t pid = fork();
    		printf("Fork created.\n");
    		
    
    		if(pid < 0){
    			printf("Fork failed.\n");
    		}else if(pid == 0){
    			if( strcmp(args[0],"history") == 0){ /*  Print History */
    				displayHistory();
    			}else if(strcmp(args[0],"r") == 0){ /*  r num */
    				int index = (int) args[1];
    				/*runHistoryAt( index - 1);*/
    			}else if(strcmp(args[0],"rr") == 0){ /*  Run recent */
    				/*runHistoryAt(0);*/
    			}else{  /*  Execute normally */
    				printf("executing..., adding to history buffer\n");
    				/* Add args to history buffer */
    				int j;
    				for (j = 0; j < sizeof(args); j++) {
    					history[placePointer][j] = args[j];
    				}
    				placePointer = (placePointer + 1) % 10;
    				/* Execute!  */
    				execvp(args[0],args);
    			}
    		}
    		
    		if(background == 0){
    			wait(NULL);
    		}else{
    		  setup(inputBuffer, args, &background);
    		}
        }
    }




Problems with Implementing History in a Simple UNIX Shell
===

I'm trying to implement a history feature for a simple shell. The history should hold the last 10 commands executed. I placed my code below, but I am running into some problems.

First, when I enter one (or two) commands and type in `history`to display the history, nothing is displayed. But, when I enter a few more commands, the entire history is displayed (like it should), but a string of zero's is displayed next to each history index. 

What am I doing wrong, and how can I fix this? 

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
    
    char *history[10][MAX_LINE];
    int placePointer;
    /**
     * Additional code added by: Matthew Bear
     */
    
    
    /**
     * 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);  
    
        start = -1;
        if (length == 0)
            exit(0);            /* ^d was entered, end of user command stream */
        if (length < 0){
            perror("error reading the command");
    		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;
    
            case '&':
                *background = 1;
                inputBuffer[i] = '\0';
                break;
                
            default :             /* some other character */
                if (start == -1)
                    start = i;
    		} 
        }    
        args[ct] = NULL; /* just in case the input line was > 80 */
    } 
    
    void displayHistory(){
    	printf("Display History:\n");
    	int i = placePointer;
    	int j;
    	int counter;
    	while(counter < 10) {
    		printf("%d: ",counter);
    		for (j = 0; j < MAX_LINE; j++) {
    		  printf("%d",history[i][j]);
    		}
    		printf("\n");
    		i = (i + 1) % 10;
    		counter++;
    	}
    }
    /*
    void runHistoryAt(int index){
    	printf("Run History At:\n");
    	char *arg1 = &history[placePointer + index][0];
    	char *argLine[MAX_LINE/2+1];
    	int j;
    	for (j = 0; j < MAX_LINE/2+1; j++) {
    	  *argLine[j] = history[placePointer + index][j];
    	}
    	execvp(arg1,argLine);
    }*/
    
    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/2+1];/* command line (of 80) has max of 40 arguments */
        
    
        while (1){            /* Program terminates normally inside setup */
    		background = 0;
    		printf("COMMAND->");
    			fflush(0);
    			setup(inputBuffer, args, &background);       /* get next command */
    
    		/* the steps are:
    		 (1) fork a child process using fork()
    		 (2) the child process will invoke execvp()
    		 (3) if background == 0, the parent will wait, 
    			otherwise returns to the setup() function. */
    		
    		pid_t pid = fork();
    		printf("Fork created.\n");
    		
    
    		if(pid < 0){
    			printf("Fork failed.\n");
    		}else if(pid == 0){
    			if( strcmp(args[0],"history") == 0){ /*  Print History */
    				displayHistory();
    			}else if(strcmp(args[0],"r") == 0){ /*  r num */
    				int index = (int) args[1];
    				/*runHistoryAt( index - 1);*/
    			}else if(strcmp(args[0],"rr") == 0){ /*  Run recent */
    				/*runHistoryAt(0);*/
    			}else{  /*  Execute normally */
    				printf("executing..., adding to history buffer\n");
    				/* Add args to history buffer */
    				int j;
    				for (j = 0; j < sizeof(args); j++) {
    					history[placePointer][j] = args[j];
    				}
    				placePointer = (placePointer + 1) % 10;
    				/* Execute!  */
    				execvp(args[0],args);
    			}
    		}
    		
    		if(background == 0){
    			wait(NULL);
    		}else{
    		  setup(inputBuffer, args, &background);
    		}
        }
    }



