You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.4 KiB
159 lines
3.4 KiB
#include <stdlib.h> |
|
#include <stdio.h> |
|
#include <stdbool.h> |
|
#include <sys/wait.h> |
|
#include <unistd.h> |
|
#include <string.h> |
|
|
|
#include "error.h" |
|
#include "run.h" |
|
|
|
#define INITIAL_LINE_BUFFER 80 |
|
#define INITIAL_WORD_SIZE 80 |
|
#define NUM_BUILTINS 2 |
|
|
|
int readline(FILE* in, char **out) { |
|
int size_of_buffer = INITIAL_LINE_BUFFER; |
|
char *buffer = calloc(size_of_buffer, sizeof(char)); |
|
char character; |
|
int count = 0; |
|
|
|
while (true) { |
|
|
|
character = fgetc(in); |
|
if (character == EOF) { |
|
buffer[count] = '\0'; |
|
*out = buffer; |
|
return EOF; |
|
} |
|
if (character == '\n') { |
|
buffer[count] = '\0'; |
|
*out = buffer; |
|
return ER_SUCCESS; |
|
} else { |
|
if (count == (size_of_buffer - 3)) { |
|
buffer = reallocarray(buffer, (size_of_buffer *= 2), |
|
sizeof(char)); |
|
|
|
if (!buffer) { |
|
return ER_ALLOC; |
|
} |
|
} |
|
|
|
buffer[count] = character; |
|
count++; |
|
} |
|
} |
|
} |
|
|
|
int split_string(char **sep_string[], int *num, char *string, char delim) { |
|
char **word_list = calloc(10, sizeof(char*)); |
|
int word_size; |
|
|
|
char *word = calloc((word_size=INITIAL_WORD_SIZE), sizeof(char)); |
|
int num_words = 0; |
|
int word_length = 0; |
|
|
|
for (int i = 0; true; i++) { |
|
if (string[i] == '\0') { |
|
if (word_length) { |
|
word_list[num_words] = word; |
|
num_words++; |
|
} |
|
|
|
*sep_string = word_list; |
|
*num = num_words; |
|
return ER_SUCCESS; |
|
} |
|
|
|
if (string[i] == delim) { |
|
if (word_length) { |
|
word_list[num_words] = word; |
|
|
|
num_words++; |
|
word_length = 0; |
|
word = calloc((word_size=INITIAL_WORD_SIZE), sizeof(char)); |
|
} |
|
} else { |
|
word[word_length] = string[i]; |
|
word_length++; |
|
|
|
if (word_length == word_size - 2) { |
|
word = reallocarray(word, word_size *= 2, sizeof(char)); |
|
} |
|
} |
|
} |
|
|
|
return ER_FAILURE; |
|
} |
|
|
|
int check_builtins(char *args[]) { |
|
char *builtins[NUM_BUILTINS] = { |
|
"cd", |
|
}; |
|
|
|
if (!strcmp(args[0], "cd")) { |
|
|
|
if (args[1] == 0) { |
|
chdir(getenv("HOME")); |
|
return ER_SUCCESS; |
|
} |
|
|
|
if (args[2] != 0) { |
|
return ER_FAILURE; |
|
} |
|
|
|
chdir(args[1]); |
|
} |
|
|
|
return ER_FAILURE; |
|
} |
|
|
|
int repl(void) { |
|
while (true) { |
|
char *line; |
|
printf("$ "); |
|
if (readline(stdin, &line)) { |
|
return ER_SUCCESS; |
|
} |
|
|
|
char **sep_string; |
|
int num_words; |
|
|
|
split_string(&sep_string, &num_words, line, ' '); |
|
pid_t child; |
|
|
|
if (check_builtins(sep_string)) { |
|
execute(stdin, stdout, sep_string, &child); |
|
} |
|
|
|
waitpid(child, NULL, 0); |
|
|
|
for (int i = 0; i < num_words; i++) { |
|
free(sep_string[i]); |
|
} |
|
free(sep_string); |
|
free(line); |
|
} |
|
} |
|
|
|
int main(int argc, char** argv) { |
|
|
|
char *chicken[] = { |
|
" _\n", |
|
" (o)\n", |
|
" / |\n", |
|
" / |==========\n", |
|
" \\ CHSH /\n", |
|
" \\______/\n", |
|
" |\n", |
|
" _|}\n"}; |
|
|
|
for (int i = 0; i < 8; i ++) { |
|
printf("%s", chicken[i]); |
|
} |
|
|
|
repl(); |
|
|
|
return ER_SUCCESS; |
|
}
|
|
|