I am currently working on a shell, implemented in C, for class that I hope to build upon over time and have run into a problem with executing my arguments. My program uses getchar() to parse entries into the array of arguments and then executes the arguments using execvp(). The issue I have is in repeated entry of arguments any subsequent shorter arguments are concatenated with characters left in memory somewhere. Example below. And I am required to use getchar, which rules out alternate methods of getting the arguments.
//Global Variables
char argument[64];
char **argv;
int main(int argc, char** argv) {
mainloop(); //Loop that calls the commands
return (EXIT_SUCCESS);
}
void prompt(){ //Modular prompt
printf ("?:");
}
void mainloop(){ //Loop that calls the functions
while(1){
prompt();
argv = (char**)malloc(sizeof(char*)*64); //allocate memory for argv
getcommand(argument, argv);
if((strcmp(argv[0],"exit" )) == 0){ //check for exit
return 0;
}
executecommand();
printcommand();
//clearcommand();
//printcommand();
}
}
void getcommand(char* argument, char** argv){ //Parser for the command
int i=0,j=0;
char c;
char* token;
while((c = getchar()) != '\n' ){ //gets char and checks for end of line
argument[i] = c;
i++;
}
token = strtok(argument, " ,."); //tokenize the command
while (token != NULL){
argv[j] = token; //pass command to array of arguments
token = strtok(NULL, " ,.");
j++;
}
//argv[j] = "\0";
}
void executecommand(){ //Function to call fork and execute with errors
pid_t childpid = fork();
int returnStatus;
if(childpid == -1){ //Fail to Fork
printf("failed to fork");
exit(1);
}
else if(childpid == 0){ //Child process
if (execvp(*argv, argv) < 0){
printf("error executing\n");
exit(1);
}
else{ //Execute successful
printf("executed");
}
}
int c=(int)waitpid(childpid, &returnStatus, 0);
if (returnStatus == 0) // Verify child process terminated without error.
{
printf("The child process terminated normally. \n");
}
if (returnStatus == 1)
{
printf("The child process terminated with an error!.\n");
}
//realloc(argv,64);
}
void printcommand(){ //Test function to print arguments
int i = 0;
while(argv[i] != NULL){
printf("Argv%d: %s \n",i, argv[i] );
i++;
}
}
/*void clearcommand(){ //Function to clear up the memory, does not work
int i=0;
argv[0] = " \0";
argv[1] = " \0";
}*/
Example output:
?: ls -l
//functions as intended
?:echo
//argument returns as echol
This is the case for any entry which is shorter than a previous entry. I do not understand why exec is reading the argument continuing after a '\0' and i am sure that I am making a memory error here. Help would be very much appreciated, I have been stuck on this one for a couple of days now.
cshshell.malloc& friends in C!