In: Computer Science
Please find the modified functions along with the full program mentioned in the question. Please provide your feedback.
Thanks and Happy learning!
#include "HALmod.h"
int GetCommand(string tokens[])
{
string commandLine;
bool commandEntered;
int tokenCount;
do
{
cout << "HALshell> ";
while (1)
{
getline(cin, commandLine);
commandEntered = CheckForCommand();
if (commandEntered)
{
break;
}
}
} while (commandLine.length() == 0);
tokenCount = TokenizeCommandLine(tokens, commandLine);
return tokenCount;
}
int TokenizeCommandLine(string tokens[], string commandLine)
{
char *token[MAX_COMMAND_LINE_ARGUMENTS];
char *workCommandLine = new char[commandLine.length() + 1];
int i;
int tokenCount;
for (i = 0; i < MAX_COMMAND_LINE_ARGUMENTS; i++)
{
tokens[i] = "";
}
strcpy(workCommandLine, commandLine.c_str());
i = 0;
if ((token[i] = strtok(workCommandLine, " ")) != NULL)
{
i++;
while ((token[i] = strtok(NULL, " ")) != NULL)
{
i++;
}
}
tokenCount = i;
for (i = 0; i < tokenCount; i++)
{
tokens[i] = token[i];
}
delete[] workCommandLine;
return tokenCount;
}
//Do not touch the below function
bool CheckForCommand()
{
if (cullProcess)
{
cullProcess = 0;
cin.clear();
cout << "\b\b \b\b";
return false;
}
return true;
}
int ProcessCommand(string tokens[], int tokenCount)
{
if (tokens[0] == "shutdown" || tokens[0] == "restart" || tokens[0] == "lo")
{
if (tokenCount > 1)
{
cout << "HALshell: " << tokens[0] << " does not require any arguments" << endl;
return 1;
}
cout << endl;
cout << "HALshell: terminating ..." << endl;
return 0;
}
else
{
//1. fork to create a child and parent
pid_t pid = fork();
//Handle error case for fork()
if (pid < 0)
{
//pid <0 means some error happened while doing fork
cout << "ERROR: Fork failed to create new process." << endl;
}
else if (pid == 0)
{
//This means it is the child process
//1. Call the ConverToC function and capture the return into a char** variable
char ** words = ConvertToC(tokens, tokenCount);
//2. Call execvp sending it two arguments : the first element(or word) of the char** variable, and the entire array
execvp(words[0], tokens);
//3. Print an error message
cout << "ERROR: Could not recognise the given command" << endl;
//4. exit
exit(0);
}
else
{
//case where the pid > 0. This means it is parent process
//1. wait for the child. Wait for the child PID
int waitReturnStatus;
pid_t ret = waitpid(pid, &waitReturnStatus, 0);
if (ret == -1)
{
cout << "ERROR: waitpid call failed" << endl;
}
//2. return 1
return 1;
}
}
}
char ** ConvertToC(string tokens[], int tokenCount)
{
char ** words;
//To store an extra word(NULL), allocate a new space by adding
//one(1) to the tokenCount during malloc
words = (char **)malloc(sizeof(char*) * (tokenCount + 1));
int i = 0;
for (i = 0; i<tokenCount; i++)
{
words[i] = strdup(tokens[i].c_str());
}
//Once the loop exits the value of i will be pointing to the
//last element which was allocated to store the NULL in the
//malloc statement above. So just store the NULL value there.
words[i] = NULL;
return words;
}