Well, I've gotten pretty far. input and output seem to work alright, I can run commands (although I've only really tested ls), and it will exit on exit. Only issue is my cd command seems to go on and off. Works the first time when do "cd test" and go to projectFolder/test, works again when I do "cd .." and then once more so I'm at the folder above. trying to go back to projectFolder "cd projectFolder" it just doesn't change the directory.
Since this is just homework and not a real world application, I'm not hurting, but it's bugging me like all get out trying to figure out why this is happening.
Full code below compiles and runs on my linux partition if anyone wants to try it and tell me what they think/know is happening
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <time.h>
#include <signal.h>
#include <termios.h>
int getInput(char *outputBuffer, int currentPos, char *breakCharacter){
//Declare:
char *output = outputBuffer + currentPos; //outputBuffer
int position = currentPos; //outputPosition = 0
char *broken = breakCharacter; //brokenCharacter
char tempChar, tempChar1, tempChar2;
//while not broken
while(1){
//read to innerBuffer
tempChar = getc(stdin);
//for each character in innerBuffer
//if current character is an ignore character
//- do nothing
if(tempChar == 27){
tempChar1 = getc(stdin);
tempChar2 = getc(stdin);
if(tempChar2 == 68 || tempChar2 == 67)
continue;
else if(tempChar2 ==65){
*broken = 'u'; //for up, saves 2 characters and allows for more uniform code.
break;
}
else if(tempChar2 == 66){
*broken = 'd'; //for down
break;
}
}
//else if current character is a break character
//- set brokenCharacter
//- break out of loops
else if(tempChar == '\n'){
*broken = '\n';
break;
}
//else if current character is backspace or delete
//- print \b
//- decrement outputPosition
if(tempChar == 8 || tempChar == 127){
if(position > 0){
putchar('\b');
putchar(' ');
putchar('\b');
position--;
}
}
//else
//- print current character
//- copy the current character to outBuffer at
//outputPosition
//- increment the outputPosition
else{
putchar(tempChar);
output[position] = tempChar;
position++;
}
}
//Return:
//outputBuffer
//size of outputBuffer
//brokenCharacter
outputBuffer = output;
return position;
}
int main()
{
//configure the input (termios)
// get the original configuration
struct termios origConfig;
tcgetattr(0, &origConfig);
// create a copy of the original configuration
struct termios newConfig = origConfig;
// adjust the new configuration
newConfig.c_lflag &= ~(ICANON|ECHO);
newConfig.c_cc[VMIN] = 3;
newConfig.c_cc[VTIME] = 1;
// set the new configuration
tcsetattr(0, TCSANOW, &newConfig);
char command[512];
char *runCommand[10];
char breakCharacter = '\n';
char *brokenCharacter = &breakCharacter;
int commandSize = 0;
//while not exited
//print prompt
char cwd[512];
getcwd(cwd, 512);
printf("%s>", cwd);
while(1){
//read input (break on up, down and \n)
commandSize = getInput(command, commandSize, brokenCharacter);
//if broken on up or down
if(breakCharacter == 'd' || breakCharacter == 'u'){
//clear the current input
int i;
for(i = commandSize; i > 0; i--){
putchar('\b');
putchar(' ');
putchar('\b');
}
//execute appropriate command to generate corresponding message
if(breakCharacter == 'u'){
strcpy(command, getlogin());
commandSize = strlen(command);
printf("%s", command);
}
else{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
strcpy(command, asctime(timeinfo));
commandSize = strlen(command)-1;
command[commandSize] = '\0';
printf("%s", command);
}
continue;
}
else{
//parse input into a command
char *token = strtok(command, " ");
int i = 0;
while(token != NULL)
{
if(i > 8){
printf("I didn't account for a command with more than 9 tokens, sorry!");
return -1;
}
runCommand[i] = token;
token = strtok(NULL, " ");
i++;
}
runCommand[i] = NULL;
//if cd command
if(strcmp(runCommand[0], "cd") == 0){
//change the current working directory
chdir(runCommand[1]);
putchar('\n');
getcwd(cwd, 512);
printf("%s>", cwd);
for(i = 0; i < commandSize; i++){
command[i] = '\0';
}
commandSize = 0;
for(i = 0; i < 9; i++)
runCommand[i] = NULL;
}
//else if exit command
else if(strcmp(runCommand[0], "exit") == 0){
//break
break;
}
//else
else{
//execute the command
int status; //holds status
int pid = fork(); //initiates fork and stores pid, 0 for child >0 for parent.
if(pid == 0){ //child process code
//execute command.
putchar('\n');
execvp(runCommand[0], runCommand);
perror(NULL);
exit(1);
}
else{ //parent process code
//waits until child process (pid) is finished.
waitpid(pid, &status, WUNTRACED);
for(i = 0; i < commandSize; i++){
command[i] = '\0';
}
commandSize = 0;
for(i = 0; i < 9; i++)
runCommand[i] = NULL;
getcwd(cwd, 512);
printf("%s>", cwd);
}
}
}
}
//restore the input configuration (termios)
tcsetattr(0, TCSANOW, &origConfig);
return 0;
}
Also, big thanks to Jorl17 for the initial advice that got me past that block.