I'm implementing a history feature for a command line shell. I've implemented a circular array to hold to ten most recent commands. Each command is also labeled by an integer specifying which total command is. For Example, if 30 total commands were entered, the ten commands in the circular array would be numbered (30, 29, 28, 27,...,21).
If a user were to insert the command "r" followed by a number labeling one of the ten instructions then that instruction is supposed to run. I keep running into a seg fault when trying to ensure that a two word command is accepted properly. Can anyone help point out what the problem is.
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 */
int position, count, rnum = 0;
char historyArray[10][MAX_LINE];
char *holder[MAX_LINE]={0};
while (1){ /* Program terminates normally inside setup */
background = 0;
printf("COMMAND->");
fflush(0);
setup(inputBuffer, args, &background); /* get next command */
position = (count % MOD_VAL);
strcpy(historyArray[position],args[0]);
if(!strcmp("rr",args[0]))
{
strcpy(historyArray[position],historyArray[((position-1)+MOD_VAL)%MOD_VAL]);
printf("%i",count);
printf("%c",'.');
printf("%c",' ');
printf("%s",historyArray[position]);
printf("%c",'\n');
strcpy(args[0],historyArray[position]);
}
else if(!strcmp("r",args[0])) //SEG FAULT OCCURING IN THIS ELSE-IF BLOCK!
{
//args[1] will hold given number
printf("%c",'\n');
printf("%s",args[0]);
printf("%s",args[1]);
printf("%s",args[2]);
printf("%c",'\n'); //PRINT STATEMENTS FOR DEBUGGING
strncpy(holder[0], args[2], MAX_LINE - 1); //SEG FAULT
rnum = atoi(args[1]);
strcpy(historyArray[position],historyArray[((position-(count-rnum))+MOD_VAL)%MOD_VAL]);
strcpy(args[0],historyArray[position]); //CHANGES VALUES OF args[1], args[2]
if(holder[0] != NULL)
{
strncpy(args[1],holder[0],MAX_LINE-1);
args[2] = NULL;
}
else
{
args[1] = NULL;
}
printf("%c",'\n');
printf("%s",args[0]);
printf("%s",args[1]);
printf("%s",args[2]);
printf("%c",'\n');
}
else if(!(strcmp("h",args[0]))||!(strcmp("history",args[0])))
{
int counter = 0;
while(counter < 10)
{
printf("%i",(count - counter));
printf("%c",'.');
printf("%c",' ');
printf("%s", historyArray[((position - counter + MOD_VAL)%MOD_VAL)]);
printf("%c",' ');
printf("%c",'\n');
counter ++;
if(counter > count)
break;
}
}
count++;
pid_t pid1; //Initialize pid_t variable to hold process identifier
pid1 = fork(); //Fork process and assign process identifier to "pid1"
if (pid1 == 0) //Child process
{
//Child process executes the command specified by the user and
//then quits.
execvp(args[0], args);
exit(0);
}
else //Parent process
{
if (background != 1)//Check for inclusion of '&' in command
{
wait(NULL); //Wait for child process to finish executing
}
}
/* 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. */
}
}
Any assistance is appreciated!
-MATT