In: Computer Science
Question from Operating Systems
Proc,Forks,Exec
Examine the code given and do changes as mentioned in the steps below:
#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
return 1;
}
char ** ConvertToC (string tokens [], int tokenCount)
{
char ** words;
words = (char **) malloc (sizeof (char*) * tokenCount);
for (int i=0; i<tokenCount; i++)
{
words[i]=strdup(tokens[i].c_str());
}
return words;
}
Step 1- Modify the "ConvertToC" function ( last function) as mentioned:
1. allocate an extra "word" for NULL (Hint: tokenCount+1)
2. store the value of NULL into the extra "word"
Step 2- Modify the "ProcessCommand" function ( second last function) as mentioned:
You will be emulating a shell. First, the shell checks for specific commands ("shutdown", "lo", etc). If it does not recognize those commands then, a fork occurs and the child will execute the command as typed.
The algorithm to implement is as follows (Hint: add code inside the else):
1. fork to create a child and parent
2. the child will do the following:
Call the ConverToC function and capture the return into a char**
variable
Call execvp sending it two arguments: the first element (or word)
of the char** variable, and the entire array
Print an error message
exit
3. the parent will do the following:
wait for the child
return 1
4. don't forget to handle the error case of the fork
//Dont try to run the program, just do the following
steps.
#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{
char ** va;
pid_t pid;
pid = fork();
if (pid == 0) {
va=ConvertToC();
execvp(*word, words);
printf("Error\n");
}
else{
wait(NULL);
}
return 1;
}
}
char ** ConvertToC (string tokens [], int tokenCount)
{
char ** words;
char ** word
words = (char **) malloc (sizeof (char*) * tokenCount);
word = (char **) malloc (sizeof (char*) * tokenCount+1);
word=NULL;
for (int i=0; i<tokenCount; i++)
{
words[i]=strdup(tokens[i].c_str());
}
return words;
}