I have been trying to program a UNIX style shell command prompt in C. Within this program I need it to keep track of the commands that have already been used, so the user can recall the last command by entering ‘r’. I made a globally initialized array to hold strings. Whenever the array of characters a user entered needs to be saved, I add it to the global array. I have tried memcpy, simply copying each value using a loop, and just copying the pointer. None of these have been working. I am not super familiar with C and I am sure it is a pointer problem.
Whenever I copy the pointer of inputBuffer to my global array string (it does get copied), however upon leaving the setup function this pointer disappears? I am not exactly sure what I am doing wrong.
Test:
(1)user input –> ls
string[0] = ls
(2)user input –> r
inputBuffer = ls
string[recent] = ls
incorrectly does…
inputBuffer = r
string[recent] = r
(I have included the relevant parts of the code.)
#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
#define SAVED_BUFFER 100
char *string[SAVED_BUFFER];
int p = 0;
int recent = -1;
int stringSize = 0;
void setup(char inputBuffer[], char *args[],int *background)
{
int length, /* # of characters in the command line *
/* 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 */
}
if (inputBuffer[0] == 'r' && inputBuffer[1] == '\n' && stringSize > 0) {
int k;
memcpy(inputBuffer, string[recent], strlen(string[recent]) + 1);
printf("%s",inputBuffer);
printf("%s",string[recent]);
}
else {
string[p] = inputBuffer;
printf("%s", string[0]);
stringSize++;
recent++; // one behind strings current array location, to get history
p++; // current string array spot
}
}
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("COMMAND2->");
fflush(0);
setup(inputBuffer, args, &background); /* get next command */
}
}
When you “save the input buffer” you actually only store a pointer to the
inputBufferarray:The actual data is not copied, you just store a pointer to the global input buffer. When the next input replaces the old content of
inputBuffer, you will see the new content even if you access it throughstring[recent].The calls to
memcpydon’t actually do anything, since the passed input and output buffer all refer to the same memory.To actually store a copy of the data you have to allocate new memory to store the copy. Since you are dealing with strings, this is most easily done with
strdup(), which duplicates a string:Later, once you are done with such a copy and don’t need it anymore you have to free the memory used by the copy: