#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
//reading the user input.
char *read_line(){
char *line = NULL;
ssize_t bufsize = 0;
getline(&line, &bufsize, stdin);
return line;
}
//parsing the user input.
char **parse_line(char *line){
int bufsize = 64, position = 0;
char **tokens = malloc(bufsize * sizeof(char*));
char *token;
token = strtok(line, " \t\r\n\a");
while (token != NULL) {
tokens[position] = token;
position++;
if (position >= bufsize) {
bufsize += 64;
tokens = realloc(tokens, bufsize * sizeof(char*));
}
token = strtok(NULL, " \t\r\n\a");
}
tokens[position] = NULL;
return tokens;
}
//executing commands.
int execute_line(char **args){
int status;
pid_t pid;
pid = fork();
if (pid == 0) {
if (execvp(args[0], args) == -1) {
perror("go/sh");
}
exit(EXIT_FAILURE);
} else if (pid < 0) {
perror("go/sh");
} else {
do {
waitpid(pid, &status, WUNTRACED);
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
}
return 1;
}
//This function is responsible for changing the directory.
int cd(char **args){
if (args[1] == NULL) {
fprintf(stderr, "go/sh: expected argument to \"cd\"\n");
} else {
if (chdir(args[1]) != 0) {
perror("go/sh");
}
}
return 1;
}
//This function is responsible for displaying help information.
int help(char **args){
printf("go/sh - Simple UNIX Shell\n\n");
printf("The following are built-in commands supported by go/sh\n");
printf("cd\t\tChange the working directory\n");
printf("help\t\tDisplay this help information\n");
printf("exit\t\tExit go/sh\n");
return 1;
}
//This function is responsible for exiting go/sh.
int go_sh_exit(char **args){
return 0;
}
//This function is responsible for dispatching the commands.
int dispatch_command(char **args){
char *builtin_str[] = {
"cd",
"help",
"exit"
};
int (*builtin_func[]) (char **) = {
&cd,
&help,
&go_sh_exit
};
int i;
if (args[0] == NULL) {
return 1;
}
for (i = 0; i < 3; i++) {
if (strcmp(args[0], builtin_str[i]) == 0) {
return (*builtin_func[i])(args);
}
}
return execute_line(args);
}
//This is the main function of the program.
int main(int argc, char **argv){
char *line;
char **args;
int status;
do {
printf("> ");
line = read_line();
args = parse_line(line);
status = dispatch_command(args);
free(line);
free(args);
} while (status);
return 0;
}