214 lines
No EOL
4.8 KiB
C
214 lines
No EOL
4.8 KiB
C
#include <unistd.h>
|
|
#include <sys/wait.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
|
|
#define LEN 512
|
|
#define PATH "/bin/"
|
|
#define ERROR -1
|
|
#define EXIT_1 256
|
|
|
|
int getHostName(char* host);
|
|
int getUserName(char* name);
|
|
int runExec(char** args);
|
|
void PrintTokens (char** tokens);
|
|
char** ReadTokens(FILE* stream) ;
|
|
void FreeTokens(char** tokens) ;
|
|
void checkIfQuit(char* word);
|
|
|
|
|
|
int main()
|
|
{
|
|
int exitCode = 0;
|
|
char* host_n = (char *)malloc(sizeof(char));
|
|
char* user_n = (char *)malloc(sizeof(char));
|
|
char** args;
|
|
|
|
if(getHostName(host_n) == ERROR)
|
|
goto quit;
|
|
if(getUserName(user_n) == ERROR)
|
|
goto quit;
|
|
|
|
while(1)
|
|
{
|
|
printf("%d %s@%s$ ",exitCode, user_n, host_n);
|
|
args = ReadTokens(stdin);
|
|
if(args != NULL)
|
|
{
|
|
exitCode = runExec(args);
|
|
FreeTokens(args); //in case of error while trying to create process - this method will free the memory already
|
|
if(exitCode == ERROR)
|
|
goto quit;
|
|
}
|
|
}
|
|
|
|
quit:
|
|
free(host_n);
|
|
free(user_n);
|
|
return 0;
|
|
}
|
|
|
|
int getHostName(char* host)
|
|
{
|
|
if(gethostname(host, 10) != 0)
|
|
{
|
|
fprintf(stderr, "%s\n", "Error: while getting host name");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int getUserName(char* name)
|
|
{
|
|
if(getlogin_r(name, 10) != 0)
|
|
{
|
|
fprintf(stderr, "%s\n", "Error: while getting User name");
|
|
return ERROR;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* This function will atempt to create a new Process.
|
|
* and will return the exit status code of the child
|
|
* @param args - an array of strings that contains all the arguments from the user
|
|
* @return int - exit status of child
|
|
*/
|
|
int runExec(char** args)
|
|
{
|
|
int status;
|
|
pid_t pid;
|
|
char* path = (char *)malloc(sizeof(char));
|
|
char* exe = (char *)malloc(sizeof(char));
|
|
strcpy(exe,args[0]);
|
|
strcpy(path, PATH);
|
|
strcat(path, exe);
|
|
|
|
printf("try: %s \n",args[0]);
|
|
|
|
pid = fork();
|
|
|
|
if(pid < 0)
|
|
{
|
|
fprintf(stderr, "%s\n", "Error: Could not create a new process");
|
|
return ERROR;
|
|
}
|
|
else if(pid == 0) // child
|
|
{
|
|
if(execv(path, args) != 0)
|
|
{
|
|
fprintf(stderr, "%s%s%s\n", "myTerminal: ", args[0] ,": command not found");
|
|
exit(1); //child error - chield needs to be closed manually. exit code 225;
|
|
}
|
|
}
|
|
else //pid > 0 father
|
|
waitpid(pid,&status,0);
|
|
free(path);
|
|
if(status == EXIT_1) //in my computer exit(1) returns 256 - ex demands wanted 255
|
|
return status-1;
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* this func will read a full line and will store all the arguments in an array (of char*).
|
|
* if the line will have only 1 word - it will call afunction to check if the word is "quit".
|
|
*
|
|
* @param stream FILE* - in our case stdin
|
|
* @return if all went well , an Array of arguements from the input line.
|
|
*/
|
|
char** ReadTokens(FILE* stream)
|
|
{
|
|
char** returnArr;
|
|
char input[LEN]; // the var to hold the line
|
|
char temp[LEN]; // will be a copy of the input line - so we can figure how many words we have
|
|
int wordCnt = 0; // word counter
|
|
int i = 0; //index for second iteration
|
|
fgets(input, LEN, stream); // get the linei
|
|
|
|
strcpy(temp, input); // copy the line
|
|
|
|
//strkot first iteration to count words (corrups temp var)
|
|
char* tok;
|
|
tok = strtok(temp," \n");
|
|
while (tok != NULL)
|
|
{
|
|
wordCnt++;
|
|
tok = strtok(NULL, " \n");
|
|
}
|
|
|
|
if(wordCnt == 0) //if there are no "words" in input - return null
|
|
return NULL;
|
|
|
|
|
|
returnArr = (char**)malloc((wordCnt + 1)*sizeof(char*)); //allocates the memory for the array
|
|
if(returnArr == NULL) //check if the malloc func finished successfuly
|
|
{
|
|
fprintf(stderr,"%s\n", "ERROR: unable to allocate memory.");
|
|
exit(1);
|
|
}
|
|
|
|
//strtok second iteration - puts all words in an index of the array
|
|
tok = strtok(input," \n");
|
|
while (tok != NULL)
|
|
{
|
|
returnArr[i] = (char *)malloc(strlen(tok)*sizeof(char));
|
|
//returnArr[i] = tok;
|
|
strcpy(returnArr[i], tok);
|
|
if(wordCnt == 1)
|
|
checkIfQuit(tok);
|
|
tok = strtok(NULL, " \n");
|
|
i++;
|
|
}
|
|
|
|
returnArr[wordCnt] = NULL; // the last index will be NULL - so we know where the end is.
|
|
|
|
return returnArr;
|
|
}
|
|
|
|
/**
|
|
* if there is only one word in the input nile the ReadTokens func will call this func.
|
|
* it will check if user want to exit our program
|
|
*
|
|
* @param word - the one word to check
|
|
*/
|
|
void checkIfQuit(char* word)
|
|
{
|
|
if(strcmp(word, "quit") == 0)
|
|
exit(0);
|
|
}
|
|
|
|
/**
|
|
* this func will print an array of char*, it will know when to finish if the
|
|
* last index is NULL!
|
|
* @param tokens - char* Array
|
|
*/
|
|
void PrintTokens (char** tokens)
|
|
{
|
|
int i;
|
|
for (i = 0; tokens[i] != NULL; i++)
|
|
{
|
|
printf("%s\n", tokens[i]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* this will make sure no memory leeks will occurd.
|
|
* runs through all indexes change them to null and then free them.
|
|
* after that it will fraa the array pinter itself.
|
|
* @param tokens - an array to free
|
|
*/
|
|
void FreeTokens(char** tokens)
|
|
{
|
|
int i = 0;
|
|
while(tokens[i] != NULL) // free all the indexes except the last one (NULL)
|
|
{
|
|
tokens[i] = NULL;
|
|
free(tokens[i]);
|
|
i++;
|
|
}
|
|
free(tokens[i]); // free the last index
|
|
tokens = NULL; // free the array
|
|
free(tokens);
|
|
} |