Creating a command history feature in a simple UNIX shell using C

I'm trying to write a history feature to a very simple UNIX shell that will list the last 10 commands used when control-c is pressed. A user can then run a previous command by typing r x, where x is the first letter of the command. I'm having quite a bit of trouble figuring out what I need to do, I have very little C experience, but I know a fair bit of C++. If anyone could give me some suggestions as to where to start, I'd appreciate it. Here is the code I'm working from right now.

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

#define MAX_LINE 80 /* 80 chars per line, per command */
#define BUFFER_SIZE 50
char buffer[BUFFER_SIZE];

/* the signal handling function */
void handle_SIGINT()
{
write(STDOUT_FILENO, buffer, strlen(buffer));

}

/**

  • 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;

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()
{
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];
pid_t pid;

/* 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(" sh>\n");
setup(inputBuffer,args,&background); /
get next command */

/* the steps are:
   \(1\) fork a child process using fork\(\) */
pid = fork\(\);
 
if\(pid == 0\)\{ /* child process \(2\) the child process will
                 invoke execvp\(\)*/
  execvp\(args[0], args\);
  exit\(0\);
\}
else if\(pid &gt; 0\)\{ /*parent process \(3\) if background == 1, the parent
                    will wait, otherwise returns to the setup\(\) function.
                  */
  if\(background == 1\)\{
    wait\(NULL\);
    
  \}/* if */   
\}/* if */

}
}

I suggest that you maintain a history file to keep track of the past commands, something like what ksh maintains. The file is .sh_history or something similar in the user's home directory. There is another thing that you would have to do, and that is have an escape sequence by which the user enters the history mode. Ksh in vi mode uses Esc to enter the command mode; you have to use something similar.

Hi, Did you get this code finished, could you send me a copy if so please, I'd really appreciate, thanks
Email address removed